设计模式:适配器模式

参考文章

java-design-patterns
三大软件设计原则
你必须理解的三大软件原则3_YAGNI
设计模式之适配器模式——掘金

正文

开始学习之前,最好知道“三大软件设计原则”

三大软件设计原则

  • KISS(Keep it Simple Stupid保持简单而不复杂)

    用最少的代码实现最好的功能
    简单就是最终的复杂
    不实现过度的封装

  • YAGNI(You Ain’t Gonna Need It你不需要它)

    如果概念上没有提到,那代码中也不能出现。举个例子来讲,将数据库访问抽象在一层是惯例,他们处理不同驱动间的差异,像MySQL, PostgreSQL and Oracle。如果你正工作于一个发布在共享主机的企业网站上,那他们改变数据库的几率有多大呢?请记住概念是用预算记下来的。

  • Don’t Repeat Yourself(不做重复的事)

      在系统中,每一项知识都必须具有单一的,明确的,权威的表述。
      程序中的每个重要功能都应该在源代码中的一个地方实现。在通过不同的代码段执行类似的功能的情况下,通过提取不同的部分将它们合并成一个通常是有益的。
    为什么需要减少重复的工作:
      复制(无意或有目的的重复)可能导致维护噩梦,糟糕的保理和逻辑矛盾。
      对系统的任何单个元素的修改不需要改变其他逻辑上不相关的元素。
      此外,逻辑上相关的元素全部可预测并一致地变化,并因此保持同步。

概述

适配器模式,1.它可以使用两个不同的类协同工作,或者使两个不同的接口实现协同工作2.它可以使用两个类的协同工作,并且可以实现多种协同工作方式,比如,我们的笔记本要必须要跟插座协同工作,那就需要电源适配器,如果电源适配器坏了,可以再买一个新。

结构

  • 目标角色(Target):— 定义Client使用的与特定领域相关的接口。
  • 客户角色(Client):与符合Target接口的对象协同。
  • 被适配角色(Adaptee):定义一个已经存在并已经使用的接口,这个接口需要适配。
  • 适配器角色(Adapte) :适配器模式的核心。它将对被适配Adaptee角色已有的接口转换为目标角色Target匹配的接口。对Adaptee的接口与Target接口进行适配.

    图例

    图片来自http://blueskykong.com/2017/01/29/design-adapter/

示例

现在以船长滑船为例,船长和船本是不相干的,我们现在需要适配器

船长的滑动技能

1
2
3
4
5
6
7
8
9
10
11
/**
* 扬帆的技能
* @author zmh
*
*/
public interface RowingBoat {
/**
* 扬
*/
void row();
}

船长

现在我们使用船长实现扬帆技能,这也有可能是你系统的原本设计,只提供船长,不提供船

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 船长,
* @author zmh
*
*/
public class Captain implements RowingBoat {
private RowingBoat rowingBoat;

public Captain(RowingBoat rowingBoat) {
this.rowingBoat =rowingBoat;
}

@Override
public void row() {
System.out.print("船长扬-");
rowingBoat.row();
}

}

现在有一只船,这可能是你后来使用或者设计,

1
2
3
4
5
6
7
8
9
10
/**
* 船
* @author zmh
*
*/
public class FishingBoat {
public void sail(){
System.out.println("帆");
}
}

适配器

现在应该想怎么使用船长和船协同工作呢,我们需要创建适配器来协同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 创建适配器,使船长能够扬帆
* @author zmh
*
*/
public class RowingBoatAdpater implements RowingBoat{
private FishingBoat boat;
public RowingBoatAdpater() {
boat=new FishingBoat();
}
@Override
public void row() {
boat.sail();
}
}

船长使用适配器

1
2
3
4
public static void main(String[] args) {
Captain c=new Captain(new RowingBoatAdpater());
c.row();
}

以下都是使用适配器模式的实例

  • Arrays.asList(arg0)

  • java.util.Collections.list()

  •  java.util.Collections.enumeration()

  •  javax.xml.bind.annotation.adapters.XMLAdapter