Adapter Pattern

Design Patterns | Stefanescu Mihai | 2022-11-25

In acest articol am sa vorbesc despre adapter pattern, un pattern usor de inteles pentru ca sunt sigur ca deja stii ce este un adaptor.

Chiar daca pare usor de explicat cu o poza, definitia este asta:

"Adapter pattern ne permite sa 'traducem' o interfata penutr a putea fi folosita cu alta"

De ajuns cu definitiile, hai sa ne uitam la cod.

Hai sa ne imaginam ca avem o carte pe care o putem deschide si putem intoarce paginile:

class Book {
	public function open()
	{
		echo "Deschid cartea de hartie.";
	}

	public function turnPage()
	{
		echo "Intorc pagina din cartea de hartie.";
	}
}

Pentru a folosi aceasta clasa avem nevoie de o persoana care sa o deschida si sa intoarca paginile:

class Person{
	public function read($book)
	{
		$book->open();
		$book->turnPage();
	}
}

Acum hai sa vedem ce am facut:

(new Person())->read(new Book());
// iar acum o sa vedem pe ecran cele 2 mesaje din clasa Book:
//Deschid cartea de hartie.
//Intorc pagina din cartea de hartie.

Pana acum totul merge perfect, dar oamenii incep sa foloseasca din ce in ce mai mult eReadere si nu clasicele carti de hartie.
Problema este ca un eReader, spre deosebire de o carte nu mai poate fi deschis si intoarsa pagina, ci il pornesc si apas pe un buton ca sa schimb pagina.
Aici apre problema, vreau sa pot folosi atat o carte clasica de hartie cat si un eReader, dar interfetele nu se potrivesc.

Enter Adapater Pattern!

Aici un adapter se potriveste perfect.
Ok, primul lucru pe care ar trebui sa il fac este sa extrag o interfata din clasa Book

interface BookInterface {
	public function open();
	public function turnPage();
}

Acum, in clasa Person pot da ca si type hint interfata BookInterface pentru functia read(), iar clasa Book va implementa aceasta interfata

class Book implements BookInterface {
	public function open()
	{
		echo "Deschid cartea de hartie.";
	}

	public function turnPage()
	{
		echo "Intorc pagina din cartea de hartie.";
	}
}

class Person {
	public function read(BookInterface $book)
	{
		$book->open();
		$book->turnPage();
	}
}

Acum, hai sa facem o clasa noua, Kindle.
Atentie totusi, poate aceasta clasa nu ne apartine sa o modificam dupa bunul plac, poate este dintr-o librarie pe care nu o putem modifica si interfata nu se potriveste.

interface eReaderInterface {
	public function turnOn();
	public function pressNextButton();
}

class Kindle implements eReaderInterface {
	public function turnOn()
	{
		echo "Pornesc kindle-ul.";
	}

	public function pressNextButton()
	{
		echo "Apas butonul pentru a schimba pagina.";
	}
}

Totusi, acum daca incerc sa folosesc aceasta noua clasa nu va functiona pentru ca interfata primita in functia read() nu este interfata de care avem nevoie:

(new Person())->read(new Kindle());

Trebuie sa gasim un mod de a face aceasta noua clasa Kindle sa poata fi folosita cu clasa Person.
Am sa fac o noua clasa numita KindleAdapter in care sa injecta clasa Kindles si care sa implementeze interfata BookInterface:

class KindleAdapter implements BookInterface {

	private $kindle;

	public function __construct(Kindle $kindle)
	{
		$this->kindle = $kindle;
	}

	public function open()
	{
		return $this->kindle->turnOn();
	}

	public function turnPage()
	{
		return $this->kindle->pressNextButton();	
	}
}

Acum avem un adapter care ne ajuta sa folosim aceleasi metode si aceasi interfata atat la o carte de hartie cat si la un eReader.

Acum hai sa dam un click sa vedem daca functioneaza:

(new Person())->read(new KindleAdapter(new Kindle()));
// acum codul functioneaza, iar acestea sunt mesajele care apar pe ecran:
//Pornesc kindle-ul.
//Apas butonul pentru a schimba pagina.

 


Imi place ce faci aici
Daca iti place ce fac aici imi poti cumpara o cafea Buy Me a Coffee at ko-fi.com

Stefanescu Mihai
Programator de ~8 ani, am lucrat la proiecte din mai multe industrstrii, de la eCommerce la telecomunicatii la automatizari. In acest timp am folosi diferite tehnologii, de la PHP, MySQL, PostgreSql, RabbitMq, Redis, Memcached si altele.
       

Get in touch
Pentru nelamuriri, dubii, comentarii si chestii de pe suflet ne putem auzi pe Discord, Reddit sau poti deschide o discutie noua pe forum.

Posteaza un comentariu

Comentarii

Inca nu au fost postate comentarii, fii primul care posteaza un comentariu!

Club-ul este dedicat membrilor si ofera access la mai multe zone ale website-ului.

🗝ïļ Login 🌟 Register

🔖 Bookmarks ⊞
âœĻ Pentru a sustine aceasta comunitate am sa te rog sa te autentifici sau sa te inregistrezi!

🌊ïļ Discord ⊞

Folosim cookie-uri pentru a oferi functionalitatile critice ale aplicatiei Invata-Programare. Folosim cookie-uri si pentru a analiza traficul, pentru care e nevoie de consimtamantul dvs. explicit.

⮆ïļ