适配器模式 秒速五厘米 2021-09-18 07:08 291阅读 0赞 # 说文解字 # ## 维度一:首先先来看看适配的中文解释 ## ![18721752-f0247f0585b6a865.png][] image.png ## 维度二:英文翻译 ## Adapter Design Patter ## notice:适配可以按照编程的思想这么理解: ## 兼容多个为了实现同一个目的类,提供统一的对外接口。 这个设计模式重点就在兼容两个字。 说兼容不容说是改造,将原本不符合要求的东西改造成现在想要的逻辑。 # 使用场景 # 1.兼容多个外部依赖(或者不同的业务类)实现相同的目的提供统一的对外接口给客户端使用。 2.兼容其他不可改的code(第三方或者项目补丁升级),再不改变源代码的前提下做对相同目的的功能增强。 # 使用范式 # ## 1.类适配器 ## //适配类 众多类要实现的目的接口,用来定义众多类的目标 publict interface Itarget{ void target(); } //被适配者 被改造者 public class XxxAdaptee{ public int origFunction(){ //原本应该执行的业务逻辑 } } //适配器 public class XxxAdaptor extends Adaptee implements ITarget { public void target() { //调用adaptee原本的方法 int origValue = origFunction(); //........执行将原有值改造成符合当前目的的逻辑 } } //包装类 public class PackClasss { //对外暴露方法,参数必然为接口类型 public void charging(Itarget itarget) { itarget.target(); } } //使用者客户端 public class Client { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(" === 对象适配器模式 ===="); PackClasss packClass = new PackClasss(); //使用者直接使用包装类,每次使用就用对应的被适配者即可不用改代码 packClass.target(new XxxAdaptee()); } } # 2.对象适配器 # //适配类 众多类要实现的目的接口,用来定义众多类的目标 publict interface Itarget{ void target(); } //被适配者 被改造者 public class XxxAdaptee{ public int origFunction(){ //原本应该执行的业务逻辑 } } //适配器 public class XxxAdaptor implements ITarget { //不通过继承,而是通过关系聚合XxxAdaptee类 private XxxAdaptee xxxadaptee; //构造方法对外暴露赋值接口 public XxxAdaptor(XxxAdaptee xxxadaptee) { this.xxxadaptee = xxxadaptee; } public void target() { //调用adaptee原本的方法 int origValue = xxxadaptee.origFunction(); //........执行将原有值改造成符合当前目的的逻辑 } } //包装类 public class PackClasss { //对外暴露方法,参数必然为接口类型 public void charging(Itarget itarget) { itarget.target(); } } //使用者客户端 public class Client { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(" === 对象适配器模式 ===="); PackClasss packClass = new PackClasss(); //使用者直接使用包装类,每次调用PackClasss 传入不同的adapter并赋值被改造者adaptee packClass.target(new XxxAdaptor(new XxxAdaptee())); } } ### ### notice: #### n1.总结使用规律: #### 通过以上发现都是通过包装类调用包装类的参数为接口的方法,通过这个方法调用,每次调用都不需要改动包装类,也就是适配器整体对外暴露的接口,每次适配器的变动不会影响适配器包装类对外暴露的接口。 #### n2.对比类适配和对象适配 #### 类适配的缺点: 适配器要想适配必须先继承被适配者,类适配器的缺点基本都是围绕这点说的。 1.Java是单继承,如果继承了被适配类,那么将不能再去继承其他类了。 2.适配器因为继承adaptee,那么adaptee相当于完全暴露在adapter中,继承了adaptee的一切,增加了adapter的使用成本。 对象适配相比类适配的改进: 1.根据“合成复用原则”,在系统中尽量使用关联关系(聚合)来替代继承关系。 2.使用成长更低,更灵活。 #### n3.两者的相同点 #### 象适配器和类适配器其实算是同一种思想,只不过实现方式不同。 适配器的思想 兼容不同的被适配者们,以达到同一个目的。 类适配器的落地思想 在不直接改变被适配者们的前提下,通过定义目标接口,对被适配者们进行改造,再通过包装类统一对外提供标准一致的且入参为接口的方法供外部使用。 ## 3.接口适配器 ## ### 核心思路 ### 当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求 ### 使用场景 ### 适用于一个接口不想使用其所有的方法的情况。 范式code //一个被嫌弃的接口 public interface Ixxxinterface { public void m1(); public void m2(); public void m3(); public void m4(); } //定义一个抽象接口实现用户不想实现所有方法的接口 public abstract class AbsAdapter implements Ixxxinterface { //默认实现 @Override public void m1() { } @Override public void m2() { } @Override public void m3() { } @Override public void m4() { } } public class Client { public static void main(String[] args) { //客户端这里只针对要使用的接口做增强 AbsAdapter absAdapter = new AbsAdapter() { @Override public void m1() { // TODO Auto-generated method stub System.out.println("使用了m1的方法"); } }; absAdapter.m1(); } } # 适配器的使用总结 # 适配器提供一种打补丁的思路,在不更改adaptee的前提下,通过适配器提供和adaptee不同的接口,来实现对adaptee的改造。 [18721752-f0247f0585b6a865.png]: /images/20210918/43cb76d2234f477d878280ac7515b262.png
还没有评论,来说两句吧...