Maison > Article > développement back-end > À propos du modèle de conception PHP - Explication détaillée de la méthode de l'adaptateur
Convertissez l'interface d'une classe en une autre interface souhaitée par le client. Le mode Adaptateur permet aux classes qui ne peuvent pas fonctionner ensemble en raison d'interfaces incompatibles de travailler ensemble. Cet article partage principalement avec vous l'explication détaillée de l'adaptateur, en espérant vous aider.
Rôle cible : Définit l'interface spécifique au domaine utilisée par le client, c'est ce que nous attendons
Rôle source : L'interface à adapter
Rôle d'adaptateur : Adapter l'interface Adaptee et l'interface cible ; l'adaptateur est le cœur de ce modèle. L'adaptateur convertit l'interface source en interface cible. Classe
1 Vous souhaitez utiliser une classe existante, mais son interface ne répond pas à vos besoins
2. Vous souhaitez créer une classe pouvant être copiée. Une classe qui peut fonctionner avec d'autres classes non liées ou imprévues
3. Vous souhaitez sous-classer une classe existante, mais il est impossible de sous-classer chacune d'elles en fonction de leurs interfaces. L'adaptateur d'objet peut s'adapter à son interface de classe parent (adaptateur d'objet uniquement)
//目标角色 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();
Peut-être que vous ne savez pas ce qu'est un adaptateur basé sur ce qui précède. Alors ensuite, laissez-moi vous expliquer en détail
En fait, l'exemple le plus simple consiste à utiliser une bibliothèque de classes tierce. Ces bibliothèques de classes seront mises à niveau au fur et à mesure de la mise à niveau de la version, et les API correspondantes changeront également. Lorsque l'interface change, l'adaptateur s'avère utile
Laissez-moi vous donner un exemple pratique
Spécialisé dans la production par Black Date Toy Company Jouets, les jouets produits ne se limitent pas aux chiens, chats, lions, poissons et autres animaux. Chaque jouet peut effectuer des opérations « bouche ouverte » et « bouche fermée », et les méthodes openMouth et closeMouth sont appelées respectivement. À l'heure actuelle, il nous est facile de penser que nous pouvons d'abord définir une classe abstraite Toy, ou même une interface Toy. Ces problèmes ne sont pas importants. D'autres classes peuvent hériter de la classe parent et implémenter les méthodes de la classe parent. Il y a de l'harmonie et de la confiance.
Destruction en douceur
Afin de développer ses activités, Black Date Toy Company coopère désormais avec Red Date Remote Control Company, qui peut utiliser des dispositifs de télécommande pour contrôler la bouche de animaux. Cependant, le dispositif de contrôle à distance de Hongzao Remote Control Company appelle les méthodes doMouthOpen et doMouthClose des animaux. Ce que les programmeurs de Heizao Toy Company doivent faire maintenant, c'est mettre à niveau les classes de la série Toy afin que Toy puisse appeler les méthodes doMouthOpen et doMouthClose.
Lors de l'examen de la méthode d'implémentation, nous avons directement pensé que si vous en avez besoin, j'ajouterai simplement ces deux méthodes pour vous dans ma classe et ma sous-classe parent. Lorsque vous ajoutez encore et encore ces deux méthodes dans la classe parent et la sous-classe, vous penserez toujours à un travail aussi répétitif. Cela ne peut-il pas être résolu ? Les programmeurs deviendront fous quand il y aura des centaines de sous-classes. Les programmeurs rivalisent souvent pour voir qui est le plus « paresseux » lorsque cela n’affecte pas l’efficacité. Les programmeurs se sentiront stupides s'ils continuent à faire cela. (En fait, j'agis souvent comme cet imbécile)
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(); } }
Le programmeur vient de terminer le codage et a pris un verre d'eau, quand soudain une autre nouvelle est arrivée. Heizao Toy Company souhaite également coopérer avec Luzao Remote Control Company, car l'équipement de télécommande de Luzao Remote Control Company est moins cher et plus stable. Cependant, le dispositif de contrôle à distance de Green Date Remote Control Company appelle la méthode operMouth(type) de l'animal pour obtenir le contrôle de la bouche. Si le type est 0, "tais-toi", sinon ouvrez la bouche. Maintenant, le programmeur doit mettre à niveau Toy et ses sous-classes afin que Toy puisse appeler la méthode operMouth(). Plus personne n’est calme.
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(); } } }
En ce moment, les programmeurs doivent utiliser leur cerveau pour trouver une solution Même s'ils sont diligents, si un jour toutes les sociétés télécommandées telles que les dattes violettes, les dattes vertes, les dattes jaunes et les dattes de montagne. venez, ils continueront à s'ignorer. Sans parler de la charge de travail accrue, cette classe Toy devient de plus en plus grande. Un jour, si le programmeur ne plante pas, le système plantera aussi.
Quel est le problème ?
En écrivant du code comme ci-dessus, l'implémentation du code viole le principe « ouvert-fermé », une entité logicielle devrait Ouvert pour extension, fermé pour modification. Autrement dit, lors de la conception d'un module, celui-ci doit être étendu sans être modifié. En d'autres termes, chaque cadavre est un petit royaume. Vous pouvez me laisser participer à vos affaires, mais vous ne pouvez pas modifier mon code interne à moins que mon code interne puisse réellement être optimisé.
Avec cette idée, nous comprenons comment utiliser l'héritage, comment utiliser le polymorphisme et même comment obtenir « une cohésion élevée, un faible couplage ».
回到这个问题,我们现在面临这么一个问题,新的接口方法我要实现,旧的接口(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类及其子类在不改变自身的情况下,通过适配器实现了不同的接口。
最后的总结
将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作.
适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)--适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!