Acasă - Siguranţă
Model de design adaptor. Model de design adaptor în PHP

Ultima actualizare: 31.10.2015

Modelul Adaptor este conceput pentru a converti interfața unei clase în interfața alteia. Datorită implementării acestui model, putem folosi împreună clase cu interfețe incompatibile.

Când ar trebui să folosesc adaptorul?

    Când trebuie să utilizați o clasă existentă, dar interfața acesteia nu corespunde nevoilor dvs

    Când trebuie să utilizați o clasă existentă împreună cu alte clase ale căror interfețe nu sunt compatibile

Definiția formală a unui model în UML este următoarea:

Descrierea formală a unui adaptor de obiecte în C# arată astfel:

Client de clasă ( public void Request(Target target) ( target.Request(); ) ) // clasă la care o altă clasă trebuie adaptată clasă Target ( public virtual void Request() () ) // Clasa adaptor Adaptor: Target ( private Adaptee adaptee = new Adaptee(); public override void Request() ( adaptee.SpecificRequest(); ) ) // Clasa adaptabilă Adaptee ( public void SpecificRequest() () )

Participanții

    Țintă: reprezintă obiectele care sunt utilizate de client

    Client: folosește obiectele țintă pentru a-și implementa sarcinile

    Adaptee: Reprezintă clasa adaptabilă pe care am dori să o folosească clientul în locul obiectelor țintă

    Adaptor: adaptorul în sine, care vă permite să lucrați cu obiecte Adaptee ca și cu obiectele țintă.

Adică clientul nu știe nimic despre Adaptee, știe și folosește doar obiecte Target. Și datorită adaptorului, putem folosi obiecte Adaptee pe client ca țintă

Acum să ne uităm la un exemplu real. Să presupunem că avem un călător care călătorește cu mașina. Dar la un moment dat trebuie să se deplaseze prin nisipurile deșertului, unde nu poate conduce o mașină. Dar poate folosi o cămilă pentru a se mișca. Cu toate acestea, clasa de călători nu permite clasa de cămilă, așa că trebuie să folosim un adaptor:

Programul de clasă ( static void Main(string args) ( // călător Driver driver = new Driver(); // mașină Auto auto = new Auto(); // să mergem într-o călătorie șofer.Travel(auto); // nisipuri întâlnim, trebuie să folosim un camel camel = new Camel( // folosiți adaptorul ITransport camelTransport = new CamelToTransportAdapter(camel) // continuați drumul prin driverul nisipurilor deșertului.Travel(camelTransport()); void Drive(); // clasă mașină Auto: ITransport ( public void Drive() ( Console.WriteLine("Mașina conduce pe drum"); ) ) class Driver ( public void Travel(ITransport transport) ( transport .Drive() ;) ) // interfață interfață animală IAnimal ( void Move(); ) // clasă camel Camel: IAnimal ( public void Move() ( Console.WriteLine("Camila se plimbă de-a lungul nisipurilor deșertului"); ) ) // Adaptor de la Camel la ITransport clasa CamelToTransportAdapter: ITransport ( Camel camel; public CamelToTransportAdapter(Camel c) ( camel = c;

) public void Drive() ( camel.Move(); ) )

Și consola va scoate:

O mașină merge de-a lungul drumului O cămilă se plimbă pe nisipurile deșertului.

Unii ar putea considera că problema utilizării adaptoarelor este exagerată, mai ales în acest caz, deoarece am putea aplica interfața ITransport la clasa Camel și am putea implementa metoda Drive() a acesteia. Cu toate acestea, în acest caz, poate exista o dublare a funcționalității: interfața IAnimal are o metodă Move(), a cărei implementare în clasa camel ar putea fi similară cu implementarea metodei Drive() din interfața ITransport. În plus, se întâmplă adesea ca cursurile să fie concepute de altcineva, iar noi nu avem nicio influență asupra lor. Le folosim doar. Ca rezultat, adaptoarele sunt destul de comune în .NET. În special, numeroase clase încorporate care sunt utilizate pentru a se conecta la diferite sisteme de baze de date implementează modelul adaptor (de exemplu, clasa System.Data.SqlClient.SqlDataAdapter).

Înainte de a citi, vă rugăm să revizuiți următoarele convenții și concepte. Acest articol este actualizat cu o oarecare frecvență, așa că dacă l-ați citit înainte, nu este un fapt că datele nu s-au schimbat.

Adaptor aparțin clasei structural modele. Este folosit pentru a converti o interfață la alta cerută de client. Adaptorul asigură compatibilitatea interfețelor incompatibile prin implementarea unui strat.

Principiul de funcționare

Adaptorul moștenește interfața țintă într-un mod deschis (să o numim Ţintă), și o interfață adaptabilă în mod închis ( Adaptat). În implementarea metodelor de interfață țintă, cererile sunt redirecționate (delegate) către o clasă cu o interfață adaptabilă

Exemplu

// Interfață țintă, clientul poate lucra numai cu ea interfață iTarget ( interogare public function(); ) // Interfață adaptabilă. Clientul nu știe cum să lucreze cu el, dar dorește cu adevărat interfața iAdaptee ( public function request(); ) // O clasă care implementează o clasă de interfață adaptabilă Adaptee implementează iAdaptee ( public function request() ( return __CLASS__ . ":: " . __METHOD__; ) ) clasă Adaptor implementează iTarget ( protected $adaptee = null; public function __construct() ( $this -> adaptee = new Adaptee(); ) public function query() ( return $this -> adaptee -> request (); ) ) $ Target = nou Adaptor(); print $Target -> interogare(); // „Adaptat::request”

Concluzie

Un adaptor poate adapta mai multe interfețe într-o singură interfață deodată adaptor obiect Utilizarea acestui model este justificată în mai multe cazuri. Dacă doriți să utilizați o clasă existentă cu o interfață diferită. Dacă intenționați să utilizați interfața adaptabilă în mai multe locuri și nu aveți ocazia să o faceți să arate la fel peste tot, atunci folosirea adaptoarelor înlocuibile poate fi o idee bună.

În ultima lecție, am analizat posibilitatea modelului de design Fațade, cu ajutorul căruia puteți reconstrui codul unui proiect mare.

În acest articol, ne concentrăm pe un model de design numit Adaptor. Utilizarea acestuia este recomandabilă dacă proiectul dumneavoastră interacționează cu API-uri terțe sau cu o altă clasă care este supusă modificărilor frecvente. Acest șablon aparține tipului „structural” deoarece cu ajutorul lui putem putem organiza structura clasei după un anumit tipar.

Încă o dată aș dori să vă reamintesc că modelele de design nu sunt diferite de clasele obișnuite. Cu ajutorul lor, ne putem structura clasele într-un mod mai bun și le putem controla comportamentul.

Sarcină

În exemplul de mai sus, folosim clasa Twitter pentru a simplifica procedura de publicare a unui mesaj. Apoi, creăm un obiect pentru a apela API-ul Twitter și publicăm un mesaj. Imaginați-vă că acest cod este folosit în mai multe locuri. Vă rugăm să rețineți că pentru a publica un mesaj folosim metoda $twitter->send(„Postare pe Twitter”);

Cu ceva timp în urmă, Twitter a schimbat numele metodei API pentru publicarea unui mesaj. Cei care au folosit versiunea anterioară vor vedea clar problema. Trebuie să schimbăm toate denumirile metodelor de trimitere a unui tweet. Imaginează-ți cât de mult cod trebuie să schimbăm și cât timp va dura. Ce se întâmplă dacă schimbarea numelui se întâmplă din nou?

Soluţie

Ca soluție, putem folosi modelul de design al adaptorului.

Un adaptor este un model de design structural conceput pentru a organiza utilizarea funcțiilor unui obiect care nu este disponibil pentru modificare printr-o interfață special creată.

Deci, în primul rând, trebuie să creăm o interfață. Schimbarea codului unei biblioteci terță parte nu are niciun sens, deoarece... conținutul acestuia se poate modifica în orice moment.

Să ne uităm la un cod scris folosind modelul de proiectare al adaptorului:

// Implementarea clasei Twitter Twitter ( public function __construct() ( // Your Code here // ) public function send($msg) ( // Postare pe Twitter // echo $msg; ) ) // Interfata simpla pentru fiecare adaptor, care va fi creat interfața socialAdapter ( public function send($msg); ) clasa twitterAdapter implementează socialAdapter ( private $twitter; public function __construct(Twitter $twitter) ( $this->twitter = $twitter; ) public function send ($msg ) ( $this->twitter->send($msg); ) )

După ce ați examinat codul, vă veți da seama că nu am atins clasa inițială Twitter. În schimb, am creat interfața adaptorului nostru social pentru clasa Twitter.

Apoi, în loc să creăm un obiect de tip Twitter, am creat un obiect al adaptorului său. Trecem un obiect din clasa principală Twitter ca parametru, astfel încât adaptorul nostru să aibă acces la obiectul clasei principale.

Acum să definim cum să folosim metodele clasei originale:

// cod client $twitter = new twitterAdapter(new Twitter()); $twitter->send(„Postare pe Twitter”);

Acum imaginați-vă că Twitter a schimbat numele metodei din send în sendTweet. În acest caz, trebuie doar să schimbăm twitterAdapter. Aruncă o privire la codul adaptorului modificat.

Clasa twitterAdapter implementează socialAdapter ( private $twitter; public function __construct(Twitter $twitter) ( $this->twitter = $twitter; ) public function send($msg) ( $this->twitter->sendTweet($msg); ) )

O singură schimbare și ne întoarcem pe drumul cel bun.

Adăugarea unui nou adaptor

Să ne uităm la modul în care modelul de design al adaptorului poate fi utilizat în alte cazuri. Acum este foarte ușor să adăugați o nouă clasă bazată pe un adaptor existent. Să presupunem că API-ul Facebook vă permite să vă actualizați starea.

În loc să folosim direct clasa Facebook, să creăm un nou adaptor.

Clasa Facebook ( public function __construct() ( // Codul dvs. // ) public function updateStatus($msg) ( // Postare pe Facebook // echo $msg; ) ) // Facebook Adapter clasa facebookAdapter implementeaza socialAdapter ( private $facebook; public function __construct(Facebook $facebook) ( $this->facebook = $facebook; ) public function send($msg) ( $this->facebook->updateStatus($msg); ) ) // cod client $facebook = new facebookAdapter(nou Facebook()); $facebook->send(„Postare pe Facebook”);

După cum puteți vedea, principiul este același. Definiți o clasă wrapper căreia îi treceți obiectul clasa originală. Când schimbați API-ul, trebuie doar să schimbați codul într-un singur loc.

Concluzie

Aplicațiile mari vor implica, fără îndoială, lucrul cu API-uri terțe, așa că folosirea modelului de design Adaptor are sens dacă doriți să evitați problema pe care am discutat-o.

Am făcut tot posibilul pentru a demonstra un exemplu de bază, dar util, de utilizare a modelului de design Adaptor.

    Adaptor (model de proiectare)/Exemple de cod- Articolul principal: Adaptor (model de proiectare) Un exemplu de implementare a unui model în C# folosind System; Adaptor pentru spațiu de nume ( clasa MainApp ( static void Main() ( ... Wikipedia

    Model proxy (model de design)

    Model de design- Acest termen are alte semnificații, vezi Model. În dezvoltarea de software, un model de design sau un model de design este un design arhitectural repetabil care reprezintă o soluție la o problemă... ... Wikipedia

    Interfață (model de design)- Modelul de proiectare a interfeței descris în modelele de proiectare Nu În informatică, modelul de interfață nu este un model special printre modelele de design. Este o metodă generală de structurare a programelor de calculator pentru a... Wikipedia

    Adjunct (model de proiectare)- Proxy Pattern (Deputat) Model de design. Oferă un obiect de control al accesului, interceptând toate apelurile către acesta. Cuprins 1 Scop 1.1 Problemă 1.2 Soluție 2 Pro 3 ... Wikipedia

    Guardian (model de design)- Design Pattern Guardian Memento Tip: Comportamental Descris în Design Patterns Da Guardian (cunoscut și sub numele de Memento, Token, Token) este un model de design comportamental. Vă permite să reparați fără a întrerupe încapsularea... Wikipedia

    Iterator (model de proiectare)- Design Pattern Iterator Iterator Tip: comportamental Descris în Design Patterns Da Iterator Pattern (cunoscut și ca Cursor) Un model de design care se referă la modele comportamentale. Este un obiect care vă permite să obțineți... Wikipedia

    Interpret (model de proiectare)- Model de proiectare Tip de interpret: comportamental Scop: rezolvă o problemă care apare frecvent, predispusă la schimbare Descris în Modele de proiectare Da Model de interpret (în engleză ... Wikipedia

    Linker (model de design)- Model de design Tip compozit: structural Descris în Modele de proiectare Da Modelul compozit este un model de design, se referă la modele structurale, combină un obiect... Wikipedia

    Stare (model de proiectare)- Model de design de stat Tip: comportamental Descris în modele de proiectare Da State este un model de design. Este folosit în cazurile în care, în timpul execuției programului, un obiect... Wikipedia

Să revenim la luarea în considerare a modelelor de proiectare structurală. De data aceasta ne vom uita la un model de design numit Adaptor(se mai numește și Wrapper împreună cu modelul Fațade).

În acest articol vom vorbi despre următoarele:

Deci, modelul Adaptor este folosit astfel încât obiectele cu o singură interfață (contract) să poată funcționa acolo unde este nevoie de un obiect cu o interfață complet diferită. Există două tipuri de adaptoare - adaptor de clasă și adaptor de obiect.

În primul rând, ne vom uita la fiecare dintre aceste tipuri, apoi voi explica diferența dintre cele două ambalaje - adaptor și fațadă.

Adaptor de obiecte

Object Adapter își atinge scopul prin compoziție. În diagrama de mai jos, clientului i se cere să utilizeze interfața TargetInterface. Pentru a face acest lucru, este creată o clasă ObjectAdapter care implementează interfața TargetInterface și stochează, de asemenea, un obiect de clasă Adaptee. Când se apelează metoda targetMethod de pe adaptor, este apelată metoda corespunzătoare de pe interfața care se adaptează.

În cel mai simplu caz, implementarea ObjectAdapter ar fi astfel:

Clasa publică ObjectAdapter implementează TargetInterface (adaptat privat Adaptee; public void targetMethod() ( adaptee.method() ) )

Avantajul acestei abordări este că separăm complet interfața client de interfața adaptabilă.

Adaptor de clasă

În cazul Class Adapter, moștenirea multiplă este utilizată pentru a ne atinge scopul nostru ClassAdapter moștenește din interfața client și din interfața Adaptable Deoarece nu există o moștenire multiplă în Java, doar unul dintre strămoși poate fi o clasă abstractă/concretă Al doilea strămoș va fi interfața, ceea ce nu este întotdeauna convenabil.

Diagrama de clasa:

Și iată o implementare trivială a clasei ClassAdapter:

Clasa publică ClassAdapter extinde Adaptee implementează TargetInterface ( public void targetMethod() ( method(); ) )

Aș dori să vă atrag atenția asupra faptului că, cu o astfel de implementare a adaptorului, poate apărea un conflict în semnăturile metodei. Object Adapter nu are această problemă.

Class Adapter este considerat o soluție mai simplă atunci când nu este necesară separarea strictă a interfețelor client și adaptabile.

Diferența dintre adaptor și fațadă

Acum vreau să spun câteva cuvinte despre modelul Facade, care, la fel ca adaptorul, este un Wrapper definit nou interfață în timp ce adaptorul este utilizat existent interfețe.

Nu ar trebui să comparați Facade și Adapter astfel: se spune că Facade poate îngloba mai multe clase, dar Adapter adaptează doar una. Se poate foarte bine ca adaptorul să fie necesar pentru a adapta mai multe clase și invers, Fațada va trebui folosită pentru a simplifica doar o clasă complexă. Deci diferența dintre aceste două modele nu este în numărul de entități care sunt înfășurate, ci în motivul pentru care o fac.

Exemplu de utilizare a adaptorului în JDK

De asemenea, puteți găsi exemple de utilizare a adaptorului în biblioteca standard. Probabil cel mai popular caz de utilizare este java.io.InputStreamReader și OutputStreamWriter.

Constructorul InputStreamReader ia un InputStream ca intrare și ca rezultat adaptează fluxul în Reader.

Mai târziu voi posta codul pentru utilizarea adaptoarelor din proiecte reale la care am participat, dar deocamdată aștept întrebările și comentariile voastre. Noroc.



 


Citire:



Care unități flash USB sunt cele mai fiabile și mai rapide?

Care unități flash USB sunt cele mai fiabile și mai rapide?

Foarte des pe forumuri, mulți oameni întreabă despre cum să alegeți o unitate flash și la ce parametri ar trebui să acordați atenție pentru ca...

Conectarea unui laptop la un televizor prin cablu USB pentru conectarea unui laptop la un televizor VGA

Conectarea unui laptop la un televizor prin cablu USB pentru conectarea unui laptop la un televizor VGA

Salutare tuturor! Am împrumutat o vreme netbook-ul Acer Aspire ONE D270 și am decis să-l testez împreună cu un televizor. În imensitatea...

Schimbarea interfeței Steam - de la imagini simple la întreaga prezentare pe ecran Design nou steam

Schimbarea interfeței Steam - de la imagini simple la întreaga prezentare pe ecran Design nou steam

Cred că nu este un secret că utilizatorii Steam au posibilitatea de a schimba tema clientului lor și, de obicei, descarcăm teme gata făcute și...

Cum să anulați un abonament Megogo la televizor: instrucțiuni detaliate Cum să vă dezabonați de la abonamentele Megogo

Cum să anulați un abonament Megogo la televizor: instrucțiuni detaliate Cum să vă dezabonați de la abonamentele Megogo

Caracteristicile și avantajele serviciului Megogo Unul dintre cele mai mari servicii video din Europa de Est și CSI este Megogo. Catalogul conține peste 80 de mii...

imagine-alimentare RSS