选择23种设计模式之一:原型模式
概述
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
解决的问题
使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
模式中的角色
目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
需要适配的类(Adaptee):需要适配的类或适配者类。
类图如下所示:
java剖析如下:
需要适配的类如下:
package adapter;
/**
*
* 需要适配的类
* @author fchao
* @date 2016年12月4日
*/
public class Adaptee {
public void funA() {
System.out.println("aaaaaaaa");
}
public String FunB(String fun) {
System.out.println("bbbbbbbb");
return fun;
}
}
说明:此类是需要被适配的类,此类的方法可能是别的同事所书写,但是我不能拿着别的类在上面书写,不然跟改的地方可就打得多了。别人使用的场景可能如下:
package adapter;
public class Controller {
public String menthod() {
Adaptee adaptee = new Adaptee();
adaptee.funA();
return adaptee.FunB("view");
}
public static void main(String[] args) {
Controller c = new Controller();
String menthod = c.menthod();
System.out.println(menthod);
}
}
此时对Apadtee进行适配,适配的原因是什么?
由于此接口是之前项目的或者是别的同事进行维护此类的,如果维护此类的人过多,则会导致此类变得越来越臃肿,并难以维护。若客户端需要新的接口方法,不在此类维护,就需要对此类进行适配,保障此被适配类的完整性,后期维护后还能在进行使用。
客户需要的服务:
package adapter;
public interface Target {
public void eat();
}
适配者类:
package adapter;
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void eat() {
// 获取被适配者的服务
String funB = adaptee.FunB("aaa");
System.out.println("eat --->" + funB);
}
}
此时在新的使用场景如下;
package adapter;
public class Controller {
public String menthod() {
Adaptee adaptee = new Adaptee();
//adaptee.funA();
Target adapter = new Adapter(adaptee);
adapter.eat();
return "";
}
public static void main(String[] args) {
Controller c = new Controller();
String menthod = c.menthod();
System.out.println(menthod);
}
}
给人的感觉就是:适配者模式能在旧的服务依旧能使用的情况下,还能提供新的服务,给人的感觉这是给方法增加,但是增加方法可不是这种选择,可以使用代理模式对方法进行增强。
模式总结
优点通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。
复用了现存的类,解决了现存类和复用环境要求不一致的问题。
将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。
缺点
对于对象适配器来说,更换适配器的实现过程比较复杂。
适用场景
系统需要使用现有的类,而这些类的接口不符合系统的接口。
想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
两个类所做的事情相同或相似,但是具有不同接口的时候。
旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。
使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。