java设计模式-适配器模式

你的名字 2022-05-28 10:08 399阅读 0赞

文章转自汤高的Java设计模式(六)—-适配器模式

适配模式的目的
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。


适配器模式:
1、类适配器(使用继承和实现的方式)
2、对象适配器(使用组合的方式,构造方法传入的形式)
3、缺省适配器(缺省适配器与上面的大不同,不是为了使两个类一起工作,而是为了方便代码的可读性,或者方便性)

缺省模式参考链接:
设计模式-缺省适配器模式
Java与模式:缺省适配器模式
比较简单明了,不要往类适配器和对象适配器上面套。

概述
 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
适配器模式的用途
  即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
下面是两个典型例子
20160128161544841
20160128161603560
模式中的角色

  • 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
  • 需要适配的类(Adaptee):需要适配的类或适配者类。
  • 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。  

类的适配器模式(采用继承实现)

20160128161643952
源代码:

  1. //目标接口,或称为标准接口
  2. public interface Target {
  3. //普通功能
  4. public void request();
  5. }
  6. //已存在的、具有特殊功能、但不符合我们既有的标准接口的类
  7. public class Adaptee {
  8. public void specificRequest() {
  9. System.out.println("被适配类...我是两孔插座 具有特殊功能");
  10. }
  11. }
  12. //适配器类,继承了被适配类,同时实现标准接口
  13. public class Adapter extends Adaptee implements Target {
  14. @Override
  15. public void request() {
  16. System.out.println("我是适配器类 我能适配任何两孔插座 让它正常工作");
  17. this.specificRequest();
  18. }
  19. }
  20. public class Client {
  21. public static void main(String[] args) {
  22. Target adapter = new Adapter();
  23. //通过适配器调用特殊功能
  24. adapter.request();
  25. }
  26. }

结果:
我是适配器类 我能适配任何两孔插座 让它正常工作
被适配类…我是两孔插座 具有特殊功能


对象适配器(采用对象组合方式实现)

20160128161731671

  1. 源代码:
  2. //目标接口,或称为标准接口
  3. public interface Target {
  4. //普通功能
  5. public void request();
  6. }
  7. //已存在的、具有特殊功能、但不符合我们既有的标准接口的类
  8. public class Adaptee {
  9. public void specificRequest() {
  10. System.out.println("被适配类...我是两孔插座 具有特殊功能");
  11. }
  12. }
  13. //适配器类,直接关联被适配类,同时实现标准接口
  14. class Adapter implements Target {
  15. // 直接关联被适配类
  16. private Adaptee adaptee;
  17. // 可以通过构造函数传入具体需要适配的被适配类对象
  18. public Adapter(Adaptee adaptee) {
  19. this.adaptee = adaptee;
  20. }
  21. public void request() {
  22. // 这里是使用委托的方式完成特殊功能
  23. System.out.println("我是适配器类 我能适配任何两孔插座 让它正常工作");
  24. this.adaptee.specificRequest();
  25. }
  26. }
  27. public class Client {
  28. public static void main(String[] args) {
  29. //使用特殊功能类,即适配类,
  30. // 需要先创建一个被适配类的对象作为参数
  31. Target adapter = new Adapter(new Adaptee());
  32. adapter.request();
  33. }
  34. }

结果:
我是适配器类 我能适配任何两孔插座 让它正常工作
被适配类…我是两孔插座 具有特殊功能


类适配器和对象适配器的权衡
  • 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
  • 对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。
  • 对于对象适配器,要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。
  • 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。
  • 对于对象适配器,需要额外的引用来间接得到Adaptee。   

适配器模式的优点

更好的复用性
  系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
更好的扩展性
  在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。

适配器模式的缺点

  过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

缺省适配模式

  缺省适配(Default Adapter)模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。作为适配器模式的一个特例,缺省是适配模式在JAVA语言中有着特殊的应用。

就是一个抽象类对功能接口的所有功能做空实现 然后子类继承这个抽象类 这样就可以对部分功能进行实现或拓展了。

源代码
功能接口:

  1. package com.madman.base.designMode.adapter;
  2. public interface Man{
  3. void eat();
  4. void goWalk();
  5. }

缺省适配类

  1. package com.madman.base.designMode.adapter;
  2. public abstract class AbstraceMan implements Man{
  3. @Override
  4. public void eat() {
  5. }
  6. @Override
  7. public void goWalk() {
  8. }
  9. }

具体实现

  1. package com.madman.base.designMode.adapter;
  2. public class Madmanman extends AbstraceMan{
  3. @Override
  4. public void eat() {
  5. System.out.println("madman在吃饭");
  6. }
  7. }

客户端

  1. package com.madman.base.designMode.adapter;
  2. public class Client{
  3. public static void main(String[] args) {
  4. Man man = new Madmanman();
  5. man.eat();
  6. }
  7. }

结果:
madman在吃饭


在很多情况下,必须让一个具体类实现某一个接口,但是这个类又用不到接口所规定的所有的方法。通常的处理方法是,这个具体类要实现所有的方法,那些有用的方法要有实现,那些没有用的方法也要有空的、平庸的实现。

 这些空的方法是一种浪费,有时也是一种混乱。除非看过这些空方法的代码,程序员可能会以为这些方法不是空的。即便他知道其中有一些方法是空的,也不一定知道哪些方法是空的,哪些方法不是空的,除非看过这些方法的源代码或是文档。

 缺省适配模式可以很好的处理这一情况。可以设计一个抽象的适配器类实现接口,此抽象类要给接口所要求的每一种方法都提供一个空的方法。 他只实现某一部分功能 因为他只用到了某一部分功能而已,如果以后要用,再实现其他功能就是,但是今天他不用,就没必要该功能了!

适配器模式的用意是要改变源的接口,以便于目标接口相容。缺省适配的用意稍有不同,它是为了方便建立一个不平庸的适配器类而提供的一种平庸实现。

在任何时候,如果不准备实现一个接口的所有方法时,就可以使用“缺省适配模式”制造一个抽象类,给出所有方法的平庸的具体实现。这样,从这个抽象类再继承下去的子类就不必实现所有的方法了

发表评论

表情:
评论列表 (有 0 条评论,399人围观)

还没有评论,来说两句吧...

相关阅读