一、设计模式的分类
(如果以前看过关于设计模式的分类的话,这部分可以忽略!)
经过很多大神的总结,目前Java中一共23种经典的设计模式!
按照目的,设计模式可以分为以下三种用途:
1.创建型模式:用来处理对象的创建过程
2.结构型模式:用来处理类或者对象的组合
3.行为型模式:用来对类或对象怎样交互和怎样分配职责进行描述
创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:
工厂方法模式(Factory Method Pattern)
抽象工厂模式(Abstract Factory Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)
单例模式(Singleton Pattern)
结构型模式用来处理类或者对象的组合,主要包含以下7种设计模式: 适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰者模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
行为型模式用来对类或对象怎样交互和怎样分配职责进行描述,主要包含以下11种设计模式:
责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern
解释器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
备忘录模式(Memento Pattern)
观察者模式(Observer Pattern)
状态模式(State Pattern)
策略模式(Strategy Pattern)
模板方法模式(Template Method Pattern)
访问者模式(Visitor Pattern)
本篇文章主要为讲解一下适配器模式(Adapter Pattern)!
二、适配器模式概述
英文:Convert the interface of a class into another interface clients expect。
中文:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
三、适配器模式类图(类适配器类图)
四、适配器模式使用场景
• 系统需要使用现有的类,而这些类的接口不符合系统的接口。
• 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
• (仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
• 两个类所做的事情相同或相似,但是具有不同接口的时候。
• 旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。
• 使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。
总结:
所以说适配器模式实际上是一个补偿型模式,一般不会在进行系统设计的时候用到。往往当你打算修改正在服役的系统的某个接口时,可以考虑是否用的上。
五、适配器模式实现方式(概念看着很枯燥)
类适配器:
当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
对象适配器:
对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。在工作中推荐使用“对象适配”。
缺省适配器模式:
缺省适配器模式是一种特殊的适配器模式,但这个适配器是由一个抽象类实现的,并且在抽象类中要实现目标接口中所规定的所有方法,但很多方法的实现都是“平庸”的实现,也就是说,这些方法都是空方法。而具体的子类都要继承此抽象类。
六、适配器模式实例讲解
类适配器实例:
如图(三、适配器模式类图)所示,适配器Adapter将被适配的对象的接口转换成客户端需要的Target所规定的接口。通过适配器,客户端可以将Adaptee类当作一个Target来与之协同工作。我们举个例子。我们首先定义目标Target接口,Target接口之规定了一个方法:request()。
代码如下所示:
public interface Target {
public void request();
}
源对象Adaptee代码如下:
public class Adaptee {
public void doSth() {
System.out.println("做我自己的事情");
}
}
对于适配器来说,要达到适配的作用,需要继承源对象Adaptee并且实现目标接口Target,
代码如下:
public class Adapter extends Adaptee implements Target{
@Override
public void request() {
super.doSth();
}
}
这样,客户端可以通过调用Target对象的request方法,享受到实际上Adaptee对象的doSth中提供的服务,接口不匹配的问题就搞定了。
代码如下:
public class Client {
public static void main(String[] args) {
Target t = new Adapter();
t.request();
}
}
运行一下,结果如下:
--------------------------------------------------------------------------
做我自己的事情
--------------------------------------------------------------------------
对象适配器实例:
在对象适配器模式中,适配器类Adapter和源Adaptee之间的关系不再是继承关系,而是一种委托的关系。
Adapter往往持有一个Adaptee的引用。我们将上面的代码例子中Adapter的代码进行修改,代码如下:
public class Adapter2 implements Target{
private Adaptee adaptee;
@Override
public void request() {
adaptee.doSth();
}
}
运行一下,结果如下:
--------------------------------------------------------------------------
做我自己的事情
--------------------------------------------------------------------------
七、优缺点总结
优点:
1、通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。
2、复用了现存的类,解决了现存类和复用环境要求不一致的问题。
3、将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
4、 一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。
缺点:
1、对于对象适配器来说,更换适配器的实现过程比较复杂。
总结了一下大家写好的东西,如果那里有什么问题,欢迎大家指出来!