当我谈Proxy与Adpater模式时,我谈些什么

本文对比分析了Proxy(代理)模式与Adapter(适配器)模式的设计思路与应用场景,介绍了这两种设计模式的角色、UML类图及代码示例。

当我谈Proxy与Adpater模式时,我谈些什么

前言

今天跟同事谈起了一道面试题:“Proxy模式跟Adpater模式的区别”,这两个设计模式都是很相似的模式,很多有点经验的程序员都可能会聊的头头是道,但是恐怕谈起一些设计上的细节可能就会卡壳,因此我写下了这篇文章,以此作为一个简短的回顾。

Adapter(适配器)模式

Adpater属于两种适应设计模式中的其中一种,另外一种是Iterator(迭代器)模式,下次有机会再仔细聊聊它。

设计模式的书很喜欢以‘电源适配器插头’作为适配器模式的范例范例,那么我们也从这个例子开始吧。

参与模式的角色

1. Target (适配接口)

暴露给调用方的接口,定义了被适配对象暴露的方法。(我们需要220V的电源)

2. Client (请求者)

实际需要使用接口的逻辑(某电器需要使用220V的电源)

3. Adaptee(被适配对象)

被适配者,包含了具体的实现,及可能不太合适调用方使用的方法。(110V的电源不合适现在所用的电器)

4. Adpater(适配器)

实际适配的实现,用继承的方式隐藏了被适配对象的实现,又以实现适配接口的方式暴露调用者适合的方法。

UML类图

image

范例代码

下面的代码实现了一个输出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

image

范例代码
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共存亡。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值