设计模式学习 - 装饰者模式

装饰者模式:

    在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

该模式的组成部分:

  •   一个共同的抽象类(父类,也可以是接口)
  •   具体的被装饰者类(可以是多个)
  •   一个抽象的装饰者类 和 多个具体的装饰者类

注:

  1.   不需要 额外的被装饰者的抽象类 是因为 共同的抽象类 即是 被装饰者 的父类。也就是说其实在装饰者模式中,装饰者和被装饰者都共同源于一个父类。
  2.   需要一个 额外的装饰者的抽象类 是因为 装饰类 可以额外的定义一些方法 来完成对被装饰类 的装饰。

UML 类图如下:

代码的具体实现:

1、公共抽象类:

// 定义一个饮料类充当 装饰者与被装饰者的共同 抽象父类
class Beverage: NSObject {
    var beverageDescription: String = ""

    // 返回 描述信息
    func getBeverageDescription() -> String {
        return self.beverageDescription
    }

    // 需要被 装饰 的方法
    func cost() -> Float {
        return 0;
    }
}

2、被装饰者部分:

// 一个具体的被装饰者类:HouseBlend
class HouseBlend: Beverage {

    override init() {
        super.init()
        self.beverageDescription = "It‘s HouseBlend"
    }

    // 需要被 装饰 的方法
    override func cost() -> Float {
        return 0.9
    }
}

3、装饰者部分:

// 装饰者的抽象类(但是在这里,我定义了一个 有实现了接口的类 充当 装饰者的抽象类)
class CondimentDecortor: Beverage {
    // 装饰者类 需要一个 被装饰者 的对象
    var concreteDrink: Beverage!

    // 因为这个方法 在装饰者类中是通用的, 所以我在父类中实现了,以节约代码量
    override func getBeverageDescription() -> String {
        return "\(self.concreteDrink.getBeverageDescription()) With \(self.beverageDescription)"
    }
}

// 一个具体的装饰者类: Milk
class Milk: CondimentDecortor {

    // 在初始化的时候 将自己的被装饰类 具体化(赋以对象)
    init(cDrink: Beverage) {
        super.init()
        self.concreteDrink = cDrink
        self.beverageDescription = "Milk"
    }

    // 装饰(扩充) Cost 方法
    override func cost() -> Float {
        return concreteDrink!.cost() + 0.1;
    }
}

4、测试代码:

println("*********  WelCome To StarBucks Coffee  *********")

// 一杯不需要任何调料的 Coffee
var drink: Beverage = HouseBlend()
println("\(drink.getBeverageDescription()) \nAnd $ is \(drink.cost())")

// 一杯需要加 牛奶 和 大豆 的 Coffee
var drink1: Beverage = HouseBlend()
drink1 = Milk(cDrink: drink1)
drink1 = Soy(cDrink: drink1)
println("\(drink1.getBeverageDescription()) \nAnd $ is \(drink1.cost())")

5、 测试结果:

时间: 2024-10-14 13:04:12

设计模式学习 - 装饰者模式的相关文章

设计模式之装饰者模式(三)

欢迎大家的持续关注.上一次,我们结合第一篇推导出来的类图,到第二篇根据类图进行实际代码的编写,对装饰者模式有了一个整体的概念以及实战.不知道对你帮助如何呢?小编已经有门道了,看完接下来的一部分,你会恍然大悟,原来实际编码中你一直在用装饰者模式. 真实世界的装饰者:Java I/O 看到标题,是不是就很想往下看,到底是I/O中的什么呢,让你早已经拥有了装饰者模式的实践?就如书上给的描述,你第一次(还有第二次和第三次)看到这些API发出"哇"的惊叹时,放心,你不是唯一收到惊吓的人.下面,我

掌握设计模式之装饰者模式

![](http://ww4.sinaimg.cn/large/006tNc79ly1g4ztauvhzej30p00dw45p.jpg) ## 前言 当应用开发中,我们要为一个对象在原有功能上进行扩展增强时,往往采用继承的方式,而继承过多时就会使得功能类更加复杂,不利于维护,而设计模式中装饰者模式可以帮助我们更好对应这种场景,装饰者模式可以做到让对象能够动态地进行功能扩展,而不影响其他对象. 那究竟它是如何实现的呢,又如何实际应用呢,就让我们一起来学习下这个模式吧. ## 模式定义 装饰者模式

设计模式 2 —— 装饰者模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式

设计模式学习之-状态模式

一.状态模式状态模式,当一个对象的内在状态发生改变时允许改变其行为行为,这个对象像是改变了其子类.状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同的状态的一系列类当中,可以把复杂的判断逻辑简化.当然,如果这个状态判断比较简单,那就没有必要用“状态模式”了.这段话有点难以理解,简而言之就是,在一类中根据当前状态去实例化下一状态子类.下面是状态模式结构图. State类,是一个抽象状态类,定义一个接口以封装与Context的特定状态相关的行为.

设计模式学习02—工厂模式

1.动机与定义 我们在程序中使用一个对象时,需要new一下,如果需要设置其他值就再初始化一下.比如我要使用一个按钮,手动new一个矩形按钮,然后初始化一些值,如显示文字,背景色等. // 矩形按钮 IButton btn = new RecButton(); // 初始化其他值 btn.setText("提交"); btn.setBackgroundColor("#00aaff"); // 其他初始化省略 // 圆形按钮 IButton btn2 = new Rou

Design Pattern 设计模式 Decorator 装饰者模式

1 设计一个基类 2 继承这个基类,并包含这个基类的一个对象 3 创建继承类的时候,初始化这个基类,因为是基类指针,所以可以是所有基类的衍生类对象,那么就可以叠加任意多个衍生类对象了. 关键是在衍生类中包含一个基类对象,然后有了继承和包含两重关系,可以使得一个类一个类对象叠加,达到装饰目的. 等于是创建了一个对象指针链表,一个一个对象发挥其相应的作用. 下面程序装饰一个桌子,同时包含释放内存的处理. 关键要知道基类的析构函数必须使用虚函数,为什么? 1 如果基类不是析构函数,那么如果衍生类中包含

设计模式学习之外观模式(Facade,结构型模式)(8)

1.什么是外观模式为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 2.为什么要使用外观模式在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,从而导致客户程序随着子系统的变化而变化,那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦? 现在来考虑这样一个抵押系统,当有一个客户来时,有如下几件事情需要确认:到银行子系统查询他是否有足够多的存款,到信用子系统查询他是否有良好的信

设计模式学习05—原型模式

一.动机与定义 之前学习原型模式一直以为原型模式目的是为了方便的创建相同或相似对象,用复制对象的方式替换new的方式,还研究了深克隆和浅克隆.最近仔细看了GOF的设计模式,发现原型模式的本意并不仅仅是复制对象这么简单. 复制对象确实是一方面,当我们需要大量相似,甚至相同对象的时候,除了一个个的new之外,还可以根据一个原型,直接复制出更多的对象.但是如果把原型模式认为只是复制对象这么简单就错了. 创建型模式主要讲如何创建对象,通常包含何时创建,谁来创建,怎么创建等.GOF书里面写的意图是,用原型

设计模式学习之代理模式(Proxy)

一.代理模式的初衷 不想让客户端直接访问具体实现接口,客户端不应该直接访问具体实现,一般会涉及到以下四个对象 业务接口:定义客户端访问的接口,是实现类和代理类都需要实现的 实现类:实现了业务接口,真正的实现是在这里 代理类:同样实现了业务接口,一般都会关联一个实现类的实例,由它来调用实现类 客户端:顾名思义,使用者,与代理类打交道,甚至都不知道具体实现类的存在. 二.代理模式设计图 三.代理模式的简单实现代码 BizInterface.java package com.lipan.designp