보름 넘게 에세이를 쓰지 못한 이유는 4학년이 되면 할 일이 너무 많아서 취업이 막히기 때문이에요. 제 스스로의 체력이 부족한 것도 큰 이유지만, 더 중요한 것은 뛰어난 실무 경험이 부족해서 인사팀의 관심을 끌기가 어려웠습니다. 그래서 여기 누군가가 나에게 일자리를 주길 바라는 작은 광고가 있습니다. 인턴십을 해도 상관없습니다. 최악의 경우 급여를 받지 못해도 상관없습니다. 전혀 결론이 없습니다). 위치는 임의적이지만 현재는 청두에서 남은 1년만 마무리하면 어디든 코드를 작성할 수 있습니다.
나는 항상 "좋은 사실을 많이 알고 있지만 이 삶을 제대로 살 수 없다"고 느낀다고 말하기가 부끄럽습니다. 누군가가 이 블로그를 읽는지 여부에 관계없이 항상 현재 지식에 대해 작성해야 하며, 더 중요한 것은 선배들의 지도를 받기를 바랍니다.
주제로 돌아가서, 세 가지 기본 디자인 패턴 을 공유한 후 오늘은 자주 사용하지 않는 것 같지만 필요할 때 매우 편리한 또 다른 모드인 어댑터를 공유하겠습니다. 모델.
객체가 있든 없든 "객체지향"을 외치는 이 시대, 객체지향을 익히면 예상치 못한 편리함을 얻을 수 있습니다. . 프로그래밍을 배우는 친구는 먼저 몇 줄의 코드를 작성하여 간단한 기능을 구현한 다음 나중에 일부 반복 작업을 결합하여 "함수"를 형성하고 나중에 "함수"와 속성을 결합하여 "클래스"를 형성하는 방법을 배울 수 있습니다. 단계적으로 우리는 코드를 실행하는 기계의 효율성을 높이는 동시에 프로그래머의 작업량을 줄이는 것을 고려하고 있습니다. 그렇다면 오늘 이야기하는 어댑터 모델에서 더 중요한 고려사항은 무엇일까요? 프로그래머의 작업량입니다.
어댑터 패턴은 언제 사용되나요?
실제로 가장 간단한 예는 타사 라이브러리를 참조하는 경우입니다. 이 클래스 라이브러리의 버전이 변경되면 제공되는 API도 변경될 수 있습니다. 안타깝게도 애플리케이션에서 참조하는 API가 변경된 경우 마음속으로 "wocao"를 욕하는 것 외에도 많은 코드를 변경해야 합니다.
꼭 이래야 하나요? 일반적으로 나는 "아니요"라고 대답합니다. 어댑터 패턴이 있어요~~
인터페이스가 바뀌면 어댑터 패턴이 유용하죠.
예를 들어보세요
위의 간단한 설명으로 이해가 된다면, 뛰어난 이해력에 감탄할 수밖에 없습니다. 대부분의 사람들은 여전히 혼란스러워할 것입니다. 이해를 돕기 위해 한 블로거의 예를 인용하겠습니다. 원래 주소.
태초의 조화
헤이자오토이컴퍼니는 장난감 전문 생산업체로, 생산하는 장난감은 이에 국한되지 않습니다. 개, 고양이, 사자, 물고기 및 기타 동물. 각 장난감은 "입 열기" 및 "입 닫기" 작업을 수행할 수 있으며 openMouth 및 closeMouth 메서드가 각각 호출됩니다.
이때는 추상 클래스인 Toy나 인터페이스인 Toy를 먼저 정의하면 된다고 생각하기 쉽습니다. 다른 클래스가 상위 클래스를 상속받아 메소드를 구현할 수도 있습니다. 부모 클래스의. 조화와 자신감이 있습니다.
균형파괴
사업확장을 위해 현재 블랙데이토이컴퍼니는 레드데이트리모컨컴퍼니와 협력하게 되었고, 레드데이트리모콘컴퍼니는 원격제어 장비를 이용하여 동물을 제어할 수 있습니다. 그러나 Hongzao Remote Control Company의 원격 제어 장치는 동물의 doMouthOpen 및 doMouthClose 메소드를 호출합니다. Heizao Toy Company의 프로그래머가 지금 해야 할 일은 Toy가 doMouthOpen 및 doMouthClose 메소드를 호출할 수 있도록 Toy 시리즈 클래스를 업그레이드하는 것입니다.
구현 방법을 고려할 때 필요하다면 이 두 가지 방법을 상위 클래스와 하위 클래스에 추가하면 될 것이라고 직접 생각했습니다. 이 두 메소드를 상위 클래스와 하위 클래스에 계속해서 추가하다 보면 이런 반복적인 작업에 대해 항상 고민하게 되는데, 해결이 되지 않을까요? 수백 개의 하위 클래스가 있으면 프로그래머는 미칠 것입니다. 프로그래머는 효율성에 영향을 미치지 않으면서 누가 더 "게으른"지 확인하기 위해 경쟁하는 경우가 많습니다. 프로그래머들이 이런 일을 계속한다면 바보처럼 느껴질 것입니다. (사실 이런 바보같은 짓을 자주함)
<span>abstract</span><span>class</span><span> Toy { </span><span>public</span><span>abstract</span><span>function</span><span> openMouth(); </span><span>public</span><span>abstract</span><span>function</span><span> closeMouth(); </span><span>//</span><span>为红枣遥控公司控制接口增加doMouthOpen方法</span><span>public</span><span>abstract</span><span>function</span><span> doMouthOpen(); </span><span>//</span><span>为红枣遥控公司控制接口增加doMouthClose方法</span><span>public</span><span>abstract</span><span>function</span><span> doMouthClose(); } </span><span>class</span> Dog <span>extends</span><span> Toy { </span><span>public</span><span>function</span><span> openMouth() { </span><span>echo</span> "Dog open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> closeMouth() { </span><span>echo</span> "Dog open Mouth\n"<span>; } </span><span>//</span><span>增加的方法</span><span>public</span><span>function</span><span> doMouthOpen() { </span><span>$this</span>-><span>doMouthOpen(); } </span><span>//</span><span>增加的方法</span><span>public</span><span>function</span><span> doMouthClose() { </span><span>$this</span>-><span>closeMouth(); } } </span><span>class</span> Cat <span>extends</span><span> Toy { </span><span>public</span><span>function</span><span> openMouth() { </span><span>echo</span> "Cat open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> closeMouth() { </span><span>echo</span> "Cat open Mouth\n"<span>; } </span><span>//</span><span>增加的方法</span><span>public</span><span>function</span><span> doMouthOpen() { </span><span>$this</span>-><span>doMouthOpen(); } </span><span>//</span><span>增加的方法</span><span>public</span><span>function</span><span> doMouthClose() { </span><span>$this</span>-><span>closeMouth(); } }</span>
더 짜증나
프로그래머가 막 코딩을 끝냈어 , 물을 한 모금 마셨는데 갑자기 또 다른 소식이 왔습니다.
Black Zao Toy Company도 Lu Zao Remote Control Company와 협력하고 싶어합니다. Lu Zao Remote Control Company의 원격 제어 장비가 더 저렴하고 안정적이기 때문입니다. 그러나 그린데이트리모컨컴퍼니의 원격제어 장치는 입 제어를 구현하기 위해 동물의 operMouth($type) 메소드를 호출한다. $type이 0이면 "닥쳐", 그렇지 않으면 입을 벌립니다.
이제 프로그래머는 Toy가 operMouth() 메서드를 호출할 수 있도록 Toy와 그 하위 클래스를 업그레이드해야 합니다. 더 이상 아무도 침착하지 않습니다.
<span>abstract</span><span>class</span><span> Toy { </span><span>public</span><span>abstract</span><span>function</span><span> openMouth(); </span><span>public</span><span>abstract</span><span>function</span><span> closeMouth(); </span><span>public</span><span>abstract</span><span>function</span><span> doMouthOpen(); </span><span>public</span><span>abstract</span><span>function</span><span> doMouthClose(); </span><span>//</span><span>为绿枣遥控公司控制接口增加doMouthClose方法 </span><span>public</span><span>abstract</span><span>function</span> operateMouth(<span>$type</span> = 0<span>); } </span><span>class</span> Dog <span>extends</span><span> Toy { </span><span>public</span><span>function</span><span> openMouth() { </span><span>echo</span> "Dog open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> closeMouth() { </span><span>echo</span> "Dog open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> doMouthOpen() { </span><span>$this</span>-><span>doMouthOpen(); } </span><span>public</span><span>function</span><span> doMouthClose() { </span><span>$this</span>-><span>closeMouth(); } </span><span>public</span><span>function</span> operateMouth(<span>$type</span> = 0<span>) { </span><span>if</span> (<span>$type</span> == 0<span>) { </span><span>$this</span>-><span>closeMouth(); } </span><span>else</span><span> { </span><span>$this</span>-><span>operateMouth(); } } } </span><span>class</span> Cat <span>extends</span><span> Toy { </span><span>public</span><span>function</span><span> openMouth() { </span><span>echo</span> "Cat open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> closeMouth() { </span><span>echo</span> "Cat open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> doMouthOpen() { </span><span>$this</span>-><span>doMouthOpen(); } </span><span>public</span><span>function</span><span> doMouthClose() { </span><span>$this</span>-><span>closeMouth(); } </span><span>public</span><span>function</span> operateMouth(<span>$type</span> = 0<span>) { </span><span>if</span> (<span>$type</span> == 0<span>) { </span><span>$this</span>-><span>closeMouth(); } </span><span>else</span><span> { </span><span>$this</span>-><span>operateMouth(); } } }</span>
이때 프로그래머들은 열심히 머리를 써서 방법을 찾아야 하는데, 언젠가 모든 원격제어 회사가 보라색 대추, 녹색을 좋아하게 된다면 어떨까요? 날짜, 노란색 날짜, 산 날짜가 올까요? 그 때 증가하는 작업량에 관계없이 이 Toy 클래스는 어느 날 프로그래머가 충돌하지 않으면 시스템도 충돌합니다.
어디가 문제인가요?
像上面那样编写代码,代码实现违反了“开-闭”原则,一个软件实体应当对扩展开放,对修改关闭。即在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。也就是说每个尸体都是一个小王国,你让我参与你的事情这个可以,但你不能修改我的内部,除非我的内部代码确实可以优化。
在这种想法下,我们懂得了如何去用继承,如何利用多态,甚至如何实现“高内聚,低耦合”。
回到这个问题,我们现在面临这么一个问题,新的接口方法我要实现,旧的接口(Toy抽象类)也不能动,那么总得有个解决方法吧。那就是引入一个新的类--我们本文的主角--适配器。 适配器要完成的功能很明确,引用现有接口的方法实现新的接口的方法。更像它名字描述的那样,你的接口不改的话,我就利用现有接口和你对接一下吧。
到此,解决方法已经呼之欲出了,下面贴上代码。
<?<span>php </span><span>abstract</span><span>class</span><span> Toy { </span><span>public</span><span>abstract</span><span>function</span><span> openMouth(); </span><span>public</span><span>abstract</span><span>function</span><span> closeMouth(); } </span><span>class</span> Dog <span>extends</span><span> Toy { </span><span>public</span><span>function</span><span> openMouth() { </span><span>echo</span> "Dog open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> closeMouth() { </span><span>echo</span> "Dog close Mouth\n"<span>; } } </span><span>class</span> Cat <span>extends</span><span> Toy { </span><span>public</span><span>function</span><span> openMouth() { </span><span>echo</span> "Cat open Mouth\n"<span>; } </span><span>public</span><span>function</span><span> closeMouth() { </span><span>echo</span> "Cat close Mouth\n"<span>; } } </span><span>//</span><span>目标角色:红枣遥控公司 </span><span>interface</span><span> RedTarget { </span><span>public</span><span>function</span><span> doMouthOpen(); </span><span>public</span><span>function</span><span> doMouthClose(); } </span><span>//</span><span>目标角色:绿枣遥控公司及 </span><span>interface</span><span> GreenTarget { </span><span>public</span><span>function</span> operateMouth(<span>$type</span> = 0<span>); } </span><span>//</span><span>类适配器角色:红枣遥控公司 </span><span>class</span> RedAdapter <span>implements</span><span> RedTarget { </span><span>private</span><span>$adaptee</span><span>; </span><span>function</span> __construct(Toy <span>$adaptee</span><span>) { </span><span>$this</span>->adaptee = <span>$adaptee</span><span>; } </span><span>//</span><span>委派调用Adaptee的sampleMethod1方法 </span><span>public</span><span>function</span><span> doMouthOpen() { </span><span>$this</span>->adaptee-><span>openMouth(); } </span><span>public</span><span>function</span><span> doMouthClose() { </span><span>$this</span>->adaptee-><span>closeMouth(); } } </span><span>//</span><span>类适配器角色:绿枣遥控公司 </span><span>class</span> GreenAdapter <span>implements</span><span> GreenTarget { </span><span>private</span><span>$adaptee</span><span>; </span><span>function</span> __construct(Toy <span>$adaptee</span><span>) { </span><span>$this</span>->adaptee = <span>$adaptee</span><span>; } </span><span>//</span><span>委派调用Adaptee:GreenTarget的operateMouth方法 </span><span>public</span><span>function</span> operateMouth(<span>$type</span> = 0<span>) { </span><span>if</span> (<span>$type</span><span>) { </span><span>$this</span>->adaptee-><span>openMouth(); } </span><span>else</span><span> { </span><span>$this</span>->adaptee-><span>closeMouth(); } } } </span><span>class</span><span> testDriver { </span><span>public</span><span>function</span><span> run() { </span><span>//</span><span>实例化一只狗玩具 </span><span>$adaptee_dog</span> = <span>new</span><span> Dog(); </span><span>echo</span> "给狗套上红枣适配器\n"<span>; </span><span>$adapter_red</span> = <span>new</span> RedAdapter(<span>$adaptee_dog</span><span>); </span><span>//</span><span>张嘴 </span><span>$adapter_red</span>-><span>doMouthOpen(); </span><span>//</span><span>闭嘴 </span><span>$adapter_red</span>-><span>doMouthClose(); </span><span>echo</span> "给狗套上绿枣适配器\n"<span>; </span><span>$adapter_green</span> = <span>new</span> GreenAdapter(<span>$adaptee_dog</span><span>); </span><span>//</span><span>张嘴 </span><span>$adapter_green</span>->operateMouth(1<span>); </span><span>//</span><span>闭嘴 </span><span>$adapter_green</span>->operateMouth(0<span>); } } </span><span>$test</span> = <span>new</span><span> testDriver(); </span><span>$test</span>->run();
最后的结果就是,Toy类及其子类在不改变自身的情况下,通过适配器实现了不同的接口。
最后总结
将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作.
适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)--适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。
以上
系列文章:
php模式设计之 单例模式
php模式设计之 工厂模式
php模式设计之 注册树模式
php模式设计之 适配器模式
以上就介绍了php模式设计之 适配器模式,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。