设计模式(五)适配器模式

适配器:

 

  适配器这个东西,我想没什么人会感到陌生,平时我们手机充电的时候,连接插座和数据线的那个“插头”,就是我们口中的适配器。

  为什么会需要这个东西呢?

  这是由于产品的多样性造成的。在中国,每一个插座提供的电压为220V,而在其他国家,这个标准可能是110V,和中国有所不同。

  而不是每个产品,在充电的时候,都需要220V的电压,有可能某些产品只需要110V,或者其他标准的电压,这种情况,一般称之为:不适配。

  如果出现不适配的情况,强行充电,那么某些产品就可能一些不可预料的情况,例如,爆炸。

  而适配器就是用来针对这种不适配情况的解决方案。

  每一个适配器,都有一个输出和一个输入,将插座中获取的标准电压,转换成产品可以接受的特殊电压,保证充电的安全性。

  这个输入和输出,也可能是一个范围。

 

 

适配器模式:

 

  在开发的过程中,也许会遇见接口不兼容的问题,适配器模式就是这类问题的一种解决方案。

  适配器模式分为两种:类适配器模式、对象适配器模式,前者是基于多继承实现的,在 Java 中不做讨论。

  接口不兼容的具体表现为:某一个类,需要去实现某一个接口提供的行为,但是却没有能力做到这一点,这就是之前在适配器中提到的不兼容。

  以上提到的,没有能力,具体指的是要做到这一点,会打破设计中的一些基本准则。

  下面看另一个具体的现实场景,适配器模式的具体实现,会在之后的场景中体现。

 

 

现实场景:

 

  在我们平时的日常中,翻译就是另一个典型的适配器模式应用。

  现在假设这么一个场景:在球场上,教练制定战术,告诉球员。

  教练制定战术所用的语言是英文,这就是一个标准(类比中国插座提供的220V电压)。

  但是球员来自世界各地,不可能每一个人都懂英文(类比需要定制化电压的产品),这就产生了不适配的问题。

 

  一般来说,以上的情况会怎么解决?

  也许教练足够博学,他能够提供不止一套标准,也就是懂多国语言,可以将战术通过其他语言复述一遍,但是通常都不会这么做。

  那就要每一个非英文母语球员,自己尝试去理解教练布置的战术,在这个过程中,需要一个翻译。

  翻译就是这个场景中的适配器,他和其他英文母语的球员一样,拥有听懂教练布置战术的能力。

 

 

思想:

 

  根据之前提供的解决方案,英文球员和翻译,都拥有相同的行为,所以会实现同一个接口,或者继承同一个抽象类。

  非英文的球员(Adaptee),依赖翻译(Adapter),来实现理解战术的过程。

 

 

UML:

 

 

 

代码:

 

1 public interface IntroductionEN {
2 
3     void attackEN();
4 
5     void defenseEN();
6 
7 }
IntroductionEN
 1 @AllArgsConstructor
 2 @Data
 3 public class ManEN implements IntroductionEN {
 4 
 5     private String name;
 6 
 7     @Override
 8     public void attackEN() {
 9         System.out.println(this.name + " Attack");
10     }
11 
12     @Override
13     public void defenseEN() {
14         System.out.println(this.name + " Defense");
15     }
16 
17 }
ManEN
 1 @Data
 2 @AllArgsConstructor
 3 public class ManCN {
 4 
 5     private String name;
 6 
 7     public void attackCN() {
 8         System.out.println(this.name + " 进攻");
 9     }
10 
11     public void defenseCN() {
12         System.out.println(this.name + " 防守");
13     }
14 
15 }
ManCN
 1 @Data
 2 @AllArgsConstructor
 3 public class TranslatorEN implements IntroductionEN {
 4 
 5     private ManCN manCN;
 6 
 7     @Override
 8     public void attackEN() {
 9         manCN.attackCN();
10     }
11 
12     @Override
13     public void defenseEN() {
14         manCN.defenseCN();
15     }
16 
17 }
TranslatorEN

 

 

应用场景:

 

  在编程世界里,不存在做不到这种事情,之所以使用适配器模式,更多的是为了防止代码打破开-闭原则。

  所以,在设计代码的时候,一般不会考虑适配器模式,它更多的,是一种面对需求变更的补救措施。

  适配器模式最多的应用场景,是为了适配第三方软件。

  系统没有必要为了实现第三方提供的接口,而对自己的代码进行大的修改,这是就需要一个专门的适配器,去适应这些接口了。

 

posted @ 2017-10-05 12:00  Gerrard_Feng  阅读(181)  评论(0编辑  收藏  举报