适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern) 是作为两个不兼容的接口之间的桥梁。
例子:读卡器是作为内存卡和笔记本之间的是适配器,内存卡插入读卡器,读卡器再插入笔记本电脑。
参考资料: 、
作用:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
何时使用:1.要使用已有的一个类的方法,但是不符合我们的使用规范,且我们不知道其源码,无法copy。2。建立一个重复使用的类,用于联系一些彼此之间没有太大联系的类。3.通过接口的转换,将一个类插入到另一个类中。
如何实现:继承或者依赖。适配器继承或者依赖已有的代码,实现目标类的接口。
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
适配器有两种模式:这两种的差别在于一个是继承源角色类,一个是获取源角色类的对象。
类适配器模式:(继承源角色)
对象适配器模式:(获取源角色对象)
差别:1.类适配器的话,因为是继承了源角色类的关系,所以不能去处理源角色类的子类。而对象适配器则没有关系,一个适配器可以将其源类和其子类都适配到目标接口。
2.类适配器可以重新定义源角色类的方法,通过重写方法即可。而对象适配器的话只能通过适配器子类的方法来达到重写源角色类的方法 。
代码实现:类适配器模式
1 /** 2 * 目标角色 3 */ 4 public interface Target { 5 //已有的方法 6 void sampleOp1(); 7 //没有但是想要实现的方法 8 void sampleOp2(); 9 }
1 /** 2 * 源角色 3 */ 4 public class Adaptee { 5 6 public void sampleOp1(){ 7 System.out.println("sampleOp1..."); 8 } 9 }
1 /** 2 * 适配器角色 3 */ 4 public class Adapter extends Adaptee implements Target { 5 6 @Override 7 public void sampleOp2() { 8 System.out.println("sampleOp2...."); 9 } 10 }
//测试 @Test public void test()throws Exception{ Target target = new Adapter(); target.sampleOp1(); target.sampleOp2(); } /* *输出 *sampleOp1... *sampleOp2.... */
代码实现:对象适配器模式
1 /** 2 * 目标角色 3 */ 4 public interface Target { 5 //已有的方法 6 void sampleOp1(); 7 //没有但是想要实现的方法 8 void sampleOp2(); 9 } 10 11 12 /** 13 * 源角色 14 */ 15 public class Adaptee { 16 public void sampleOp1(){ 17 System.out.println("sampleOp1..."); 18 } 19 } 20 21 22 /** 23 * 适配器角色 24 */ 25 public class Adapter implements Target{ 26 private Adaptee adaptee; 27 28 public Adapter(Adaptee adaptee) { 29 this.adaptee = adaptee; 30 } 31 32 @Override 33 public void sampleOp1() { 34 this.adaptee.sampleOp1(); 35 } 36 37 @Override 38 public void sampleOp2() { 39 System.out.println("sampleOp2...."); 40 } 41 }
//测试
@RunWith(SpringRunner.class) @SpringBootTest public class AdapterTest { @Test public void test()throws Exception{ Target adapter = new Adapter(new Adaptee()); adapter.sampleOp1(); adapter.sampleOp2(); } } /* *sampleOp1... *sampleOp2.... */
除此之外,适配器模式还有一种应用。缺省模式
应用场景:我们要实现一个接口,但是在该接口的大量方法内部,我们只想要其中的少数一两个。
在接口的实现中,必须要将其所有的方法进行重写。所以会在代码内有大量的空缺省的方法,造成类的臃肿。
适配器的缺省模式:一个抽象的适配器角色实现该接口。
目标角色继承该抽象类。只需要实现自己想要的方法即可。
代码实现:
1 /** 2 * 一个和尚应该要做的事情 3 */ 4 public interface Bonze { 5 void chiZhai(); 6 void nianFo(); 7 void daZuo(); 8 void saoDi(); 9 void xiWu(); 10 void zhuangZhong(); 11 String getName(); 12 } 13 14 15 16 /** 17 * 适配器 18 */ 19 public abstract class TianStar implements Bonze { 20 @Override 21 public void chiZhai() { 22 23 } 24 25 @Override 26 public void nianFo() { 27 28 } 29 30 @Override 31 public void daZuo() { 32 33 } 34 35 @Override 36 public void saoDi() { 37 38 } 39 40 @Override 41 public void xiWu() { 42 43 } 44 45 @Override 46 public void zhuangZhong() { 47 48 } 49 50 @Override 51 public String getName() { 52 return null; 53 } 54 } 55 56 57 58 /** 59 * 目标角色 60 */ 61 public class LuZhiShen extends TianStar { 62 @Override 63 public void xiWu() { 64 System.out.println("" + 65 " 拳打镇关西;\n" + 66 " 大闹五台山;\n" + 67 " 大闹桃花村;\n" + 68 " 火烧瓦官寺;\n" + 69 " 倒拔垂杨柳;"); 70 } 71 72 @Override 73 public String getName() { 74 return "鲁智深在此"; 75 } 76 } 77 78 79 @RunWith(SpringRunner.class) 80 @SpringBootTest 81 public class LuZhiShenTest { 82 83 @Test 84 public void test()throws Exception{ 85 Bonze bonze = new LuZhiShen(); 86 bonze.xiWu(); 87 System.out.println(bonze.getName()); 88 } 89 } 90 91 /* 92 * 拳打镇关西; 93 * 大闹五台山; 94 * 大闹桃花村; 95 * 火烧瓦官寺; 96 * 倒拔垂杨柳; 97 *鲁智深在此 98 */