设计模式-解析decorater和visitor以及它们的异同

软件构造的设计模式中又两个很重要又长得很像的一对模式:decorater和visitor,编写程序和复习的时候遇到了相关问题,在此记录,希望能帮到你。

decorater,即装饰器模式,简单的来说,为了防止拓展功能只用子类的继承关系会造成组合爆炸,用委派机制将对象增加的不同的侧面的特性交给另一个ADT来做,而基本功能委派给自己。

举例:对于已经实现的名为ParkingField的ADT,用于模拟一个无人管理停车场,我想在它基础上拓展一个功能:给停车场交付一个公司名字,以及车辆在进入时能打印输出:“HELLO”,这些功能是新的,按照继承思维,应该建立一个子类,在子类中添加丰富功能和属性。但在Decorater中,我们不这样做。简单来说,步骤如下:

1.新建一个抽象类,用于实现需要装饰的ADT接口,这个类被称作装饰类。比如新建ParkingFieldDecorator实现ParkingField抽象接口,并且内部含有一个ConcreParkingField(即所要装饰的ADT的实现类)的对象,这一点很重要。

2.在装饰类中,“重写的方法不重写”,而是调用内部的ConcreParkingField来实现。这样,旧的ADT的基本功能就被委派给了已经有的基本ADT。

3.新建CompanyParkingField类,用于继承装饰类,具体实现丰富的内容。比如在其中加入String CompanyName用于存储公司信息。然后重要的地方来了:构造方法内,传递基础ADT以及新加入的变量,例如public CompanyParkingField(ParkingField pf,String CompanyName)

4.在装饰类的子类中,继续丰富想要的方法。

这样,原有功能被基本ADT直接调用,丰富的功能被装饰器的实现类揽下!

为什么说Visitor模式和Decorater模式相像?原因在于,已经完成的基本功能都不变化,新增功能都委派给外部另一个ADT间接完成。

那么现在来看Visitor模式:

这个模式相当于你搭起来一座房屋,但是预料到可能以后某一面墙会装窗户,所以那面墙的窗户那部分,你用了木板没用转头。等到要装窗户的时候,木板一拆,窗户一装就好了。不用拆墙,即不损坏原来已实现的ADT,而且知道哪里要插入修改。

简单来说,步骤如下:

1.新建访问器接口Visitor,里面仅有一个方法,名字叫visit,接受的参数是被修饰的ADT(给房子适配一个窗户框架)(在这里,最能体现访问者的含义,他把整个被修饰的ADT全盘接受,然后借用被访问者的方法,在外面丰富被访问者)

2.新建访问器实现类ConcreteVisitor,实现第一步里面的具体方法(给窗户框架上玻璃、花纹)

3.在被修饰接口中加入accept方法,接收参数是访问器类型(Visior)(给房子预留窗户)

4.在被装饰类的实现类中,填充accept方法,并且在里面直接调用Visitor,完成丰富的方法(装窗户)

这样,想要被添加的方法绕了一圈,实际上没有在自己本身上作修改,而是给外部的一个ADT(Visitor)完成了这样的事情。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

idremo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值