资讯专栏INFORMATION COLUMN

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

incredible / 3458人阅读

摘要:适配器模式属于两种适应设计模式中的其中一种,另外一种是迭代器模式,下次有机会再仔细聊聊它。设计模式的书很喜欢以电源适配器插头作为适配器模式的范例范例,那么我们也从这个例子开始吧。

当我谈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共存亡。

参考资料

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76512.html

相关文章

  • 我谈vim映射我谈什么

    摘要:注意不仅能映射单个键,还能映射一组键,比如脸滚键盘。通过命令可以显示当前键映射的情况。表示不允许映射的结果参与其他的映射规则的匹配。当然也有用武之地,比如当你需要映射的结果来触发另一个映射时,就用得上了。 映射功能是当下各大编辑器的标配,如果你想要熟悉所用的编辑器,必然不能缺少对它的映射机制的学习。对于vim亦是如此。 这里说到的映射功能,指的是编辑器会捕获用户的输入,并且按照事先的...

    GHOST_349178 评论0 收藏0
  • 我谈缓存的候,我谈什么

    摘要:对,当谈到缓存的时候,就是指那些设备,如浏览器,代理缓存服务器等。保持副本的新鲜服务器上的文本内容随时可能发生变化,如淘宝首页的一个文件中需要增加记录用户点击日志的功能,所以需要修改某个文件,以增加对应的功能。 TL;DR 前面大段的内容都是基本概念的介绍,建议没时间的同学直接拖到最下面看。 Web 缓存是可以自动保存常见文档副本的 HTTP 设备。对,当谈到缓存的时候,就是指那...

    Lsnsh 评论0 收藏0
  • 当谈论迭代器我谈什么

    摘要:示例代码如下此示例中可以看出,当迭代器终止时,通过抛出异常告知迭代器已耗尽。但如果迭代器所指向的数据结构在其存在时发生了插入或删除操作,则迭代器将可能失效。与的情形类似,对进行任何插入操作也将损坏迭代器。 花下猫语:之前说过,我对于编程语言跟其它学科的融合非常感兴趣,但我还说漏了一点,就是我对于 Python 跟其它编程语言的对比学习,也很感兴趣。所以,我一直希望能聚集一些有其它语言基...

    王军 评论0 收藏0
  • lodash源码分析之自减的两种形式

    摘要:作用与用法是的内部函数,之前在源码分析之缓存介绍过一种这样的数据结构这是一个二维数组,每项中的第一项作为缓存对象的,第二项为缓存的值。 这个世界需要一个特定的恶人,可以供人们指名道姓,千夫所指:全都怪你。——村上春树《当我谈跑步时我谈些什么》 本文为读 lodash 源码的第六篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新...

    Keven 评论0 收藏0

发表评论

0条评论

incredible

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<