modelele de proiectare sunt soluții la nivel de proiectare pentru probleme recurente pe care le întâlnim deseori inginerii de software. Nu este cod – repet, ❌Cod. Este ca o descriere a modului de abordare a acestor probleme și de proiectare a unei soluții. utilizarea acestor modele este considerată o bună practică, deoarece proiectarea soluției este destul de încercată și testată, rezultând o lizibilitate mai mare a codului final., Modelele de Design sunt destul de des create și utilizate de limbile OOP, cum ar fi Java, în care vor fi scrise majoritatea exemplelor de aici încolo.
tipuri de modele de design
există aproximativ 26 de modele descoperite în prezent(cu greu cred că le voi face pe toate…).aceste 26 pot fi clasificate în 3 tipuri:
1. Creațional: aceste modele sunt concepute pentru instanțierea clasei. Ele pot fi fie modele de creație de clasă, fie modele de creație obiect.
2. Structurale: aceste modele sunt concepute în ceea ce privește structura și compoziția unei clase., Scopul principal al majorității acestor modele este de a crește funcționalitatea clasei(claselor) implicate, fără a schimba o mare parte din compoziția sa.
3. Comportamental: aceste modele sunt concepute în funcție de modul în care o clasă comunică cu ceilalți.
în acest post, vom trece printr-un model de design de bază pentru fiecare tip clasificat.
de Tip 1: Creatie – De Singleton Model de Design
Singleton Model de Design este o Creatie model, al cărui obiectiv este de a crea o singură instanță a unei clase și să ofere doar una globală punct de acces la acel obiect., Un exemplu frecvent utilizat de o astfel de clasă în Java este Calendar, În cazul în care nu se poate face o instanță de acea clasă. De asemenea, utilizează propria metodă getInstance()
pentru a obține obiectul care urmează să fie utilizat.
O clasă folosind singleton model de design va include,
- Un privat variabilă statică, care deține singura instanta a clasei.
- un constructor privat, deci nu poate fi instanțiat în altă parte.
- o metodă statică publică, pentru a returna singura instanță a clasei.,
există multe implementări diferite ale designului singleton. Astăzi, voi trece prin implementările;
1. Instanțiere dornică
2. Instanțierea leneșă
3. Thread-safe Instanțierea
Eager Beaver
public class EagerSingleton {// create an instance of the class.private static EagerSingleton instance = new EagerSingleton();// private constructor, so it cannot be instantiated outside this class.private EagerSingleton() { }// get the only instance of the object created.public static EagerSingleton getInstance() {return instance;}}
Acest tip de instanțiere se întâmplă în clasa de încărcare, după instanțierea variabilei exemplu se întâmplă dincolo de orice metoda. Acest lucru reprezintă un dezavantaj grav dacă această clasă nu este utilizată deloc de aplicația client. Planul de urgență, dacă această clasă nu este utilizată, este instanțierea leneșă.,
zile leneșe
nu există o mare diferență față de implementarea de mai sus. Principalele diferențe sunt că variabila statică este inițial declarată nulă și este instanțiată doar în metodagetInstance()
dacă – și numai dacă – variabila de instanță rămâne nulă la momentul verificării.
aceasta rezolvă o problemă, dar încă mai există o altă problemă. Ce se întâmplă dacă doi clienți diferiți accesează clasa Singleton în același timp, chiar la milisecundă?, Ei bine, ei vor verifica dacă instanța este nulă în același timp și o vor găsi adevărată și astfel vor crea două instanțe ale clasei pentru fiecare solicitare de către cei doi clienți. Pentru a remedia acest lucru, va fi implementată instanțierea sigură a firului.
(Thread) siguranța este cheia
în Java, cuvântul cheie sincronizat este utilizat pe metode sau obiecte pentru a implementa siguranța firului, astfel încât un singur fir va accesa o anumită resursă la un moment dat. Instanțierea clasei este pusă într-un bloc sincronizat, astfel încât metoda să poată fi accesată doar de un client la un moment dat.,
deasupra capului pentru metoda sincronizată este mare, și reduce performanța întregii operațiuni.
De exemplu, dacă o variabilă instanță a fost deja creata, apoi de fiecare dată orice client accesează getInstance()
metodă, synchronized
metodă este de a rula și performanța scade. Acest lucru se întâmplă doar pentru a verifica dacă valoarea variabilelor instance
este nulă. Dacă constată că este, părăsește metoda. pentru a reduce această suprapunere, se utilizează o blocare dublă., Verificarea este utilizată înainte de metoda synchronized
și dacă valoarea este nulă singură, metoda synchronized
rulează.
acum pe următoarea clasificare.
tip 2: Structural-modelul de design Decorator
am să vă dau un scenariu mic pentru a da un context mai bun de ce și în cazul în care ar trebui să utilizați modelul Decorator.
Să presupunem că dețineți o cafenea și, ca orice începător, începeți cu doar două tipuri de cafea simplă, amestecul de casă și friptura întunecată., În sistemul dvs. de facturare, a existat o clasă pentru diferitele amestecuri de cafea, care moștenește clasa abstractă a băuturilor. Oamenii încep de fapt să vină și să aibă minunatul tău (deși amar?) cafea. Apoi, există newbs de cafea care, Doamne ferește, Doresc zahăr sau lapte. O astfel de parodie pentru cafea!! ??acum trebuie să aveți și cele două suplimente, atât în meniu, cât și în sistemul de facturare. Inițial, persoana IT va face o subclasă pentru ambele cafele, una inclusiv zahăr, celălalt lapte., Apoi, din moment ce clienții au întotdeauna dreptate, se spune aceste cuvinte temute:
„pot obține o cafea cu lapte, cu zahăr, vă rog?”
???
nu merge sistemul de facturare râs în fața ta din nou. Ei bine, înapoi la planșa de desen….persoana IT Adaugă apoi cafea cu lapte cu zahăr ca o altă subclasă la fiecare clasă de cafea părinte. Restul lunii este navigatie buna, oameni garnitură de până pentru a avea cafea, de fapt, a face bani. ??
dar așteptați, există mai mult!
lumea este din nou împotriva ta., Un concurent se deschide peste drum, cu nu doar 4 tipuri de cafea, dar mai mult de 10 suplimente, de asemenea! ?cumpărați toate acestea și multe altele, pentru a vinde singuri o cafea mai bună și amintiți-vă că ați uitat să actualizați sistemul de facturare dratted. Este posibil să nu puteți face numărul infinit de subclase pentru toate combinațiile tuturor suplimentelor, cu noile amestecuri de cafea. Să nu mai vorbim de dimensiunea sistemului final.??
timp pentru a investi efectiv într-un sistem de facturare adecvat., Veți găsi personal IT nou, care știe de fapt ce fac și spun ei;
„De ce, acest lucru va fi mult mai ușor și mai mic dacă ar folosi modelul decorator.”
ce naiba e asta?
modelul de design al decoratorului se încadrează în categoria structurală, care se ocupă de structura reală a unei clase, fie prin moștenire, compoziție sau ambele. Scopul acestui design este de a modifica funcționalitatea unui obiect în timpul rulării. Acesta este unul dintre multe alte modele de design care utilizează clase abstracte și interfețe cu compoziția pentru a obține rezultatul dorit.,
să dea matematica o șansă (fior?) pentru a aduce toate acestea în perspectivă;
luați 4 amestecuri de cafea și 10 suplimente. Dacă am rămas la generarea de subclase pentru fiecare combinație diferită a tuturor suplimentelor pentru un singur tip de cafea. Asta e;
(10-1) 2 = 92 = 81 subclase
scădem 1 din 10, deoarece nu puteți combina un add-on cu altul de același tip, zahărul cu zahărul sună prost. Și asta e doar pentru un amestec de cafea. Înmulțiți că 81 de 4 și veți obține un enorm 324 subclase diferite!, Dar cu modelul decorator va necesita doar 16 clase în acest scenariu. Punem pariu?
Daca avem harta noastră scenariu în conformitate cu diagrama de clase de mai sus, avem 4 clase pentru 4 amestecuri de cafea, 10 pentru fiecare add-on și 1 pentru abstracte component si 1 mai mult pentru rezumat decorator. Vezi! 16!, Acum dă-mi cei 100$.?? (jk, dar nu va fi refuzat dacă este dat… doar spunând)
după cum puteți vedea de sus, la fel cum amestecurile de cafea din beton sunt subclase ale clasei abstracte de băuturi, clasa abstractă AddOn moștenește și metodele sale. Suplimentele, care sunt subclasele sale, moștenesc la rândul lor orice metode noi pentru a adăuga funcționalitate obiectului de bază atunci când este necesar.
să trecem la codificare, pentru a vedea acest model în uz.,mai întâi pentru a face clasa abstractă a băuturilor, pe care toate amestecurile de cafea diferite le vor moșteni de la:
apoi pentru a adăuga ambele clase de amestec de cafea din beton.
clasa AddOn abstract moștenește, de asemenea, din clasa Beverage abstract (mai multe despre aceasta mai jos).și acum implementările concrete ale acestei clase abstracte:
după cum puteți vedea mai sus, putem trece orice subclasă de băuturi la orice subclasă de AddOn și obținem costul adăugat, precum și descrierea actualizată. Și, din moment ce clasa AddOn este în esență de tip băutură, putem trece un AddOn într-un alt AddOn., În acest fel, putem adăuga orice număr de suplimente la un amestec specific de cafea.
acum pentru a scrie un cod pentru a testa acest lucru.
rezultatul final este:
functioneaza! Am reușit să adăugăm mai multe suplimente la un amestec de cafea și să actualizăm cu succes costul final și descrierea acestuia, fără a fi nevoie să creăm subclase infinite pentru fiecare combinație de suplimente pentru toate amestecurile de cafea.în cele din urmă, la ultima categorie.,
tip 3: comportamental-modelul de proiectare a Comenzii
un model de design comportamental se concentrează asupra modului în care clasele și obiectele comunică între ele. Obiectivul principal al modelului de comandă este de a încuraja un grad mai mare de cuplare liberă între părțile implicate (citiți: clase).
Uhhhh … ce – i asta?
cuplarea este modul în care două (sau mai multe) clase care interacționează între ele, bine, interacționează. Scenariul ideal atunci când aceste clase interacționează este că nu depind foarte mult unul de celălalt. Asta e cuplaj liber., Deci, o definiție mai bună pentru cuplare în vrac ar fi, clase care sunt interconectate, ceea ce face cel mai puțin utilizarea reciproc.necesitatea acestui model a apărut atunci când cererile trebuiau trimise fără a ști în mod conștient ce cereți sau cine este destinatarul.
în acest model, clasa de invocare este decuplată de clasa care efectuează efectiv o acțiune. Clasa invoker are doar metoda callable execute, care execută comanda necesară, atunci când clientul o solicită.să luăm un exemplu de bază din lumea reală, comandând o masă la un restaurant de lux., Pe măsură ce fluxul merge, dați comanda (comanda) chelnerului (invoker), care apoi o înmânează bucătarului(receptorului), astfel încât să puteți obține mâncare. S-ar putea suna simplu… dar un pic meh la cod.
ideea este destul de simplă, dar codarea merge în jurul nasului.,
fluxul de funcționare pe partea tehnică este, face un beton de comandă, care implementează interfața de Comandă, cere receptorului pentru a finaliza o acțiune, și trimite comanda la invoker. Invokerul este persoana care știe când să dea această comandă. Bucătarul este singurul care știe ce să facă atunci când i se dă comanda/comanda specifică., Deci, atunci când metoda de executare a invokerului este rulată, aceasta, la rândul său, face ca metoda de executare a obiectelor de comandă să ruleze pe receptor, completând astfel acțiunile necesare.,
de Ce avem nevoie pentru a pune în aplicare;
- O interfață de Comandă
- O clasa Pentru care implementează interfața de Comandă
- Un curs Ospătar (invoker)
- Un Bucătar de clasă (receptor)
Deci, de codificare merge ca aceasta:
Bucătar, receptorul
de Comandă, interfața
public interface Command {public abstract void execute();}
Comanda, beton comanda
Chelnerul, invoker
public class Waiter {private Order order;public Waiter(Order ord) {this.order = ord;}public void execute() {this.order.execute();}}
, clientul
după Cum puteți vedea mai sus, Clientul face o Comanda si seturi de Receptor ca Bucătar., Comanda este trimisă chelnerului, care va ști când să execute comanda (adică când să dea bucătarului comanda de gătit). Când invoker este executat, metoda de executare a ordinelor este rulată pe receptor (adică bucătarului i se dă comanda să gătească paste ? sau coace tort?).,
recapitulare Rapidă
În acest post am mers prin:
- Ce este un model de design este într-adevăr,
- diferite tipuri de modele de design și de ce sunt diferite
- O bază sau comun model de design pentru fiecare tip
sper că acest lucru a fost de ajutor.
găsiți codul repo pentru post, aici.