Java中装饰者模式与代理模式的使用

来源:互联网 发布:linux 退出编辑命令 编辑:程序博客网 时间:2024/05/16 23:33

了解

先来说一下什么时装饰者模式和代理模式

装饰者模式:顾名思义,即装饰,打扮化妆。一个比较有意思的例子是齐天大圣72般变化,变苍蝇变水蛇再变土地庙,这就是装饰者模式。

代理模式:过年了你要回家,需要坐车、坐飞机,需要买票,你可以去车站买票,这可以在手机app或者网站上购票,app和网站就是代理了车站的功能,而且还能提供额外的服务,比如抢票。。

引子

有这样一个需求,你需要设计一个咖啡计费系统,其中需要花费的有咖啡饮料和咖啡调料。

  • 分析问题
    • 需要抽象一些类来实现这个功能
    • 需要哪些类?
    • 各个类的功能是什么?
    • 用继承还是组合来实现?那种方法更好?

先看需要哪些类

计费接口类,其实现子类有咖啡和调料
咖啡类,其子类有各种具体的咖啡
调料类,其子类有各种具体的调料
当然需要将其子类一些共有的抽象到父类中去。

  • 看一张类图
    这里写图片描述

图中最上面是计费类,将咖啡类和调料类的功能进行抽象,抽象出了计费功能即cost函数


然后再想,他们有哪些属性呢?其中又有哪些是可以抽象的?

很明显,不管咖啡还是调料都有名字和价格吧。所以这两个属性需要抽象,抽象到哪呢?没错抽象到计费接口类 Beverage(虽然翻译是饮料)里面。

  • 然后类图成了这样,当然为了封装可以添加一些getter和setter方法。

这里写图片描述


咦,这很简单啊,然后呢?

先来看一下,这样设计能不能实现计费呢?
首先我们应该明确,我们是利用面向对象来实现这个咖啡系统,如果只是每一次new出一个对象,然后通过获取价格将每一个的价格加起来?。。。如果你是这种思想,建议可以去撞豆腐了。


的确没有完全实现,如果你是那种只喜欢和苦咖啡不用加调料的人,但是我们这个系统是面向广大人民群众的,以人民的利益为根本,不能让他们只喝苦咖啡。
那问题就来了?如果一个人想加调料呢?相加好几种调料呢?那又该怎么办呢?

  • 该怎么办呢,怎么办呢。。。

没错今天的主角上场了!
首先上场的是代理模式。

谁代理谁呢?咖啡代理调料?这样就是说可以加调料还可以额外的加咖啡?一般来说喝咖啡饮料用一种而调料可以有多种。调料代理咖啡?需要咖啡并且可以额外的加调料。对嘛,这才是正常思路呀!

再想一下,这样可以吗,如果调料代理咖啡,添加了一个调料,但是再添加一个调料呢?这时候调料是哪儿来的?所以说调料既需要代理咖啡也需要代理调料,那调料直接代理他们的公共父类,也就是计费接口(Beverage)不行吗?
没错就这个思路!这里利用了里氏代换原则。

  • 看一下类图,其中beverage可以设置setter和getter方法进行封装

这里写图片描述


这样,顺着思路

  1. 首先,声明一个Beverage类型的变量。
  2. 如果用户只想喝苦咖啡(不加调料),那只需要实例化一个具体coffee类赋值给它(Beverage类型的变量)。
  3. 如果用户选择加调料,那就实例化他选择的具体Seasoning赋值给Beverage类型的变量,再实例化具体Coffee类用具体Seasoning代理。如果再添加其他调料只需要将第一次咖啡和Seasoning的混合物(Beverage)代理给下一个调料。
  4. 顺着思路,如果计算总价的话,只需要计算这种调料的价格和加调料前混合物的价格。
原创粉丝点击