{"id":13396655,"url":"https://github.com/ochococo/Design-Patterns-In-Swift","last_synced_at":"2025-03-13T23:31:42.660Z","repository":{"id":18592395,"uuid":"21796955","full_name":"ochococo/Design-Patterns-In-Swift","owner":"ochococo","description":"📖 Design Patterns implemented in Swift 5.0","archived":false,"fork":false,"pushed_at":"2024-08-03T07:30:28.000Z","size":1399,"stargazers_count":15124,"open_issues_count":5,"forks_count":1748,"subscribers_count":652,"default_branch":"master","last_synced_at":"2024-10-15T21:42:18.671Z","etag":null,"topics":["computer-science","design-patterns","gang-of-four","good-practices","playground","swift","swift-5"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ochococo.png","metadata":{"files":{"readme":"README-CN.md","changelog":null,"contributing":"CONTRIBUTING-CN.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"ochococo"}},"created_at":"2014-07-13T18:15:14.000Z","updated_at":"2024-10-15T17:01:46.000Z","dependencies_parsed_at":"2023-02-18T05:16:02.965Z","dependency_job_id":"681e85a2-a532-438f-b269-7ae8373c09de","html_url":"https://github.com/ochococo/Design-Patterns-In-Swift","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ochococo%2FDesign-Patterns-In-Swift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ochococo%2FDesign-Patterns-In-Swift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ochococo%2FDesign-Patterns-In-Swift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ochococo%2FDesign-Patterns-In-Swift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ochococo","download_url":"https://codeload.github.com/ochococo/Design-Patterns-In-Swift/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221421596,"owners_count":16817839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computer-science","design-patterns","gang-of-four","good-practices","playground","swift","swift-5"],"created_at":"2024-07-30T18:00:58.970Z","updated_at":"2024-10-25T11:31:04.711Z","avatar_url":"https://github.com/ochococo.png","language":"Swift","readme":"\n\n设计模式（Swift 5.0 实现）\n======================\n\n([Design-Patterns-CN.playground.zip](https://raw.githubusercontent.com/ochococo/Design-Patterns-In-Swift/master/Design-Patterns-CN.playground.zip)).\n\n👷 源项目由 [@nsmeme](http://twitter.com/nsmeme) (Oktawian Chojnacki) 维护。\n\n🇨🇳 中文版由 [@binglogo](https://twitter.com/binglogo) 整理翻译。\n\n🚀 如何由源代码，并生成 README 与 Playground 产物，请查看：\n- [CONTRIBUTING.md](https://github.com/ochococo/Design-Patterns-In-Swift/blob/master/CONTRIBUTING.md)\n- [CONTRIBUTING-CN.md](https://github.com/ochococo/Design-Patterns-In-Swift/blob/master/CONTRIBUTING-CN.md)\n\n\n\n```swift\nprint(\"您好！\")\n```\n\n\n## 目录\n\n| [行为型模式](#行为型模式)                                    | [创建型模式](#创建型模式)                                 | [结构型模式](#结构型模式structural)                          |\n| ------------------------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------ |\n| [🐝 责任链 Chain Of Responsibility](#-责任链chain-of-responsibility) | [🌰 抽象工厂 Abstract Factory](#-抽象工厂abstract-factory) | [🔌 适配器 Adapter](#-适配器adapter)                          |\n| [👫 命令 Command](#-命令command)                              | [👷 生成器 Builder](#-生成器builder)                       | [🌉 桥接 Bridge](#-桥接bridge)                                |\n| [🎶 解释器 Interpreter](#-解释器interpreter)                  | [🏭 工厂方法 Factory Method](#-工厂方法factory-method)     | [🌿 组合 Composite](#-组合composite)                          |\n| [🍫 迭代器 Iterator](#-迭代器iterator)                        | [🔂 单态 Monostate](#-单态monostate)                       | [🍧 修饰 Decorator](#-修饰decorator)                          |\n| [💐 中介者 Mediator](#-中介者mediator)                        | [🃏 原型 Prototype](#-原型prototype)                       | [🎁 外观 Façade](#-外观facade)                                |\n| [💾 备忘录 Memento](#-备忘录memento)                          | [💍 单例 Singleton](#-单例singleton)                       | [🍃 享元 Flyweight](#-享元flyweight)                          |\n| [👓 观察者 Observer](#-观察者observer)                        |                                                           | [☔ 保护代理 Protection Proxy](#-保护代理模式protection-proxy) |\n| [🐉 状态 State](#-状态state)                                  |                                                           | [🍬 虚拟代理 Virtual Proxy](#-虚拟代理virtual-proxy)          |\n| [💡 策略 Strategy](#-策略strategy)                            |                                                           |                                                              |\n| [📝 模板方法 Templdate Method](#-template-method)             |                                                           |                                                              |\n| [🏃 访问者 Visitor](#-访问者visitor)                          |                                                           |                                                              |\n\n 行为型模式\n ========\n \n \u003e在软件工程中， 行为型模式为设计模式的一种类型，用来识别对象之间的常用交流模式并加以实现。如此，可在进行这些交流活动时增强弹性。\n \u003e\n \u003e**来源：** [维基百科](https://zh.wikipedia.org/wiki/%E8%A1%8C%E7%82%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F)\n\n\n\n\n🐝 责任链（Chain Of Responsibility）\n------------------------------\n\n责任链模式在面向对象程式设计里是一种软件设计模式，它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象，它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。\n\n### 示例：\n\n```swift\n\nprotocol Withdrawing {\n    func withdraw(amount: Int) -\u003e Bool\n}\n\nfinal class MoneyPile: Withdrawing {\n\n    let value: Int\n    var quantity: Int\n    var next: Withdrawing?\n\n    init(value: Int, quantity: Int, next: Withdrawing?) {\n        self.value = value\n        self.quantity = quantity\n        self.next = next\n    }\n\n    func withdraw(amount: Int) -\u003e Bool {\n\n        var amount = amount\n\n        func canTakeSomeBill(want: Int) -\u003e Bool {\n            return (want / self.value) \u003e 0\n        }\n\n        var quantity = self.quantity\n\n        while canTakeSomeBill(want: amount) {\n\n            if quantity == 0 {\n                break\n            }\n\n            amount -= self.value\n            quantity -= 1\n        }\n\n        guard amount \u003e 0 else {\n            return true\n        }\n\n        if let next {\n            return next.withdraw(amount: amount)\n        }\n\n        return false\n    }\n}\n\nfinal class ATM: Withdrawing {\n\n    private var hundred: Withdrawing\n    private var fifty: Withdrawing\n    private var twenty: Withdrawing\n    private var ten: Withdrawing\n\n    private var startPile: Withdrawing {\n        return self.hundred\n    }\n\n    init(hundred: Withdrawing,\n           fifty: Withdrawing,\n          twenty: Withdrawing,\n             ten: Withdrawing) {\n\n        self.hundred = hundred\n        self.fifty = fifty\n        self.twenty = twenty\n        self.ten = ten\n    }\n\n    func withdraw(amount: Int) -\u003e Bool {\n        return startPile.withdraw(amount: amount)\n    }\n}\n```\n\n ### 用法\n \n```swift\n// 创建一系列的钱堆，并将其链接起来：10\u003c20\u003c50\u003c100\nlet ten = MoneyPile(value: 10, quantity: 6, next: nil)\nlet twenty = MoneyPile(value: 20, quantity: 2, next: ten)\nlet fifty = MoneyPile(value: 50, quantity: 2, next: twenty)\nlet hundred = MoneyPile(value: 100, quantity: 1, next: fifty)\n\n// 创建 ATM 实例\nvar atm = ATM(hundred: hundred, fifty: fifty, twenty: twenty, ten: ten)\natm.withdraw(amount: 310) // Cannot because ATM has only 300\natm.withdraw(amount: 100) // Can withdraw - 1x100\n```\n\n👫 命令（Command）\n ------------\n 命令模式是一种设计模式，它尝试以对象来代表实际行动。命令对象可以把行动(action) 及其参数封装起来，于是这些行动可以被：\n * 重复多次\n * 取消（如果该对象有实现的话）\n * 取消后又再重做\n ### 示例：\n\n```swift\nprotocol DoorCommand {\n    func execute() -\u003e String\n}\n\nfinal class OpenCommand: DoorCommand {\n    let doors:String\n\n    required init(doors: String) {\n        self.doors = doors\n    }\n    \n    func execute() -\u003e String {\n        return \"Opened \\(doors)\"\n    }\n}\n\nfinal class CloseCommand: DoorCommand {\n    let doors:String\n\n    required init(doors: String) {\n        self.doors = doors\n    }\n    \n    func execute() -\u003e String {\n        return \"Closed \\(doors)\"\n    }\n}\n\nfinal class HAL9000DoorsOperations {\n    let openCommand: DoorCommand\n    let closeCommand: DoorCommand\n    \n    init(doors: String) {\n        self.openCommand = OpenCommand(doors:doors)\n        self.closeCommand = CloseCommand(doors:doors)\n    }\n    \n    func close() -\u003e String {\n        return closeCommand.execute()\n    }\n    \n    func open() -\u003e String {\n        return openCommand.execute()\n    }\n}\n```\n\n### 用法\n\n```swift\nlet podBayDoors = \"Pod Bay Doors\"\nlet doorModule = HAL9000DoorsOperations(doors:podBayDoors)\n\ndoorModule.open()\ndoorModule.close()\n```\n\n🎶 解释器（Interpreter）\n ------------------\n\n 给定一种语言，定义他的文法的一种表示，并定义一个解释器，该解释器使用该表示来解释语言中句子。\n\n ### 示例：\n\n```swift\n\nprotocol IntegerExpression {\n    func evaluate(_ context: IntegerContext) -\u003e Int\n    func replace(character: Character, integerExpression: IntegerExpression) -\u003e IntegerExpression\n    func copied() -\u003e IntegerExpression\n}\n\nfinal class IntegerContext {\n    private var data: [Character:Int] = [:]\n\n    func lookup(name: Character) -\u003e Int {\n        return self.data[name]!\n    }\n\n    func assign(expression: IntegerVariableExpression, value: Int) {\n        self.data[expression.name] = value\n    }\n}\n\nfinal class IntegerVariableExpression: IntegerExpression {\n    let name: Character\n\n    init(name: Character) {\n        self.name = name\n    }\n\n    func evaluate(_ context: IntegerContext) -\u003e Int {\n        return context.lookup(name: self.name)\n    }\n\n    func replace(character name: Character, integerExpression: IntegerExpression) -\u003e IntegerExpression {\n        if name == self.name {\n            return integerExpression.copied()\n        } else {\n            return IntegerVariableExpression(name: self.name)\n        }\n    }\n\n    func copied() -\u003e IntegerExpression {\n        return IntegerVariableExpression(name: self.name)\n    }\n}\n\nfinal class AddExpression: IntegerExpression {\n    private var operand1: IntegerExpression\n    private var operand2: IntegerExpression\n\n    init(op1: IntegerExpression, op2: IntegerExpression) {\n        self.operand1 = op1\n        self.operand2 = op2\n    }\n\n    func evaluate(_ context: IntegerContext) -\u003e Int {\n        return self.operand1.evaluate(context) + self.operand2.evaluate(context)\n    }\n\n    func replace(character: Character, integerExpression: IntegerExpression) -\u003e IntegerExpression {\n        return AddExpression(op1: operand1.replace(character: character, integerExpression: integerExpression),\n                             op2: operand2.replace(character: character, integerExpression: integerExpression))\n    }\n\n    func copied() -\u003e IntegerExpression {\n        return AddExpression(op1: self.operand1, op2: self.operand2)\n    }\n}\n```\n\n### 用法\n\n```swift\nvar context = IntegerContext()\n\nvar a = IntegerVariableExpression(name: \"A\")\nvar b = IntegerVariableExpression(name: \"B\")\nvar c = IntegerVariableExpression(name: \"C\")\n\nvar expression = AddExpression(op1: a, op2: AddExpression(op1: b, op2: c)) // a + (b + c)\n\ncontext.assign(expression: a, value: 2)\ncontext.assign(expression: b, value: 1)\ncontext.assign(expression: c, value: 3)\n\nvar result = expression.evaluate(context)\n```\n\n🍫 迭代器（Iterator）\n ---------------\n\n 迭代器模式可以让用户通过特定的接口巡访容器中的每一个元素而不用了解底层的实现。\n \n ### 示例：\n\n```swift\nstruct Novella {\n    let name: String\n}\n\nstruct Novellas {\n    let novellas: [Novella]\n}\n\nstruct NovellasIterator: IteratorProtocol {\n\n    private var current = 0\n    private let novellas: [Novella]\n\n    init(novellas: [Novella]) {\n        self.novellas = novellas\n    }\n\n    mutating func next() -\u003e Novella? {\n        defer { current += 1 }\n        return novellas.count \u003e current ? novellas[current] : nil\n    }\n}\n\nextension Novellas: Sequence {\n    func makeIterator() -\u003e NovellasIterator {\n        return NovellasIterator(novellas: novellas)\n    }\n}\n```\n\n### 用法\n\n```swift\nlet greatNovellas = Novellas(novellas: [Novella(name: \"The Mist\")] )\n\nfor novella in greatNovellas {\n    print(\"I've read: \\(novella)\")\n}\n```\n\n💐 中介者（Mediator）\n ---------------\n\n 用一个中介者对象封装一系列的对象交互，中介者使各对象不需要显示地相互作用，从而使耦合松散，而且可以独立地改变它们之间的交互。\n\n ### 示例：\n\n```swift\nprotocol Receiver {\n    associatedtype MessageType\n    func receive(message: MessageType)\n}\n\nprotocol Sender {\n    associatedtype MessageType\n    associatedtype ReceiverType: Receiver\n    \n    var recipients: [ReceiverType] { get }\n    \n    func send(message: MessageType)\n}\n\nstruct Programmer: Receiver {\n    let name: String\n    \n    init(name: String) {\n        self.name = name\n    }\n    \n    func receive(message: String) {\n        print(\"\\(name) received: \\(message)\")\n    }\n}\n\nfinal class MessageMediator: Sender {\n    internal var recipients: [Programmer] = []\n    \n    func add(recipient: Programmer) {\n        recipients.append(recipient)\n    }\n    \n    func send(message: String) {\n        for recipient in recipients {\n            recipient.receive(message: message)\n        }\n    }\n}\n\n```\n\n### 用法\n\n```swift\nfunc spamMonster(message: String, worker: MessageMediator) {\n    worker.send(message: message)\n}\n\nlet messagesMediator = MessageMediator()\n\nlet user0 = Programmer(name: \"Linus Torvalds\")\nlet user1 = Programmer(name: \"Avadis 'Avie' Tevanian\")\nmessagesMediator.add(recipient: user0)\nmessagesMediator.add(recipient: user1)\n\nspamMonster(message: \"I'd Like to Add you to My Professional Network\", worker: messagesMediator)\n\n```\n\n💾 备忘录（Memento）\n--------------\n\n在不破坏封装性的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态\n\n### 示例：\n\n```swift\ntypealias Memento = [String: String]\n```\n\n发起人（Originator）\n\n```swift\nprotocol MementoConvertible {\n    var memento: Memento { get }\n    init?(memento: Memento)\n}\n\nstruct GameState: MementoConvertible {\n\n    private enum Keys {\n        static let chapter = \"com.valve.halflife.chapter\"\n        static let weapon = \"com.valve.halflife.weapon\"\n    }\n\n    var chapter: String\n    var weapon: String\n\n    init(chapter: String, weapon: String) {\n        self.chapter = chapter\n        self.weapon = weapon\n    }\n\n    init?(memento: Memento) {\n        guard let mementoChapter = memento[Keys.chapter],\n              let mementoWeapon = memento[Keys.weapon] else {\n            return nil\n        }\n\n        chapter = mementoChapter\n        weapon = mementoWeapon\n    }\n\n    var memento: Memento {\n        return [ Keys.chapter: chapter, Keys.weapon: weapon ]\n    }\n}\n```\n\n管理者（Caretaker）\n\n```swift\nenum CheckPoint {\n\n    private static let defaults = UserDefaults.standard\n\n    static func save(_ state: MementoConvertible, saveName: String) {\n        defaults.set(state.memento, forKey: saveName)\n        defaults.synchronize()\n    }\n\n    static func restore(saveName: String) -\u003e Any? {\n        return defaults.object(forKey: saveName)\n    }\n}\n```\n\n### 用法\n\n```swift\nvar gameState = GameState(chapter: \"Black Mesa Inbound\", weapon: \"Crowbar\")\n\ngameState.chapter = \"Anomalous Materials\"\ngameState.weapon = \"Glock 17\"\nCheckPoint.save(gameState, saveName: \"gameState1\")\n\ngameState.chapter = \"Unforeseen Consequences\"\ngameState.weapon = \"MP5\"\nCheckPoint.save(gameState, saveName: \"gameState2\")\n\ngameState.chapter = \"Office Complex\"\ngameState.weapon = \"Crossbow\"\nCheckPoint.save(gameState, saveName: \"gameState3\")\n\nif let memento = CheckPoint.restore(saveName: \"gameState1\") as? Memento {\n    let finalState = GameState(memento: memento)\n    dump(finalState)\n}\n```\n\n👓 观察者（Observer）\n---------------\n\n一个目标对象管理所有相依于它的观察者对象，并且在它本身的状态改变时主动发出通知\n\n### 示例：\n\n```swift\nprotocol PropertyObserver : class {\n    func willChange(propertyName: String, newPropertyValue: Any?)\n    func didChange(propertyName: String, oldPropertyValue: Any?)\n}\n\nfinal class TestChambers {\n\n    weak var observer:PropertyObserver?\n\n    private let testChamberNumberName = \"testChamberNumber\"\n\n    var testChamberNumber: Int = 0 {\n        willSet(newValue) {\n            observer?.willChange(propertyName: testChamberNumberName, newPropertyValue: newValue)\n        }\n        didSet {\n            observer?.didChange(propertyName: testChamberNumberName, oldPropertyValue: oldValue)\n        }\n    }\n}\n\nfinal class Observer : PropertyObserver {\n    func willChange(propertyName: String, newPropertyValue: Any?) {\n        if newPropertyValue as? Int == 1 {\n            print(\"Okay. Look. We both said a lot of things that you're going to regret.\")\n        }\n    }\n\n    func didChange(propertyName: String, oldPropertyValue: Any?) {\n        if oldPropertyValue as? Int == 0 {\n            print(\"Sorry about the mess. I've really let the place go since you killed me.\")\n        }\n    }\n}\n```\n\n### 用法\n\n```swift\nvar observerInstance = Observer()\nvar testChambers = TestChambers()\ntestChambers.observer = observerInstance\ntestChambers.testChamberNumber += 1\n```\n\n🐉 状态（State）\n---------\n\n在状态模式中，对象的行为是基于它的内部状态而改变的。\n这个模式允许某个类对象在运行时发生改变。\n\n### 示例：\n\n```swift\nfinal class Context {\n\tprivate var state: State = UnauthorizedState()\n\n    var isAuthorized: Bool {\n        get { return state.isAuthorized(context: self) }\n    }\n\n    var userId: String? {\n        get { return state.userId(context: self) }\n    }\n\n\tfunc changeStateToAuthorized(userId: String) {\n\t\tstate = AuthorizedState(userId: userId)\n\t}\n\n\tfunc changeStateToUnauthorized() {\n\t\tstate = UnauthorizedState()\n\t}\n}\n\nprotocol State {\n\tfunc isAuthorized(context: Context) -\u003e Bool\n\tfunc userId(context: Context) -\u003e String?\n}\n\nclass UnauthorizedState: State {\n\tfunc isAuthorized(context: Context) -\u003e Bool { return false }\n\n\tfunc userId(context: Context) -\u003e String? { return nil }\n}\n\nclass AuthorizedState: State {\n\tlet userId: String\n\n\tinit(userId: String) { self.userId = userId }\n\n\tfunc isAuthorized(context: Context) -\u003e Bool { return true }\n\n\tfunc userId(context: Context) -\u003e String? { return userId }\n}\n```\n\n### 用法\n\n```swift\nlet userContext = Context()\n(userContext.isAuthorized, userContext.userId)\nuserContext.changeStateToAuthorized(userId: \"admin\")\n(userContext.isAuthorized, userContext.userId) // now logged in as \"admin\"\nuserContext.changeStateToUnauthorized()\n(userContext.isAuthorized, userContext.userId)\n```\n\n💡 策略（Strategy）\n--------------\n\n对象有某个行为，但是在不同的场景中，该行为有不同的实现算法。策略模式：\n* 定义了一族算法（业务规则）；\n* 封装了每个算法；\n* 这族的算法可互换代替（interchangeable）。\n\n### 示例：\n\n```swift\n\nstruct TestSubject {\n    let pupilDiameter: Double\n    let blushResponse: Double\n    let isOrganic: Bool\n}\n\nprotocol RealnessTesting: AnyObject {\n    func testRealness(_ testSubject: TestSubject) -\u003e Bool\n}\n\nfinal class VoightKampffTest: RealnessTesting {\n    func testRealness(_ testSubject: TestSubject) -\u003e Bool {\n        return testSubject.pupilDiameter \u003c 30.0 || testSubject.blushResponse == 0.0\n    }\n}\n\nfinal class GeneticTest: RealnessTesting {\n    func testRealness(_ testSubject: TestSubject) -\u003e Bool {\n        return testSubject.isOrganic\n    }\n}\n\nfinal class BladeRunner {\n    private let strategy: RealnessTesting\n\n    init(test: RealnessTesting) {\n        self.strategy = test\n    }\n\n    func testIfAndroid(_ testSubject: TestSubject) -\u003e Bool {\n        return !strategy.testRealness(testSubject)\n    }\n}\n\n```\n\n ### 用法\n \n```swift\n\nlet rachel = TestSubject(pupilDiameter: 30.2,\n                         blushResponse: 0.3,\n                         isOrganic: false)\n\n// Deckard is using a traditional test\nlet deckard = BladeRunner(test: VoightKampffTest())\nlet isRachelAndroid = deckard.testIfAndroid(rachel)\n\n// Gaff is using a very precise method\nlet gaff = BladeRunner(test: GeneticTest())\nlet isDeckardAndroid = gaff.testIfAndroid(rachel)\n```\n\n📝 模板方法模式\n-----------\n\n 模板方法模式是一种行为设计模式， 它通过父类/协议中定义了一个算法的框架， 允许子类/具体实现对象在不修改结构的情况下重写算法的特定步骤。\n\n### 示例：\n\n```swift\nprotocol Garden {\n    func prepareSoil()\n    func plantSeeds()\n    func waterPlants()\n    func prepareGarden()\n}\n\nextension Garden {\n\n    func prepareGarden() {\n        prepareSoil()\n        plantSeeds()\n        waterPlants()\n    }\n}\n\nfinal class RoseGarden: Garden {\n\n    func prepare() {\n        prepareGarden()\n    }\n\n    func prepareSoil() {\n        print (\"prepare soil for rose garden\")\n    }\n\n    func plantSeeds() {\n        print (\"plant seeds for rose garden\")\n    }\n\n    func waterPlants() {\n       print (\"water the rose garden\")\n    }\n}\n\n```\n\n### 用法\n\n```swift\n\nlet roseGarden = RoseGarden()\nroseGarden.prepare()\n```\n\n🏃 访问者（Visitor）\n--------------\n\n封装某些作用于某种数据结构中各元素的操作，它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。\n\n### 示例：\n\n```swift\nprotocol PlanetVisitor {\n\tfunc visit(planet: PlanetAlderaan)\n\tfunc visit(planet: PlanetCoruscant)\n\tfunc visit(planet: PlanetTatooine)\n    func visit(planet: MoonJedha)\n}\n\nprotocol Planet {\n\tfunc accept(visitor: PlanetVisitor)\n}\n\nfinal class MoonJedha: Planet {\n    func accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }\n}\n\nfinal class PlanetAlderaan: Planet {\n    func accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }\n}\n\nfinal class PlanetCoruscant: Planet {\n\tfunc accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }\n}\n\nfinal class PlanetTatooine: Planet {\n\tfunc accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }\n}\n\nfinal class NameVisitor: PlanetVisitor {\n\tvar name = \"\"\n\n\tfunc visit(planet: PlanetAlderaan)  { name = \"Alderaan\" }\n\tfunc visit(planet: PlanetCoruscant) { name = \"Coruscant\" }\n\tfunc visit(planet: PlanetTatooine)  { name = \"Tatooine\" }\n    func visit(planet: MoonJedha)     \t{ name = \"Jedha\" }\n}\n\n```\n\n### 用法\n\n```swift\nlet planets: [Planet] = [PlanetAlderaan(), PlanetCoruscant(), PlanetTatooine(), MoonJedha()]\n\nlet names = planets.map { (planet: Planet) -\u003e String in\n\tlet visitor = NameVisitor()\n    planet.accept(visitor: visitor)\n\n    return visitor.name\n}\n\nnames\n```\n\n\n 创建型模式\n ========\n \n \u003e 创建型模式是处理对象创建的设计模式，试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题，或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题。\n \u003e\n \u003e**来源：** [维基百科](https://zh.wikipedia.org/wiki/%E5%89%B5%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F)\n \n\n\n\n\n🌰 抽象工厂（Abstract Factory）\n-------------\n\n抽象工厂模式提供了一种方式，可以将一组具有同一主题的单独的工厂封装起来。在正常使用中，客户端程序需要创建抽象工厂的具体实现，然后使用抽象工厂作为接口来创建这一主题的具体对象。\n\n### 示例：\n\n协议\n\n```swift\n\nprotocol BurgerDescribing {\n    var ingredients: [String] { get }\n}\n\nstruct CheeseBurger: BurgerDescribing {\n    let ingredients: [String]\n}\n\nprotocol BurgerMaking {\n    func make() -\u003e BurgerDescribing\n}\n\n// 工厂方法实现\n\nfinal class BigKahunaBurger: BurgerMaking {\n    func make() -\u003e BurgerDescribing {\n        return CheeseBurger(ingredients: [\"Cheese\", \"Burger\", \"Lettuce\", \"Tomato\"])\n    }\n}\n\nfinal class JackInTheBox: BurgerMaking {\n    func make() -\u003e BurgerDescribing {\n        return CheeseBurger(ingredients: [\"Cheese\", \"Burger\", \"Tomato\", \"Onions\"])\n    }\n}\n\n```\n\n抽象工厂\n\n```swift\n\nenum BurgerFactoryType: BurgerMaking {\n\n    case bigKahuna\n    case jackInTheBox\n\n    func make() -\u003e BurgerDescribing {\n        switch self {\n        case .bigKahuna:\n            return BigKahunaBurger().make()\n        case .jackInTheBox:\n            return JackInTheBox().make()\n        }\n    }\n}\n```\n\n### 用法\n\n```swift\nlet bigKahuna = BurgerFactoryType.bigKahuna.make()\nlet jackInTheBox = BurgerFactoryType.jackInTheBox.make()\n```\n\n👷 生成器（Builder）\n--------------\n\n一种对象构建模式。它可以将复杂对象的建造过程抽象出来（抽象类别），使这个抽象过程的不同实现方法可以构造出不同表现（属性）的对象。\n\n### 示例：\n\n```swift\nfinal class DeathStarBuilder {\n\n    var x: Double?\n    var y: Double?\n    var z: Double?\n\n    typealias BuilderClosure = (DeathStarBuilder) -\u003e ()\n\n    init(buildClosure: BuilderClosure) {\n        buildClosure(self)\n    }\n}\n\nstruct DeathStar : CustomStringConvertible {\n\n    let x: Double\n    let y: Double\n    let z: Double\n\n    init?(builder: DeathStarBuilder) {\n\n        if let x = builder.x, let y = builder.y, let z = builder.z {\n            self.x = x\n            self.y = y\n            self.z = z\n        } else {\n            return nil\n        }\n    }\n\n    var description:String {\n        return \"Death Star at (x:\\(x) y:\\(y) z:\\(z))\"\n    }\n}\n```\n\n### 用法\n\n```swift\nlet empire = DeathStarBuilder { builder in\n    builder.x = 0.1\n    builder.y = 0.2\n    builder.z = 0.3\n}\n\nlet deathStar = DeathStar(builder:empire)\n```\n\n🏭 工厂方法（Factory Method）\n-----------------------\n\n定义一个创建对象的接口，但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。\n\n### 示例：\n\n```swift\nprotocol CurrencyDescribing {\n    var symbol: String { get }\n    var code: String { get }\n}\n\nfinal class Euro: CurrencyDescribing {\n    var symbol: String {\n        return \"€\"\n    }\n    \n    var code: String {\n        return \"EUR\"\n    }\n}\n\nfinal class UnitedStatesDolar: CurrencyDescribing {\n    var symbol: String {\n        return \"$\"\n    }\n    \n    var code: String {\n        return \"USD\"\n    }\n}\n\nenum Country {\n    case unitedStates\n    case spain\n    case uk\n    case greece\n}\n\nenum CurrencyFactory {\n    static func currency(for country: Country) -\u003e CurrencyDescribing? {\n\n        switch country {\n            case .spain, .greece:\n                return Euro()\n            case .unitedStates:\n                return UnitedStatesDolar()\n            default:\n                return nil\n        }\n        \n    }\n}\n```\n\n### 用法\n\n```swift\nlet noCurrencyCode = \"No Currency Code Available\"\n\nCurrencyFactory.currency(for: .greece)?.code ?? noCurrencyCode\nCurrencyFactory.currency(for: .spain)?.code ?? noCurrencyCode\nCurrencyFactory.currency(for: .unitedStates)?.code ?? noCurrencyCode\nCurrencyFactory.currency(for: .uk)?.code ?? noCurrencyCode\n```\n\n 🔂 单态（Monostate）\n ------------\n\n  单态模式是实现单一共享的另一种方法。不同于单例模式，它通过完全不同的机制，在不限制构造方法的情况下实现单一共享特性。\n  因此，在这种情况下，单态会将状态保存为静态，而不是将整个实例保存为单例。\n [单例和单态 - Robert C. Martin](http://staff.cs.utu.fi/~jounsmed/doos_06/material/SingletonAndMonostate.pdf)\n\n### 示例:\n\n```swift\nclass Settings {\n\n    enum Theme {\n        case `default`\n        case old\n        case new\n    }\n\n    private static var theme: Theme?\n\n    var currentTheme: Theme {\n        get { Settings.theme ?? .default }\n        set(newTheme) { Settings.theme = newTheme }\n    }\n}\n```\n\n### 用法:\n\n```swift\nimport SwiftUI\n\n// 改变主题\nlet settings = Settings() // 开始使用主题 .old\nsettings.currentTheme = .new // 改变主题为 .new\n\n// 界面一\nlet screenColor: Color = Settings().currentTheme == .old ? .gray : .white\n\n// 界面二\nlet screenTitle: String = Settings().currentTheme == .old ? \"Itunes Connect\" : \"App Store Connect\"\n```\n\n🃏 原型（Prototype）\n--------------\n\n通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”，这个原型是可定制的。\n\n### 示例：\n\n```swift\nclass MoonWorker {\n\n    let name: String\n    var health: Int = 100\n\n    init(name: String) {\n        self.name = name\n    }\n\n    func clone() -\u003e MoonWorker {\n        return MoonWorker(name: name)\n    }\n}\n```\n\n### 用法\n\n```swift\nlet prototype = MoonWorker(name: \"Sam Bell\")\n\nvar bell1 = prototype.clone()\nbell1.health = 12\n\nvar bell2 = prototype.clone()\nbell2.health = 23\n\nvar bell3 = prototype.clone()\nbell3.health = 0\n```\n\n💍 单例（Singleton）\n--------------\n\n单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象，这样有利于我们协调系统整体的行为\n\n### 示例：\n\n```swift\nfinal class ElonMusk {\n\n    static let shared = ElonMusk()\n\n    private init() {\n        // Private initialization to ensure just one instance is created.\n    }\n}\n```\n\n### 用法\n\n```swift\nlet elon = ElonMusk.shared // There is only one Elon Musk folks.\n```\n\n\n结构型模式（Structural）\n====================\n\n\u003e 在软件工程中结构型模式是设计模式，借由一以贯之的方式来了解元件间的关系，以简化设计。\n\u003e\n\u003e**来源：** [维基百科](https://zh.wikipedia.org/wiki/%E7%B5%90%E6%A7%8B%E5%9E%8B%E6%A8%A1%E5%BC%8F)\n\n\n\n\n🔌 适配器（Adapter）\n--------------\n\n适配器模式有时候也称包装样式或者包装(wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起，做法是将类自己的接口包裹在一个已存在的类中。\n\n### 示例：\n\n```swift\nprotocol NewDeathStarSuperLaserAiming {\n    var angleV: Double { get }\n    var angleH: Double { get }\n}\n```\n\n**被适配者**\n\n```swift\nstruct OldDeathStarSuperlaserTarget {\n    let angleHorizontal: Float\n    let angleVertical: Float\n\n    init(angleHorizontal: Float, angleVertical: Float) {\n        self.angleHorizontal = angleHorizontal\n        self.angleVertical = angleVertical\n    }\n}\n```\n\n**适配器**\n\n```swift\nstruct NewDeathStarSuperlaserTarget: NewDeathStarSuperLaserAiming {\n\n    private let target: OldDeathStarSuperlaserTarget\n\n    var angleV: Double {\n        return Double(target.angleVertical)\n    }\n\n    var angleH: Double {\n        return Double(target.angleHorizontal)\n    }\n\n    init(_ target: OldDeathStarSuperlaserTarget) {\n        self.target = target\n    }\n}\n```\n\n### 用法\n\n```swift\nlet target = OldDeathStarSuperlaserTarget(angleHorizontal: 14.0, angleVertical: 12.0)\nlet newFormat = NewDeathStarSuperlaserTarget(target)\n\nnewFormat.angleH\nnewFormat.angleV\n```\n\n🌉 桥接（Bridge）\n-----------\n\n桥接模式将抽象部分与实现部分分离，使它们都可以独立的变化。\n\n### 示例：\n\n```swift\nprotocol Switch {\n    var appliance: Appliance { get set }\n    func turnOn()\n}\n\nprotocol Appliance {\n    func run()\n}\n\nfinal class RemoteControl: Switch {\n    var appliance: Appliance\n\n    func turnOn() {\n        self.appliance.run()\n    }\n    \n    init(appliance: Appliance) {\n        self.appliance = appliance\n    }\n}\n\nfinal class TV: Appliance {\n    func run() {\n        print(\"tv turned on\");\n    }\n}\n\nfinal class VacuumCleaner: Appliance {\n    func run() {\n        print(\"vacuum cleaner turned on\")\n    }\n}\n```\n\n### 用法\n\n```swift\nlet tvRemoteControl = RemoteControl(appliance: TV())\ntvRemoteControl.turnOn()\n\nlet fancyVacuumCleanerRemoteControl = RemoteControl(appliance: VacuumCleaner())\nfancyVacuumCleanerRemoteControl.turnOn()\n```\n\n🌿 组合（Composite）\n--------------\n\n将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。\n\n### 示例：\n\n组件（Component）\n\n```swift\nprotocol Shape {\n    func draw(fillColor: String)\n}\n```\n\n叶子节点（Leafs）\n\n```swift\nfinal class Square: Shape {\n    func draw(fillColor: String) {\n        print(\"Drawing a Square with color \\(fillColor)\")\n    }\n}\n\nfinal class Circle: Shape {\n    func draw(fillColor: String) {\n        print(\"Drawing a circle with color \\(fillColor)\")\n    }\n}\n\n```\n\n组合\n\n```swift\nfinal class Whiteboard: Shape {\n\n    private lazy var shapes = [Shape]()\n\n    init(_ shapes: Shape...) {\n        self.shapes = shapes\n    }\n\n    func draw(fillColor: String) {\n        for shape in self.shapes {\n            shape.draw(fillColor: fillColor)\n        }\n    }\n}\n```\n\n### 用法\n\n```swift\nvar whiteboard = Whiteboard(Circle(), Square())\nwhiteboard.draw(fillColor: \"Red\")\n```\n\n🍧 修饰（Decorator）\n--------------\n\n修饰模式，是面向对象编程领域中，一种动态地往一个类中添加新的行为的设计模式。\n就功能而言，修饰模式相比生成子类更为灵活，这样可以给某个对象而不是整个类添加一些功能。\n\n### 示例：\n\n```swift\nprotocol CostHaving {\n    var cost: Double { get }\n}\n\nprotocol IngredientsHaving {\n    var ingredients: [String] { get }\n}\n\ntypealias BeverageDataHaving = CostHaving \u0026 IngredientsHaving\n\nstruct SimpleCoffee: BeverageDataHaving {\n    let cost: Double = 1.0\n    let ingredients = [\"Water\", \"Coffee\"]\n}\n\nprotocol BeverageHaving: BeverageDataHaving {\n    var beverage: BeverageDataHaving { get }\n}\n\nstruct Milk: BeverageHaving {\n\n    let beverage: BeverageDataHaving\n\n    var cost: Double {\n        return beverage.cost + 0.5\n    }\n\n    var ingredients: [String] {\n        return beverage.ingredients + [\"Milk\"]\n    }\n}\n\nstruct WhipCoffee: BeverageHaving {\n\n    let beverage: BeverageDataHaving\n\n    var cost: Double {\n        return beverage.cost + 0.5\n    }\n\n    var ingredients: [String] {\n        return beverage.ingredients + [\"Whip\"]\n    }\n}\n```\n\n### 用法\n\n```swift\nvar someCoffee: BeverageDataHaving = SimpleCoffee()\nprint(\"Cost: \\(someCoffee.cost); Ingredients: \\(someCoffee.ingredients)\")\nsomeCoffee = Milk(beverage: someCoffee)\nprint(\"Cost: \\(someCoffee.cost); Ingredients: \\(someCoffee.ingredients)\")\nsomeCoffee = WhipCoffee(beverage: someCoffee)\nprint(\"Cost: \\(someCoffee.cost); Ingredients: \\(someCoffee.ingredients)\")\n```\n\n🎁 外观（Facade）\n-----------\n\n外观模式为子系统中的一组接口提供一个统一的高层接口，使得子系统更容易使用。\n\n### 示例：\n\n```swift\nfinal class Defaults {\n\n    private let defaults: UserDefaults\n\n    init(defaults: UserDefaults = .standard) {\n        self.defaults = defaults\n    }\n\n    subscript(key: String) -\u003e String? {\n        get {\n            return defaults.string(forKey: key)\n        }\n\n        set {\n            defaults.set(newValue, forKey: key)\n        }\n    }\n}\n```\n\n### 用法\n\n```swift\nlet storage = Defaults()\n\n// Store\nstorage[\"Bishop\"] = \"Disconnect me. I’d rather be nothing\"\n\n// Read\nstorage[\"Bishop\"]\n```\n\n🍃 享元（Flyweight）\n--------------\n\n使用共享物件，用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件；它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。\n\n### 示例：\n\n```swift\n// 特指咖啡生成的对象会是享元\nstruct SpecialityCoffee {\n    let origin: String\n}\n\nprotocol CoffeeSearching {\n    func search(origin: String) -\u003e SpecialityCoffee?\n}\n\n// 菜单充当特制咖啡享元对象的工厂和缓存\nfinal class Menu: CoffeeSearching {\n\n    private var coffeeAvailable: [String: SpecialityCoffee] = [:]\n\n    func search(origin: String) -\u003e SpecialityCoffee? {\n        if coffeeAvailable.index(forKey: origin) == nil {\n            coffeeAvailable[origin] = SpecialityCoffee(origin: origin)\n        }\n\n        return coffeeAvailable[origin]\n    }\n}\n\nfinal class CoffeeShop {\n    private var orders: [Int: SpecialityCoffee] = [:]\n    private let menu: CoffeeSearching\n\n    init(menu: CoffeeSearching) {\n        self.menu = menu\n    }\n\n    func takeOrder(origin: String, table: Int) {\n        orders[table] = menu.search(origin: origin)\n    }\n\n    func serve() {\n        for (table, origin) in orders {\n            print(\"Serving \\(origin) to table \\(table)\")\n        }\n    }\n}\n```\n\n### 用法\n\n```swift\nlet coffeeShop = CoffeeShop(menu: Menu())\n\ncoffeeShop.takeOrder(origin: \"Yirgacheffe, Ethiopia\", table: 1)\ncoffeeShop.takeOrder(origin: \"Buziraguhindwa, Burundi\", table: 3)\n\ncoffeeShop.serve()\n```\n\n☔ 保护代理模式（Protection Proxy）\n------------------\n\n在代理模式中，创建一个类代表另一个底层类的功能。\n保护代理用于限制访问。\n\n### 示例：\n\n```swift\nprotocol DoorOpening {\n    func open(doors: String) -\u003e String\n}\n\nfinal class HAL9000: DoorOpening {\n    func open(doors: String) -\u003e String {\n        return (\"HAL9000: Affirmative, Dave. I read you. Opened \\(doors).\")\n    }\n}\n\nfinal class CurrentComputer: DoorOpening {\n    private var computer: HAL9000!\n\n    func authenticate(password: String) -\u003e Bool {\n\n        guard password == \"pass\" else {\n            return false\n        }\n\n        computer = HAL9000()\n\n        return true\n    }\n\n    func open(doors: String) -\u003e String {\n\n        guard computer != nil else {\n            return \"Access Denied. I'm afraid I can't do that.\"\n        }\n\n        return computer.open(doors: doors)\n    }\n}\n```\n\n### 用法\n\n```swift\nlet computer = CurrentComputer()\nlet podBay = \"Pod Bay Doors\"\n\ncomputer.open(doors: podBay)\n\ncomputer.authenticate(password: \"pass\")\ncomputer.open(doors: podBay)\n```\n\n🍬 虚拟代理（Virtual Proxy）\n----------------\n\n在代理模式中，创建一个类代表另一个底层类的功能。\n虚拟代理用于对象的需时加载。\n\n### 示例：\n\n```swift\nprotocol HEVSuitMedicalAid {\n    func administerMorphine() -\u003e String\n}\n\nfinal class HEVSuit: HEVSuitMedicalAid {\n    func administerMorphine() -\u003e String {\n        return \"Morphine administered.\"\n    }\n}\n\nfinal class HEVSuitHumanInterface: HEVSuitMedicalAid {\n\n    lazy private var physicalSuit: HEVSuit = HEVSuit()\n\n    func administerMorphine() -\u003e String {\n        return physicalSuit.administerMorphine()\n    }\n}\n```\n\n### 用法\n\n```swift\nlet humanInterface = HEVSuitHumanInterface()\nhumanInterface.administerMorphine()\n```\n\n\nInfo\n====\n\n📖 Descriptions from: [Gang of Four Design Patterns Reference Sheet](http://www.blackwasp.co.uk/GangOfFour.aspx)\n","funding_links":["https://github.com/sponsors/ochococo"],"categories":["Swift Playgrounds","Conteúdos","Swift","Patterns","HarmonyOS","Programming Language Design Patterns","Patterns [🔝](#readme)","Learning Swift: Advanced Topics","Style Guides","객체지향","Uncategorized","swift-5","Programming Languages","Другие списки / ссылки","GoF design patterns (Language/Framework specifc)","Language","Language/Framework design patterns (mainly GoF)"],"sub_categories":["Padrões de Projeto","Vim","Style Guides","Windows Manager","Design Patterns","웹","Uncategorized","Туториалы"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fochococo%2FDesign-Patterns-In-Swift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fochococo%2FDesign-Patterns-In-Swift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fochococo%2FDesign-Patterns-In-Swift/lists"}