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

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

装饰模式

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

装饰模式的特点

  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层

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

时间: 2024-08-10 15:08:00

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

swift设计模式学习 - 装饰模式代码大全

装饰模式 在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 装饰模式的特点 装饰对象和真实对象有相同的接口.这样客户端对象就能以和真实对象相同的方式和装饰对象交互. 装饰对象包含一个真实对象的引用(reference) 装饰对象接受所有来自客户端的请求.它把这些请求转发给真实的对象. 装饰对象可以在转发这些请求以前或以后增加一些附加功能.这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能.在面向对象的设计中

设计模式学习-装饰模式

1.什么是装饰模式 装饰模式,在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.动态地给一个对象添加一些额外的职责.这样是能够把类中的装饰功能从类中搬移出去,这样可以简化原有的类.有效地把类的核心功能和装饰功能区分开了. 2.装饰模式的实现 在本例子中,举例最常见的人穿衣服的例子,首先我们定义这样一个Person的基类,如下: #include <cstdio> #include <string> #include

学习大话设计模式06_装饰模式

装饰模式(Decorator): 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 1 /** 2 * Component 是定义一个对象接口,可以给这些对象动态地添加职责 3 * @author Monica 4 * 5 */ 6 public abstract class Component { 7 public abstract void Operation(); 8 } 9 10 11 /** 12 * ConcreteComponent 是定义了一个具体

Java设计模式学习记录-装饰模式

前言 装饰模式也是一种结构型模式,主要是目的是相对于类与类之间的继承关系来说,使用装饰模式可以降低耦合度.JDK中有不少地方都使用到了装饰模式,例如Java的各种I/O流,javax.swing包中一些图形界面构件功能的增强等地方都运用了装饰模式. 装饰模式 定义 装饰模式的定义是:在不改变原类文件以及不使用继承的情况下,动态的扩展一个对象的功能.装饰模式是通过创建一个包装对象来实现的,也就是用装饰来包裹真实的对象. 举例 还是老规矩,举例说明,在给亲朋好友过生日时会买生日蛋糕,然后生日蛋糕又有

设计模式学习总结

本文是对各处设计模式示例的总结概括和简化,主要参考 http://blog.csdn.net/zhangerqing/article/details/8194653 直接看本文估计比较枯燥无聊,因为没图~~??,建议对设计模式有兴趣的先看看上面的博文,或者基础比较好可直接移到最底下看下我的各模式一句话概括总结,有什么意见建议欢迎提出~~~~~~~~~~ 总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式.结构型模式,共七种:适配器模式.装饰

JAVA设计模式之 装饰模式【Decorator Pattern】

一.概述 动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活.装饰模式是一种对象结构型模式.装饰模式是一种用于替代继承的技术,使用对象之间的关联关系取代类之间的继承关系.在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能. 二.适用场景 装饰原有对象.在不改变原有对象的情况下扩展增强新功能/新特征..当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式. 三.UML类图 四

设计模式学习难度系数排名

这是yqj2065感觉的每个设计模式学习难度系数. 刘伟(Sunny)先生有一个5分制的学习难度,列在模式名称之后. 有几个模式的评价差别很大,抽象工厂模式和享元模式给4分/5,而单例模式1分/5.冠军是一样的. 学习难度系数: ☆☆☆☆☆ ☆☆☆☆☆ 依赖注入模式 静态工厂模式 2 策略模式 1 ★☆☆☆☆ ☆☆☆☆☆ 工厂方法模式 2 模板方法模式 2 适配器模式    2 责任链模式   3 外观模式 1 ★★☆☆☆ ☆☆☆☆☆ 抽象工厂模式  4 桥接模式  3 迭代器    3 享元模

设计模式学习总结系列应用实例

1.单例模式 应用实例:1.一个党只能有一个主席.2.Windows是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行.3.一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件. 2.工厂模式 应用实例:1.你需要一辆汽车,你可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现 2.Hibernate换数据库只需换方言和驱动

设计模式学习笔记(目录篇)

设计模式学习笔记(目录篇) 为了方便查看,特此将设计模式学习笔记系列单独做一个目录. 1   设计模式学习笔记(一:命令模式) 2   设计模式学习笔记(二:观察者模式) 3   设计模式学习笔记(三:装饰模式) 4   设计模式学习笔记(四:策略模式) 5   设计模式学习笔记(五:适配器模式) 6   设计模式学习笔记(六:责任链模式) 7   设计模式学习笔记(七:外观模式) 8   设计模式学习笔记(八:迭代器模式) 9   设计模式学习笔记(九:中介者模式) 10  设计模式学习笔记(