今天跟同事谈起了一道面试题:“Proxy模式跟Adpater模式的区别”,这两个设计模式都是很类似的模式,不少有点经验的程序员均可能会聊的头头是道,可是恐怕谈起一些设计上的细节可能就会卡壳,所以我写下了这篇文章,以此做为一个简短的回顾。java
Adpater属于两种适应设计模式中的其中一种,另一种是Iterator(迭代器)模式,下次有机会再仔细聊聊它。程序员
设计模式的书很喜欢以‘电源适配器插头’做为适配器模式的范例范例,那么咱们也从这个例子开始吧。面试
暴露给调用方的接口,定义了被适配对象暴露的方法。(咱们须要220V的电源)设计模式
实际须要使用接口的逻辑(某电器须要使用220V的电源)this
被适配者,包含了具体的实现,及可能不太合适调用方使用的方法。(110V的电源不合适如今所用的电器)spa
实际适配的实现,用继承的方式隐藏了被适配对象的实现,又以实现适配接口的方式暴露调用者适合的方法。设计
下面的代码实现了一个输出110V的电源,经过220V电源适配器,实现了一个符合22V标准接口的输出,提供给客户端的示范。代理
# adpatee public class Power110v { private int volte = 110; public Power110v(){ System.out.print("the power is on at "+volte+"V"); } public String get100vPower(){ return volte; } } # target public interface Power220v { get220vPower(String input); } # adapter public PowerAdpater extends Power110v implemnts Power220v { public get220vPower(){ volte = volte * 2; System.out.println("the power is on at "+volte+"V") } } #client public class Main (){ public static void main(String[] args){ PowerAdapter pa = new PowerAdapter(); pa.get220vPower(); } }
Adapter模式适用于那些已有代码很稳定,但新调用方须要对部分代码进行调整,或者组合多个方法进行组合实现逻辑的状况下适用。能够尽可能适用已有的稳定代码,只做适当的修改即可以完成新的逻辑功能。code
使用proxy的角色,功能的调用方,下面的例子是Manager(经理)类。对象
定义了proxy角色与RealSubject的一致性接口,范例代码中,是Reportable(可汇报)接口,
Proxy会处理来自Client的请求,能够处理的功能本身处理,不能处理的功能让RealSubject处理,范例代码是TeamLeader类。
RealSubject将会在Proxy缺少功能时提供实现,跟Proxy同样实现一样的接口,范例代码中是TeamMember类。
public interface Reportable{ public void setReportMatrial(String jobContent); public String getReportMatrial(); public String getFeedback(); } public TeamMember implements Reportable{ String reportMatrial; public void setReportMatrial(String input){ this.reportMatrial = input; } public String getReportMatrial(){ return this.reportMatrial; } public String getFeedback(){ return "Here is the report content ["+this.reportMatrial+"]"; } } } public TeamLeader implements Reportable{ String reportMatrial; TeamMember member; public TeamLeader(String input){ this.reportMatrial = input; } public void setReportMatrial(String input){ if (member != null){ member.setReportMatrial(input) } this.reportMatrial = input; } public String getReportMatrial(){ return this.reportMatrial; } public String getFeedback(){ if ( member != null ){ return member.getFeedback(); } member = new TeamMember(); member.setReportMatrial(this.reportMatrial); } } public class Manager { public static void main(String[] args){ TeamLeader tl = new TeamLeader("monthly report"); tl.setReportMatrial("weekly report") String currentReportType = tl.getReportMatrial(); // the manager forgot what kind report should receive System.out.println("the current report type is " + currentReportType); // the manager ask the teamleader for the report detail. System.out.println("get some report from team leader"tl.getFeedback()); } }
二者头经过实现接口暴露实际逻辑给调用方,核心逻辑都在最内一层的类中。
Proxy实现subject类与proxy类,都是实现同样的接口,暴露同样的方法。Adpater模式则Adpater与Adpatee则不必定实现一样的方法。理论上Proxy模式的proxy类,也承担一部分的功能,当它没法实现调用功能时才会建立被代理的RealSubject类。Adpater类则原则上与Adpatee共存亡。