当我谈Proxy与Adpater模式时,我谈些什么
前言
今天跟同事谈起了一道面试题:“Proxy模式跟Adpater模式的区别”,这两个设计模式都是很相似的模式,很多有点经验的程序员都可能会聊的头头是道,但是恐怕谈起一些设计上的细节可能就会卡壳,因此我写下了这篇文章,以此作为一个简短的回顾。
Adapter(适配器)模式
Adpater属于两种适应设计模式中的其中一种,另外一种是Iterator(迭代器)模式,下次有机会再仔细聊聊它。
设计模式的书很喜欢以‘电源适配器插头’作为适配器模式的范例范例,那么我们也从这个例子开始吧。
参与模式的角色
1. Target (适配接口)
暴露给调用方的接口,定义了被适配对象暴露的方法。(我们需要220V的电源)
2. Client (请求者)
实际需要使用接口的逻辑(某电器需要使用220V的电源)
3. Adaptee(被适配对象)
被适配者,包含了具体的实现,及可能不太合适调用方使用的方法。(110V的电源不合适现在所用的电器)
4. Adpater(适配器)
实际适配的实现,用继承的方式隐藏了被适配对象的实现,又以实现适配接口的方式暴露调用者适合的方法。
UML类图
范例代码
下面的代码实现了一个输出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模式适用于那些已有代码很稳定,但新调用方需要对部分代码进行调整,或者组合多个方法进行组合实现逻辑的情况下适用。可以尽量适用已有的稳定代码,只作适当的修改便可以完成新的逻辑功能。
Proxy模式
参与模式的角色
1. Client
使用proxy的角色,功能的调用方,下面的例子是Manager(经理)类。
2. Subject
定义了proxy角色与RealSubject的一致性接口,范例代码中,是Reportable(可汇报)接口,
3. Proxy
Proxy会处理来自Client的请求,可以处理的功能自己处理,不能处理的功能让RealSubject处理,范例代码是TeamLeader类。
4. RealSubject
RealSubject将会在Proxy缺乏功能时提供实现,跟Proxy一样实现同样的接口,范例代码中是TeamMember类。
UML
范例代码
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与Adpater的总结
相同点
两者头通过实现接口暴露实际逻辑给调用方,核心逻辑都在最内一层的类中。
不同点
Proxy实现subject类与proxy类,都是实现一样的接口,暴露一样的方法。Adpater模式则Adpater与Adpatee则不一定实现同样的方法。理论上Proxy模式的proxy类,也承担一部分的功能,当它无法实现调用功能时才会创建被代理的RealSubject类。Adpater类则原则上与Adpatee共存亡。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。