iOS设计模式-装饰器

概念

装饰器模式是一种结构型设计模式 ,它允许你在不修改原有类的情况下,通过"包裹"的方式动态地为对象添加新功能。与继承不同,它在运行时灵活组合,符合开闭原则(对扩展开放,对修改关闭)。

适用场景

适用于 在基本功能基础上,进行功能叠加场景。

角色

协议:行为抽象

功能组件:遵守协议,实现基础功能

装饰器基类:遵守协议,持有功能组件,调用转发

装饰器扩展:继承自装饰器基类,通过重载,进行行为扩展(功能叠加)

示例:咖啡配料系统

  • 定义协议
scss 复制代码
protocol Coffee {
    func description() -> String
    func cost() -> Double
}
  • 功能组件,遵守协议。

实现基本功能。

csharp 复制代码
class PlainCoffee: Coffee {
    func description() -> String { "简单咖啡" }
    func cost() -> Double { 10.0 }
}
  • 基础装饰器(持有引用功能组件,同时也遵守协议,转发调用)

作为基类

swift 复制代码
class CoffeeDecorator: Coffee {

    private let decoratedCoffee: Coffee

    init(_ coffee: Coffee) {
        self.decoratedCoffee = coffee
    }

    // 协议调用 转发
    func description() -> String {
        decoratedCoffee.description()
    }

    func cost() -> Double {
        decoratedCoffee.cost()
    }
}
  • 具体装饰器(扩展行为)

继承自 基础装饰器,重载;

职责单一: 每个装饰器只做一件事,(每种功能分开写在一个子类中

swift 复制代码
class MilkDecorator: CoffeeDecorator {
    override func description() -> String {
        super.description() + ",加牛奶"
    }
    override func cost() -> Double {
        super.cost() + 5.0
    }
}

class SugarDecorator: CoffeeDecorator {
    override func description() -> String {
        super.description() + ",加糖"
    }
    override func cost() -> Double {
        super.cost() + 3.0
    }
}

class VanillaDecorator: CoffeeDecorator {
    override func description() -> String {
        super.description() + ",香草风味"
    }
    override func cost() -> Double {
        super.cost() + 8.0
    }
}
  • 灵活组合

功能一层一层加

scss 复制代码
let plain = PlainCoffee()
print(plain.description()) // 简单咖啡
print(plain.cost())        // 10.0

// 组合 叠加
let milkCoffee = MilkDecorator(plain)
let sugerCoffee = SugarDecorator(milkCoffee)
let fancyCoffee = VanillaDecorator(sugerCoffee)

print(fancyCoffee.description())
// 简单咖啡,加牛奶,加糖,香草风味

print(fancyCoffee.cost())
// 26.0(10 + 5 + 3 + 8)
  • 可扩展性:

需要加其他功能?只需再写一个对应的装饰器,插入链中,其他代码零修改。

相关推荐
卸任7 小时前
Vibe coding工具使用心得
前端·ai编程
brien98 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance8 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M8 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写8 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李8 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易9 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马9 小时前
前沿视界
前端
kyriewen9 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易9 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员