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

原创 2017年02月09日 17:46:04

移动端访问不佳,请访问我的个人博客

设计模式学习的demo地址,欢迎大家学习交流

装饰模式

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

装饰模式的特点

  1. 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
  2. 装饰对象包含一个真实对象的引用(reference)
  3. 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
  4. 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

装饰模式的基本实现

上图是最基本的装饰模式的结构图,下面将用swift代码来实现一个基本装饰模式:

1).先写一个Component接口

protocol Component {
    func operation()
}

2).写一个具体的Component对象

class ConcreteComponent: Component {
    func operation() {
        // 具体操作的实现
    }
}

3).写一个装饰抽象类

class Decorator: Component {
    var component: Component?
    func operation() {
        component?.operation()
    }
}

4).写具体的装饰对象

// 装饰对象A
class ConcreteDecoratorA: Decorator {
    private var addedState: String?
    override func operation() {
        super.operation()
        addedState = "ConcreteDecoratorA独有的功能,用来区分ConcreteDecoratorB"
        // 具体装饰对象A的操作
    }
}
// 装饰对象B
class ConcreteDecoratorB: Decorator {
    override func operation() {
        super.operation()
        addedBehavior()
        // 具体装饰对象B的操作
    }
    // ConcreteDecoratorB独有的方法,用来区分ConcreteDecoratorA
    private func addedBehavior() {

    }
}

通过以上代码我们就能简单了解装饰模式的基本实现于过程,它的主要的目的就是:在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能,就像以上示例代码一样,通过ConcreteDecoratorAConcreteDecoratorB去扩展ConcreteComponent这个对象的功能,这样不用去改变ConcreteComponent这个类的源文件,也可以达到扩展的效果。

用装饰模式解决实际问题(买车选配的问题)

下面通过一个实际的例子来看看,比如我们在买车的时候一般会选配很多配件,下面我们通过策略模式来实现这一过程,下上个结构图:

下面贴上代码:

// Component
protocol Car {
    // 多少钱
    func howMuch()-> Int
    // 展示装配的配件
    func showParts()
}

// ConcreteComponents
class Suv: Car {
    init(owner: String) {
        print("\(owner)买了一辆Suv,10W")
    }

    func howMuch() -> Int {
        return 10
    }

    func showParts() {}
}

class Mpv: Car {
    init(owner: String) {
        print("\(owner)买了一辆Mpv,15W")
    }
    func howMuch() -> Int {
        return 15
    }
    func showParts() {}
}

// Decorator
class CarParts: Car {
    var car: Car?
    func howMuch() -> Int {
        return car?.howMuch() ?? 0
    }
    func showParts() {
        car?.showParts()
    }
    func decorator(_ car: Car) -> Car {
        self.car = car
        return self
    }
}

// ConcreteDecorators 
class Sofa: CarParts {
    override func howMuch() -> Int {
        return super.howMuch() + 1
    }
    override func showParts() {
        super.showParts()
        print("选配了真皮沙发,1W")
    }
}

class Safety: CarParts {
    override func howMuch() -> Int {
        return super.howMuch() + 3
    }

    override func showParts() {
        super.showParts()
        print("选配了全套安全系统,3W")
    }
}

class Engine: CarParts {
    override func howMuch() -> Int {
        return super.howMuch() + 5
    }
    override func showParts() {
        super.showParts()
        print("选配了V8发动机,5W")
    }
}

下面我们使用一下以上代码看看:

//wcl买一辆suv
var suv: Car = Suv(owner: "wcl")
//装配沙发
suv = Sofa().decorator(suv)
//装配发动机
suv = Engine().decorator(suv)
//装配安全系统
suv = Safety().decorator(suv)
suv.showParts()
print("一共花了\(suv.howMuch())W")
print("\n")
//wcl买一辆mpv
var mpv: Car = Mpv(owner: "wcl")
//装配发动机
mpv = Engine().decorator(mpv)
//装配安全系统
mpv = Safety().decorator(mpv)
mpv.showParts()
print("一共花了\(mpv.howMuch())W")

以下是代码打印的结果:

wcl买了一辆Suv,10W
选配了真皮沙发,1W
选配了V8发动机,5W
选配了全套安全系统,3W
一共花了19W

wcl买了一辆Mpv,15W
选配了V8发动机,5W
选配了全套安全系统,3W
一共花了23W

这样就用装饰模式简单了实现了一下这个过程,在不改变SuvMpv这两个类的源文件的情况下对它进行操作。

总结

我们先看看装饰模式的优点:

  1. 可以将类中装饰功能从类中搬出移除,这样可以简化原有的类
  2. 有效的将核心职责和装饰功能区分开来,而且可以除去相关类中重复的装饰逻辑

装饰模式的缺点:

  1. 装饰模式虽然扩展性较高,类的数量略多,如何取舍可扩展性和简洁性是个问题,有所选择就要有所牺牲
  2. 很难搞清楚一个类究竟被装饰了多少层,可能是1层,也可能是100层

以上是我对于装饰模式的理解,如果有不对的地方欢迎大家交流,最后谢谢大家的阅读~~

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wang631106979/article/details/54949898

swift设计模式学习 - 外观模式

移动端访问不佳,请访问我的个人博客 设计模式学习的demo地址,欢迎大家学习交流 外观模式外观模式(Facade),为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统...
  • wang631106979
  • wang631106979
  • 2017-03-09 12:05:25
  • 1701

Swift设计模式之抽象工厂模式

转自 Swift设计模式 原文 Design-Patterns-In-Swift // 抽象工厂模式 // 百度百科:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类 // 设计模...
  • aotian16
  • aotian16
  • 2016-05-12 11:40:53
  • 794

Swift设计模式之命令模式

转自 Swift设计模式 原文 Design-Patterns-In-Swift // 命令模式 // 百度百科:一组行为抽象为对象,实现二者之间的松耦合 // 设计模式分类:行为型模式/** * ...
  • aotian16
  • aotian16
  • 2016-05-12 11:36:48
  • 349

iOS+中的<em>设计模式</em>+(<em>Swift</em>版本)

精通Python<em>设计模式</em> 高清晰PDF.pdf 立即下载 上传者: donggua209 时间: 2017-09-23 综合评分: 0 积分/C币:12 <em>Swift</em> 实现单例 代理 通知 的<em>设计模式</em> OC ...
  • 2018年04月14日 00:00

Swift设计模式之状态模式

转自 Swift设计模式 原文 Design-Patterns-In-Swift // 状态模式 // 百度百科:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类 // 设计模式...
  • aotian16
  • aotian16
  • 2016-05-12 11:32:24
  • 362

设计模式——装饰模式(Decorator)

要想正确理解设计模式,首先必须明确它是为了解决什么问题而提出来的。 设计模式学习笔记 ——Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1、概念 ...
  • u012909091
  • u012909091
  • 2014-08-18 20:23:19
  • 19931

学习、探究Java设计模式——装饰者模式

定义装饰者模式:在不改变原类文件以及不使用继承的情况下,动态地将责任附加到对象上,从而实现动态拓展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。设计原则要使用装饰者模式,需要满...
  • a553181867
  • a553181867
  • 2016-08-03 22:52:44
  • 5443

Swift设计模式整理

定位 使用方法 分类 源码 参考文章 定位swift设计模式的入门读物。各个模式详细介绍请自行搜索网文,博客,也可以查看下面的参考文章。使用方法 读懂代码 在网上查找各种对应设计模式的含义 再次回来读...
  • aotian16
  • aotian16
  • 2016-05-13 12:02:35
  • 418

swift设计模式学习一

好久没写博客了,最新有些时间,刚好在研究设计模式,准备记录下学习历程吧。昨天看的工厂模式,但理解的不够,后面再写吧,免得误导各位。 今天看的模版方法,如果有写的不对的地方 希望大家指出。下面写一段通用...
  • u013643459
  • u013643459
  • 2016-04-25 20:16:32
  • 82

设计模式-----装饰模式.

装饰者模式,我刚看到这个模式的时候,我的脑海里第一反应是已经很经典的广告语:人靠衣装,美靠亮装.思想上移   一点就是装饰模式,就是对某个东西进行装饰,对某个功能进行附加,从而得到新的功能.  ...
  • tang_huan_11
  • tang_huan_11
  • 2012-11-25 15:32:28
  • 1448
收藏助手
不良信息举报
您举报文章:swift设计模式学习 - 装饰模式
举报原因:
原因补充:

(最多只允许输入30个字)