Home >Backend Development >PHP Tutorial >About PHP design pattern-detailed explanation of adapter method
Convert the interface of a class into another interface that the customer wants. The Adapter mode allows classes that cannot work together because of incompatible interfaces to work together. This article mainly shares with you the detailed explanation of the adapter, hoping to help you.
Target role: Define the domain-specific interface used by the client, this is what we are looking for
Source role: The interface that needs to be adapted
Adapter role: Adapt the Adaptee interface and the target interface; the adapter is the core of this model, the adapter converts the source interface into the target interface, this role is specific Class
1. You want to use an existing class, but its interface does not meet your needs
2. You want to create a class that can be copied Use a class that can work with other unrelated or unforeseen classes
3. You want to subclass an existing class, but it is impossible to subclass each one. Match their interfaces. The object adapter can adapt to its parent class interface (only for object adapters)
//目标角色 interface Target { public function simpleMethod1(); public function simpleMethod2(); } //源角色 class Adaptee { public function simpleMethod1(){ echo 'Adapter simpleMethod1'."<br>"; } } //类适配器角色 class Adapter implements Target { private $adaptee; function __construct(Adaptee $adaptee) { $this->adaptee = $adaptee; } //委派调用Adaptee的sampleMethod1方法 public function simpleMethod1(){ echo $this->adaptee->simpleMethod1(); } public function simpleMethod2(){ echo 'Adapter simpleMethod2'."<br>"; } } //客户端 class Client { public static function main() { $adaptee = new Adaptee(); $adapter = new Adapter($adaptee); $adapter->simpleMethod1(); $adapter->simpleMethod2(); } } Client::main();
Maybe you don’t know what an adapter is because of the above. So next, let me explain in detail
In fact, the simplest example is to use a third-party class library. These class libraries will be upgraded as the version is upgraded, and the corresponding APIs will also change. When the interface changes, the adapter comes in handy
Let me give you a practical example
Specially produced by Heizao Toy Company Toys, the toys produced are not limited to dogs, cats, lions, fish and other animals. Each toy can perform "open mouth" and "close mouth" operations, and the openMouth and closeMouth methods are called respectively. At this time, it is easy for us to think that we can first define an abstract class Toy, or even an interface Toy. These problems are not big, and other classes can inherit the parent class and implement the methods of the parent class. There is harmony and confidence.
Smooth Destruction
In order to expand the business, now Black Date Toy Company cooperates with Red Date Remote Control Company, which can use remote control devices to control the mouth of animals. However, the remote control device of Hongzao Remote Control Company calls the doMouthOpen and doMouthClose methods of animals. What the programmers of Heizao Toy Company must do now is to upgrade the Toy series classes so that Toy can call the doMouthOpen and doMouthClose methods.
When considering the implementation method, we directly thought that if you need it, I will just add these two methods to my parent class and subclass for you. When you repeatedly add these two methods in the parent class and subclass again and again, you will always think about such repetitive work. Can't it be solved? Programmers will go crazy when there are hundreds of subclasses. Programmers often compete to see who is more "lazy" when it does not affect efficiency. Programmers will feel stupid if they continue to do this. (Actually, I often act like this fool)
abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); //为红枣遥控公司控制接口增加doMouthOpen方法 public abstract function doMouthOpen(); //为红枣遥控公司控制接口增加doMouthClose方法 public abstract function doMouthClose(); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n"; } public function closeMouth() { echo "Dog open Mouth\n"; } //增加的方法 public function doMouthOpen() { $this->doMouthOpen(); } //增加的方法 public function doMouthClose() { $this->closeMouth(); } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n"; } public function closeMouth() { echo "Cat open Mouth\n"; } //增加的方法 public function doMouthOpen() { $this->doMouthOpen(); } //增加的方法 public function doMouthClose() { $this->closeMouth(); } }
The programmer had just finished coding and took a drink of water, when suddenly another news came. Heizao Toy Company also wants to cooperate with Luzao Remote Control Company, because the remote control equipment of Luzao Remote Control Company is cheaper and more stable. However, the remote control device of Green Date Remote Control Company calls the operMouth(type) method of the animal to achieve mouth control. If type is 0, "shut up", otherwise open your mouth. Now, the programmer has to upgrade Toy and its subclasses so that Toy can call the operMouth() method. No one is calm anymore.
abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); public abstract function doMouthOpen(); public abstract function doMouthClose(); //为绿枣遥控公司控制接口增加doMouthClose方法 public abstract function operateMouth($type = 0); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n"; } public function closeMouth() { echo "Dog open Mouth\n"; } public function doMouthOpen() { $this->doMouthOpen(); } public function doMouthClose() { $this->closeMouth(); } public function operateMouth($type = 0) { if ($type == 0) { $this->closeMouth(); } else { $this->operateMouth(); } } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n"; } public function closeMouth() { echo "Cat open Mouth\n"; } public function doMouthOpen() { $this->doMouthOpen(); } public function doMouthClose() { $this->closeMouth(); } public function operateMouth($type = 0) { if ($type == 0) { $this->closeMouth(); } else { $this->operateMouth(); } } }
At this time, programmers must use their brains to find a way. Even if they are diligent, if one day all the remote control companies such as purple dates, green dates, yellow dates, and mountain dates come, they will ignore their increasing number. Not to mention the workload, this Toy class is getting bigger and bigger. One day, if the programmer doesn't crash, the system will crash too.
Where is the problem
Writing code as above, the code implementation violates the "open-closed" principle, a software entity should Open for extension, closed for modification. That is, when designing a module, the module should be extended without being modified. In other words, every corpse is a small kingdom. You can let me participate in your affairs, but you cannot modify my internal code unless my internal code can really be optimized.
With this idea, we understand how to use inheritance, how to utilize polymorphism, and even how to achieve "high cohesion and low coupling".
回到这个问题,我们现在面临这么一个问题,新的接口方法我要实现,旧的接口(Toy抽象类)也不能动,那么总得有个解决方法吧。那就是引入一个新的类--我们本文的主角--适配器。 适配器要完成的功能很明确,引用现有接口的方法实现新的接口的方法。更像它名字描述的那样,你的接口不改的话,我就利用现有接口和你对接一下吧。
到此,解决方法已经呼之欲出了,下面贴上代码。
<?php abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n"; } public function closeMouth() { echo "Dog close Mouth\n"; } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n"; } public function closeMouth() { echo "Cat close Mouth\n"; } } //目标角色:红枣遥控公司 interface RedTarget { public function doMouthOpen(); public function doMouthClose(); } //目标角色:绿枣遥控公司及 interface GreenTarget { public function operateMouth($type = 0); } //类适配器角色:红枣遥控公司 class RedAdapter implements RedTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } //委派调用Adaptee的sampleMethod1方法 public function doMouthOpen() { $this->adaptee->openMouth(); } public function doMouthClose() { $this->adaptee->closeMouth(); } } //类适配器角色:绿枣遥控公司 class GreenAdapter implements GreenTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } //委派调用Adaptee:GreenTarget的operateMouth方法 public function operateMouth($type = 0) { if ($type) { $this->adaptee->openMouth(); } else { $this->adaptee->closeMouth(); } } } class testDriver { public function run() { //实例化一只狗玩具 $adaptee_dog = new Dog(); echo "给狗套上红枣适配器\n"; $adapter_red = new RedAdapter($adaptee_dog); //张嘴 $adapter_red->doMouthOpen(); //闭嘴 $adapter_red->doMouthClose(); echo "给狗套上绿枣适配器\n"; $adapter_green = new GreenAdapter($adaptee_dog); //张嘴 $adapter_green->operateMouth(1); //闭嘴 $adapter_green->operateMouth(0); } } $test = new testDriver(); $test->run();
更加烦躁
最后的结果就是,Toy类及其子类在不改变自身的情况下,通过适配器实现了不同的接口。
最后的总结
将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作.
适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)--适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。
The above is the detailed content of About PHP design pattern-detailed explanation of adapter method. For more information, please follow other related articles on the PHP Chinese website!