package adapter; /**目标角色 Target 接口 * 香港地区使用的插座面板,提供输出电流的功能 * @author noteless * */ public interface TargetHongkongPanelInterface { public void offerHongKongElectricity(); } package adapter; /**目标角色 Target 某个具体的港版插座面板 实现类 * 香港地区使用的插座面板,提供输出电流的功能 * @author noteless * */ public class TargetHongkongPanel implements TargetHongkongPanelInterface{ @Override public void offerHongKongElectricity() { System.out.println("港版面板 提供电流"); } }
大陆地区插座面板
package adapter; /**被适配角色 Adaptee 接口 * 大陆地区使用的插座面板,提供输出电流的功能 * @author noteless * */ public interface AdapteeChinaMainlandPanelInterface { public void offerChinaMainlandElectricity(); } package adapter; /**被适配角色 Adaptee 某种具体类型的插座面板 实现类 * 大陆地区使用的插座面板,提供输出电流的功能 * @author noteless */ public class AdapteeChinaMainlandPanel implements AdapteeChinaMainlandPanelInterface{ @Override public void offerChinaMainlandElectricity() { System.out.println("国标面板 提供电流"); } }
package adapter; /**客户角色 Client 港版插头 * @author noteless * */ public class ClientHongKongSocket { /**接受港版插座面板作为参数 * 港版插头,插入到港版插座面板 * @param targetHongkongPanel */ public void plugIn(TargetHongkongPanelInterface targetHongkongPanel) { targetHongkongPanel.offerHongKongElectricity(); } /* * 测试主程序,港版插头 插入到适配器上 * 适配器插入到大陆面板上 */ public static void main(String ...args) { //港版插头 ClientHongKongSocket socket = new ClientHongKongSocket(); //大陆面板 AdapteeChinaMainlandPanel adapteeChinaMainlandPanel = new AdapteeChinaMainlandPanel(); //适配器 Adapter adapter = new Adapter(adapteeChinaMainlandPanel); //港版插头 插到 适配器上 socket.plugIn(adapter); } }
package adapter; /**适配器角色 Adapter * 实现目标角色 TargetHongkongPanelInterface * 组合使用被适配角色 AdapteeChinaMainlandPanelInterface * 将对目标角色的方法调用转换为被适配角色的方法调用 * @author noteless * */ public class Adapter implements TargetHongkongPanelInterface{ private AdapteeChinaMainlandPanelInterface adapteeChinaMainlandPanel; Adapter(AdapteeChinaMainlandPanel adapteeChinaMainlandPanel){ this.adapteeChinaMainlandPanel = adapteeChinaMainlandPanel; } @Override public void offerHongKongElectricity() { adapteeChinaMainlandPanel.offerChinaMainlandElectricity(); } }
意图:
将一个类的接口转换成客户希望的另外一个接口。
适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.
注意:此处说的接口,并不是单纯的指Interface,而是指一切可以提供方法调用的类型,可能是接口也可能是类
|
客户使用适配器的过程:
客户通过目标接口调用适配器的方法,对适配器发出请求
适配器使用被适配者接口把请求进行处理
客户接收到调用的结果,但是并未察觉这一切是适配器在起转换作用.
|
适配器三种模式 |
类适配器 对象适配器 接口适配器 |
想要把一个类的接口转换为客户希望的另外一个接口 必须要有输入输出,有目标 有源 所以作为一个适配器,必须要 一手拿着被适配者也就是源 另一手拿着的是目标 想要转变为目标,那么必须得同目标时一样的类型, 在oop中想要成为目标类型 要么继承 要么实现 想要拥有被适配者,要么继承,要么实现,要么就是关联(拥有一个对象) 三种方式可以理解为按照 拥有被适配者 的方式进行划分的 如果继承Adaptee,那么就是类 适配器 如果拥有一个Adaptee,也就是拥有一个Adaptee对象,那么就是对象 适配器 如果实现Adaptee,那么就是 接口适配器 |
类适配器
根据上面的描述,如果继承Adaptee,那么就是类 适配器,
在Java中不允许多继承,既然已经继承了Adaptee ,那么就必须要求目标是一个接口(此处接口就是Interface)
这就有一定的局限性
而且,既然是继承被适配者类,那么,被适配者的子类拥有的方法和行为,他并不能拥有,也就是说不能适配被适配者的子类
|
优点,那就是,适配器作为被适配者的子类,自然拥有更多的操作空间,比如重写方法 |
对象适配器 |
如同我们上面的例子一样,如果把被适配者当做一个属性对象放到适配器中,这就是对象适配器
显然,他不要求目标一定是接口, 继承还是实现都可以
同类适配器比较的话,显然,他不能对被适配者 原来的一些方法进行操作,只能进行使用,不过也无伤大雅,不算缺点
因为他是拥有一个被适配者类型的对象,那么,被适配者和他的子类显然都可以作为具体的对象传入
|
接口适配器 按照我们的描述,如果实现了被适配者 Adaptee 那么就是接口适配器 具体说来: 当不需要全部实现接口提供的方法时 可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法) 那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求 它适用于一个接口不想使用其所有的方法的情况 |
package interfaceadapter; public interface Interfaces { public void method1(); public void method2(); public void method3(); public void method4(); public void method5(); }
package interfaceadapter; /** * @author noteless * */ public abstract class AbstractClass implements Interfaces { @Override public void method1() { } @Override public void method2() { } @Override public void method3() { } @Override public void method4() { } @Override public void method5() { } }
package interfaceadapter; public class ImplementClass1 extends AbstractClass { @Override public void method1() { System.out.println("method1 called "); } @Override public void method3() { System.out.println("method3 called "); } @Override public void method5() { System.out.println("method5 called "); } } package interfaceadapter; public class ImplementClass2 extends AbstractClass { @Override public void method2() { System.out.println("method2 called"); } @Override public void method4() { System.out.println("method4 called"); } }
package interfaceadapter; public class Test { public static void main(String[] args) { Interfaces class1 = new ImplementClass1(); Interfaces class2 = new ImplementClass2(); class1.method1(); class1.method2(); class1.method3(); class1.method4(); class1.method5(); System.out.println("------"); class2.method1(); class2.method2(); class2.method3(); class2.method4(); class2.method5(); } }
package doubleadapter; public interface TargetInterface { void targetRequest(); } package doubleadapter; public class TargetImplClass implements TargetInterface{ @Override public void targetRequest() { System.out.println("targetRequest ... "); } }
package doubleadapter; public interface AdapteeInterface { void adapteeRequest(); } package doubleadapter; public class AdapteeImplClass implements AdapteeInterface{ @Override public void adapteeRequest() { System.out.println("adapteeRequest ... "); } }
package doubleadapter; public class Adapter implements TargetInterface,AdapteeInterface { private TargetInterface target; private AdapteeInterface adaptee; Adapter(TargetInterface target){ this.target = target; } Adapter(AdapteeInterface adaptee){ this.adaptee = adaptee; } @Override public void adapteeRequest() { target.targetRequest(); } @Override public void targetRequest() { adaptee.adapteeRequest(); } }
适配器Adapter模式的宗旨是:
保留现有类所提供的服务,向客户提供接口,以满足客户的期望,也就是将现有接口转换为客户希望的另外的一个接口
本质在于转换
|
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.apache.commons.collections.iterators; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator;
public class EnumerationIterator implements Iterator { private Collection collection; private Enumeration enumeration; private Object last; public EnumerationIterator() { this((Enumeration)null, (Collection)null); } public EnumerationIterator(Enumeration enumeration) { this(enumeration, (Collection)null); } public EnumerationIterator(Enumeration enumeration, Collection collection) { this.enumeration = enumeration; this.collection = collection; this.last = null; } public boolean hasNext() { return this.enumeration.hasMoreElements(); } public Object next() { this.last = this.enumeration.nextElement(); return this.last; } public void remove() { if (this.collection != null) { if (this.last != null) { this.collection.remove(this.last); } else { throw new IllegalStateException("next() must have been called for remove() to function"); } } else { throw new UnsupportedOperationException("No Collection associated with this Iterator"); } } public Enumeration getEnumeration() { return this.enumeration; } public void setEnumeration(Enumeration enumeration) { this.enumeration = enumeration; } }
public class EnumerationIterator implements Iterator {
private Enumeration enumeration;
|
设计模式是作为解决问题或者设计类层级结构时的一种思维的存在,而不是公式一样的存在!
|