✍ 创建型的设计模式,我们已经介绍完了,下面介绍一下结构型的设计模式。
结构型模式(Structural Pattern) 描述 如何将类或者对象结合在一起形成更大的结构 ,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。
它可以分为 类结构型模式
和 对象结构型模式
:
✍ 我们这次介绍的第一个结构型的设计模式是适配器模式,
在软件开发中采用类似于电源适配器的设计和编码技巧被称为 适配器模式 。 通常情况下, 客户端可以通过目标类的接口访问它所提供的服务
。有时,现有的类可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名与目标类中定义的方法名不一致等原因所导致的。在这种情况下,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用。如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成这样的转化。
在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是 适配器(Adapter)
,它所包装的对象就是 适配者(Adaptee)
,即被适配的类。适配器提供客户类需要的接口, 适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用 。
也就是说: 当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。
因此, 适配器可以使由于接口不兼容而不能交互的类可以一起工作 。
这就是适配器模式的模式动机。
如果要给适配器模式下一个定义,可以这样说:
适配器模式(Adapter Pattern) : 将一个接口转换成客户希望的另一个接口 ,
适配器模式 使接口不兼容的那些类可以一起工作
,其别名为 包装器(Wrapper)
。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
适配器模式包含如下角色:
✍ 下面演示一下:
类适配器模式
定义一个目标接口(目标(Target)接口)
public interface Target {
void request();
}
实现接口的类(这里仅仅是为了演示需要)
public class ConcreteTarget implements Target{
@Override
public void request() {
System.out.println("ConcreteTarget目标方法");
}
}
被适配者 (适配者(Adaptee)类)
public class Adaptee {
public void adapteeRequest(){
System.out.println("被适配者的方法");
}
}
关键 继承被适配者且继承目标接口(适配器(Adapter)类)
//继承被适配者
public class Adapter extends Adaptee implements Target{
@Override
public void request() {
super.adapteeRequest();
}
}
public class Test {
public static void main(String[] args) {
Target target = new ConcreteTarget();
target.request();
Target adapterTarget = new Adapter();
adapterTarget.request();
}
}
下面来看一下对象适配器模式
和类适配器模式相比 只有一处发生了变化
Adapter 类 之前还继承了Adaptee,现在没有继承
//继承被适配者
public class Adapter implements Target{
private Adaptee adaptee = new Adaptee();
@Override
public void request() {
adaptee.adapteeRequest();
}
}
✍ 说一下适配器模式的优缺点:
适配器模式通用的优点
适配器模式通用的缺点:
类适配器模式还具有如下优点:
类适配器模式的缺点如下:
对象适配器模式还具有如下优点:
对象适配器模式的缺点如下:
✍ 在以下情况下可以使用适配器模式:
✍ 模式应用很广泛
Sun 公司在1996 年公开了Java 语言的数据库连接工具JDBC ,JDBC 使得Java 语言程序能够与数据库连接,并使用SQL 语言来查询和操作数据。JDBC 给出一个客户端通用的抽象接口,每一个具体数据库引擎 (如SQL Server 、Oracle 、MySQL 等) 的JDBC 驱动软件都是一个介于JDBC 接口和数据库引擎接口之间的适配器软件。 抽象的JDBC 接口和各个数据库引擎API 之间都需要相应的适配器软件,这就是为各个不同数据库引擎准备的 驱动程序
在Spring AOP 框架中,对BeforeAdvice 、AfterAdvice 、ThrowsAdvice 三种通知类型借助适配器模式来实现。
还有在Java IO框架中字节流与字符流之间的转换。
✍ 模式扩展
默认适配器模式(Default Adapter Pattern) 或缺省适配器模式
当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求,它适用于一个接口不想使用其所有的方法的情况。因此也称为单接口适配器模式
双向适配器
在对象适配器的使用过程中,如果在适配器中同时包含对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法,那么该适配器就是一个双向适配器。