Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/ochococo/Design-Patterns-In-Swift

📖 Design Patterns implemented in Swift 5.0
https://github.com/ochococo/Design-Patterns-In-Swift

computer-science design-patterns gang-of-four good-practices playground swift swift-5

Last synced: about 2 months ago
JSON representation

📖 Design Patterns implemented in Swift 5.0

Lists

README

        

设计模式(Swift 5.0 实现)
======================

([Design-Patterns-CN.playground.zip](https://raw.githubusercontent.com/ochococo/Design-Patterns-In-Swift/master/Design-Patterns-CN.playground.zip)).

👷 源项目由 [@nsmeme](http://twitter.com/nsmeme) (Oktawian Chojnacki) 维护。

🇨🇳 中文版由 [@binglogo](https://twitter.com/binglogo) 整理翻译。

```swift
print("您好!")
```

## 目录

| [行为型模式](#行为型模式) | [创建型模式](#创建型模式) | [结构型模式](#结构型模式structural) |
| ------------------------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------ |
| [🐝 责任链 Chain Of Responsibility](#-责任链chain-of-responsibility) | [🌰 抽象工厂 Abstract Factory](#-抽象工厂abstract-factory) | [🔌 适配器 Adapter](#-适配器adapter) |
| [👫 命令 Command](#-命令command) | [👷 生成器 Builder](#-生成器builder) | [🌉 桥接 Bridge](#-桥接bridge) |
| [🎶 解释器 Interpreter](#-解释器interpreter) | [🏭 工厂方法 Factory Method](#-工厂方法factory-method) | [🌿 组合 Composite](#-组合composite) |
| [🍫 迭代器 Iterator](#-迭代器iterator) | [🔂 单态 Monostate](#-单态monostate) | [🍧 修饰 Decorator](#-修饰decorator) |
| [💐 中介者 Mediator](#-中介者mediator) | [🃏 原型 Prototype](#-原型prototype) | [🎁 外观 Façade](#-外观facade) |
| [💾 备忘录 Memento](#-备忘录memento) | [💍 单例 Singleton](#-单例singleton) | [🍃 享元 Flyweight](#-享元flyweight) |
| [👓 观察者 Observer](#-观察者observer) | | [☔ 保护代理 Protection Proxy](#-保护代理模式protection-proxy) |
| [🐉 状态 State](#-状态state) | | [🍬 虚拟代理 Virtual Proxy](#-虚拟代理virtual-proxy) |
| [💡 策略 Strategy](#-策略strategy) | | |
| [📝 模板方法 Templdate Method](#-template-method) | | |
| [🏃 访问者 Visitor](#-访问者visitor) | | |

行为型模式
========

>在软件工程中, 行为型模式为设计模式的一种类型,用来识别对象之间的常用交流模式并加以实现。如此,可在进行这些交流活动时增强弹性。
>
>**来源:** [维基百科](https://zh.wikipedia.org/wiki/%E8%A1%8C%E7%82%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F)

🐝 责任链(Chain Of Responsibility)
------------------------------

责任链模式在面向对象程式设计里是一种软件设计模式,它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。

### 示例:

```swift

protocol Withdrawing {
func withdraw(amount: Int) -> Bool
}

final class MoneyPile: Withdrawing {

let value: Int
var quantity: Int
var next: Withdrawing?

init(value: Int, quantity: Int, next: Withdrawing?) {
self.value = value
self.quantity = quantity
self.next = next
}

func withdraw(amount: Int) -> Bool {

var amount = amount

func canTakeSomeBill(want: Int) -> Bool {
return (want / self.value) > 0
}

var quantity = self.quantity

while canTakeSomeBill(want: amount) {

if quantity == 0 {
break
}

amount -= self.value
quantity -= 1
}

guard amount > 0 else {
return true
}

if let next {
return next.withdraw(amount: amount)
}

return false
}
}

final class ATM: Withdrawing {

private var hundred: Withdrawing
private var fifty: Withdrawing
private var twenty: Withdrawing
private var ten: Withdrawing

private var startPile: Withdrawing {
return self.hundred
}

init(hundred: Withdrawing,
fifty: Withdrawing,
twenty: Withdrawing,
ten: Withdrawing) {

self.hundred = hundred
self.fifty = fifty
self.twenty = twenty
self.ten = ten
}

func withdraw(amount: Int) -> Bool {
return startPile.withdraw(amount: amount)
}
}
```

### 用法

```swift
// 创建一系列的钱堆,并将其链接起来:10<20<50<100
let ten = MoneyPile(value: 10, quantity: 6, next: nil)
let twenty = MoneyPile(value: 20, quantity: 2, next: ten)
let fifty = MoneyPile(value: 50, quantity: 2, next: twenty)
let hundred = MoneyPile(value: 100, quantity: 1, next: fifty)

// 创建 ATM 实例
var atm = ATM(hundred: hundred, fifty: fifty, twenty: twenty, ten: ten)
atm.withdraw(amount: 310) // Cannot because ATM has only 300
atm.withdraw(amount: 100) // Can withdraw - 1x100
```

👫 命令(Command)
------------
命令模式是一种设计模式,它尝试以对象来代表实际行动。命令对象可以把行动(action) 及其参数封装起来,于是这些行动可以被:
* 重复多次
* 取消(如果该对象有实现的话)
* 取消后又再重做
### 示例:

```swift
protocol DoorCommand {
func execute() -> String
}

final class OpenCommand: DoorCommand {
let doors:String

required init(doors: String) {
self.doors = doors
}

func execute() -> String {
return "Opened \(doors)"
}
}

final class CloseCommand: DoorCommand {
let doors:String

required init(doors: String) {
self.doors = doors
}

func execute() -> String {
return "Closed \(doors)"
}
}

final class HAL9000DoorsOperations {
let openCommand: DoorCommand
let closeCommand: DoorCommand

init(doors: String) {
self.openCommand = OpenCommand(doors:doors)
self.closeCommand = CloseCommand(doors:doors)
}

func close() -> String {
return closeCommand.execute()
}

func open() -> String {
return openCommand.execute()
}
}
```

### 用法

```swift
let podBayDoors = "Pod Bay Doors"
let doorModule = HAL9000DoorsOperations(doors:podBayDoors)

doorModule.open()
doorModule.close()
```

🎶 解释器(Interpreter)
------------------

给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子。

### 示例:

```swift

protocol IntegerExpression {
func evaluate(_ context: IntegerContext) -> Int
func replace(character: Character, integerExpression: IntegerExpression) -> IntegerExpression
func copied() -> IntegerExpression
}

final class IntegerContext {
private var data: [Character:Int] = [:]

func lookup(name: Character) -> Int {
return self.data[name]!
}

func assign(expression: IntegerVariableExpression, value: Int) {
self.data[expression.name] = value
}
}

final class IntegerVariableExpression: IntegerExpression {
let name: Character

init(name: Character) {
self.name = name
}

func evaluate(_ context: IntegerContext) -> Int {
return context.lookup(name: self.name)
}

func replace(character name: Character, integerExpression: IntegerExpression) -> IntegerExpression {
if name == self.name {
return integerExpression.copied()
} else {
return IntegerVariableExpression(name: self.name)
}
}

func copied() -> IntegerExpression {
return IntegerVariableExpression(name: self.name)
}
}

final class AddExpression: IntegerExpression {
private var operand1: IntegerExpression
private var operand2: IntegerExpression

init(op1: IntegerExpression, op2: IntegerExpression) {
self.operand1 = op1
self.operand2 = op2
}

func evaluate(_ context: IntegerContext) -> Int {
return self.operand1.evaluate(context) + self.operand2.evaluate(context)
}

func replace(character: Character, integerExpression: IntegerExpression) -> IntegerExpression {
return AddExpression(op1: operand1.replace(character: character, integerExpression: integerExpression),
op2: operand2.replace(character: character, integerExpression: integerExpression))
}

func copied() -> IntegerExpression {
return AddExpression(op1: self.operand1, op2: self.operand2)
}
}
```

### 用法

```swift
var context = IntegerContext()

var a = IntegerVariableExpression(name: "A")
var b = IntegerVariableExpression(name: "B")
var c = IntegerVariableExpression(name: "C")

var expression = AddExpression(op1: a, op2: AddExpression(op1: b, op2: c)) // a + (b + c)

context.assign(expression: a, value: 2)
context.assign(expression: b, value: 1)
context.assign(expression: c, value: 3)

var result = expression.evaluate(context)
```

🍫 迭代器(Iterator)
---------------

迭代器模式可以让用户通过特定的接口巡访容器中的每一个元素而不用了解底层的实现。

### 示例:

```swift
struct Novella {
let name: String
}

struct Novellas {
let novellas: [Novella]
}

struct NovellasIterator: IteratorProtocol {

private var current = 0
private let novellas: [Novella]

init(novellas: [Novella]) {
self.novellas = novellas
}

mutating func next() -> Novella? {
defer { current += 1 }
return novellas.count > current ? novellas[current] : nil
}
}

extension Novellas: Sequence {
func makeIterator() -> NovellasIterator {
return NovellasIterator(novellas: novellas)
}
}
```

### 用法

```swift
let greatNovellas = Novellas(novellas: [Novella(name: "The Mist")] )

for novella in greatNovellas {
print("I've read: \(novella)")
}
```

💐 中介者(Mediator)
---------------

用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。

### 示例:

```swift
protocol Receiver {
associatedtype MessageType
func receive(message: MessageType)
}

protocol Sender {
associatedtype MessageType
associatedtype ReceiverType: Receiver

var recipients: [ReceiverType] { get }

func send(message: MessageType)
}

struct Programmer: Receiver {
let name: String

init(name: String) {
self.name = name
}

func receive(message: String) {
print("\(name) received: \(message)")
}
}

final class MessageMediator: Sender {
internal var recipients: [Programmer] = []

func add(recipient: Programmer) {
recipients.append(recipient)
}

func send(message: String) {
for recipient in recipients {
recipient.receive(message: message)
}
}
}

```

### 用法

```swift
func spamMonster(message: String, worker: MessageMediator) {
worker.send(message: message)
}

let messagesMediator = MessageMediator()

let user0 = Programmer(name: "Linus Torvalds")
let user1 = Programmer(name: "Avadis 'Avie' Tevanian")
messagesMediator.add(recipient: user0)
messagesMediator.add(recipient: user1)

spamMonster(message: "I'd Like to Add you to My Professional Network", worker: messagesMediator)

```

💾 备忘录(Memento)
--------------

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态

### 示例:

```swift
typealias Memento = [String: String]
```

发起人(Originator)

```swift
protocol MementoConvertible {
var memento: Memento { get }
init?(memento: Memento)
}

struct GameState: MementoConvertible {

private enum Keys {
static let chapter = "com.valve.halflife.chapter"
static let weapon = "com.valve.halflife.weapon"
}

var chapter: String
var weapon: String

init(chapter: String, weapon: String) {
self.chapter = chapter
self.weapon = weapon
}

init?(memento: Memento) {
guard let mementoChapter = memento[Keys.chapter],
let mementoWeapon = memento[Keys.weapon] else {
return nil
}

chapter = mementoChapter
weapon = mementoWeapon
}

var memento: Memento {
return [ Keys.chapter: chapter, Keys.weapon: weapon ]
}
}
```

管理者(Caretaker)

```swift
enum CheckPoint {

private static let defaults = UserDefaults.standard

static func save(_ state: MementoConvertible, saveName: String) {
defaults.set(state.memento, forKey: saveName)
defaults.synchronize()
}

static func restore(saveName: String) -> Any? {
return defaults.object(forKey: saveName)
}
}
```

### 用法

```swift
var gameState = GameState(chapter: "Black Mesa Inbound", weapon: "Crowbar")

gameState.chapter = "Anomalous Materials"
gameState.weapon = "Glock 17"
CheckPoint.save(gameState, saveName: "gameState1")

gameState.chapter = "Unforeseen Consequences"
gameState.weapon = "MP5"
CheckPoint.save(gameState, saveName: "gameState2")

gameState.chapter = "Office Complex"
gameState.weapon = "Crossbow"
CheckPoint.save(gameState, saveName: "gameState3")

if let memento = CheckPoint.restore(saveName: "gameState1") as? Memento {
let finalState = GameState(memento: memento)
dump(finalState)
}
```

👓 观察者(Observer)
---------------

一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知

### 示例:

```swift
protocol PropertyObserver : class {
func willChange(propertyName: String, newPropertyValue: Any?)
func didChange(propertyName: String, oldPropertyValue: Any?)
}

final class TestChambers {

weak var observer:PropertyObserver?

private let testChamberNumberName = "testChamberNumber"

var testChamberNumber: Int = 0 {
willSet(newValue) {
observer?.willChange(propertyName: testChamberNumberName, newPropertyValue: newValue)
}
didSet {
observer?.didChange(propertyName: testChamberNumberName, oldPropertyValue: oldValue)
}
}
}

final class Observer : PropertyObserver {
func willChange(propertyName: String, newPropertyValue: Any?) {
if newPropertyValue as? Int == 1 {
print("Okay. Look. We both said a lot of things that you're going to regret.")
}
}

func didChange(propertyName: String, oldPropertyValue: Any?) {
if oldPropertyValue as? Int == 0 {
print("Sorry about the mess. I've really let the place go since you killed me.")
}
}
}
```

### 用法

```swift
var observerInstance = Observer()
var testChambers = TestChambers()
testChambers.observer = observerInstance
testChambers.testChamberNumber += 1
```

🐉 状态(State)
---------

在状态模式中,对象的行为是基于它的内部状态而改变的。
这个模式允许某个类对象在运行时发生改变。

### 示例:

```swift
final class Context {
private var state: State = UnauthorizedState()

var isAuthorized: Bool {
get { return state.isAuthorized(context: self) }
}

var userId: String? {
get { return state.userId(context: self) }
}

func changeStateToAuthorized(userId: String) {
state = AuthorizedState(userId: userId)
}

func changeStateToUnauthorized() {
state = UnauthorizedState()
}
}

protocol State {
func isAuthorized(context: Context) -> Bool
func userId(context: Context) -> String?
}

class UnauthorizedState: State {
func isAuthorized(context: Context) -> Bool { return false }

func userId(context: Context) -> String? { return nil }
}

class AuthorizedState: State {
let userId: String

init(userId: String) { self.userId = userId }

func isAuthorized(context: Context) -> Bool { return true }

func userId(context: Context) -> String? { return userId }
}
```

### 用法

```swift
let userContext = Context()
(userContext.isAuthorized, userContext.userId)
userContext.changeStateToAuthorized(userId: "admin")
(userContext.isAuthorized, userContext.userId) // now logged in as "admin"
userContext.changeStateToUnauthorized()
(userContext.isAuthorized, userContext.userId)
```

💡 策略(Strategy)
--------------

对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。策略模式:
* 定义了一族算法(业务规则);
* 封装了每个算法;
* 这族的算法可互换代替(interchangeable)。

### 示例:

```swift

struct TestSubject {
let pupilDiameter: Double
let blushResponse: Double
let isOrganic: Bool
}

protocol RealnessTesting: AnyObject {
func testRealness(_ testSubject: TestSubject) -> Bool
}

final class VoightKampffTest: RealnessTesting {
func testRealness(_ testSubject: TestSubject) -> Bool {
return testSubject.pupilDiameter < 30.0 || testSubject.blushResponse == 0.0
}
}

final class GeneticTest: RealnessTesting {
func testRealness(_ testSubject: TestSubject) -> Bool {
return testSubject.isOrganic
}
}

final class BladeRunner {
private let strategy: RealnessTesting

init(test: RealnessTesting) {
self.strategy = test
}

func testIfAndroid(_ testSubject: TestSubject) -> Bool {
return !strategy.testRealness(testSubject)
}
}

```

### 用法

```swift

let rachel = TestSubject(pupilDiameter: 30.2,
blushResponse: 0.3,
isOrganic: false)

// Deckard is using a traditional test
let deckard = BladeRunner(test: VoightKampffTest())
let isRachelAndroid = deckard.testIfAndroid(rachel)

// Gaff is using a very precise method
let gaff = BladeRunner(test: GeneticTest())
let isDeckardAndroid = gaff.testIfAndroid(rachel)
```

📝 模板方法模式
-----------

模板方法模式是一种行为设计模式, 它通过父类/协议中定义了一个算法的框架, 允许子类/具体实现对象在不修改结构的情况下重写算法的特定步骤。

### 示例:

```swift
protocol Garden {
func prepareSoil()
func plantSeeds()
func waterPlants()
func prepareGarden()
}

extension Garden {

func prepareGarden() {
prepareSoil()
plantSeeds()
waterPlants()
}
}

final class RoseGarden: Garden {

func prepare() {
prepareGarden()
}

func prepareSoil() {
print ("prepare soil for rose garden")
}

func plantSeeds() {
print ("plant seeds for rose garden")
}

func waterPlants() {
print ("water the rose garden")
}
}

```

### 用法

```swift

let roseGarden = RoseGarden()
roseGarden.prepare()
```

🏃 访问者(Visitor)
--------------

封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

### 示例:

```swift
protocol PlanetVisitor {
func visit(planet: PlanetAlderaan)
func visit(planet: PlanetCoruscant)
func visit(planet: PlanetTatooine)
func visit(planet: MoonJedha)
}

protocol Planet {
func accept(visitor: PlanetVisitor)
}

final class MoonJedha: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }
}

final class PlanetAlderaan: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }
}

final class PlanetCoruscant: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }
}

final class PlanetTatooine: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(planet: self) }
}

final class NameVisitor: PlanetVisitor {
var name = ""

func visit(planet: PlanetAlderaan) { name = "Alderaan" }
func visit(planet: PlanetCoruscant) { name = "Coruscant" }
func visit(planet: PlanetTatooine) { name = "Tatooine" }
func visit(planet: MoonJedha) { name = "Jedha" }
}

```

### 用法

```swift
let planets: [Planet] = [PlanetAlderaan(), PlanetCoruscant(), PlanetTatooine(), MoonJedha()]

let names = planets.map { (planet: Planet) -> String in
let visitor = NameVisitor()
planet.accept(visitor: visitor)

return visitor.name
}

names
```

创建型模式
========

> 创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题。
>
>**来源:** [维基百科](https://zh.wikipedia.org/wiki/%E5%89%B5%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F)

🌰 抽象工厂(Abstract Factory)
-------------

抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。在正常使用中,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象。

### 示例:

协议

```swift

protocol BurgerDescribing {
var ingredients: [String] { get }
}

struct CheeseBurger: BurgerDescribing {
let ingredients: [String]
}

protocol BurgerMaking {
func make() -> BurgerDescribing
}

// 工厂方法实现

final class BigKahunaBurger: BurgerMaking {
func make() -> BurgerDescribing {
return CheeseBurger(ingredients: ["Cheese", "Burger", "Lettuce", "Tomato"])
}
}

final class JackInTheBox: BurgerMaking {
func make() -> BurgerDescribing {
return CheeseBurger(ingredients: ["Cheese", "Burger", "Tomato", "Onions"])
}
}

```

抽象工厂

```swift

enum BurgerFactoryType: BurgerMaking {

case bigKahuna
case jackInTheBox

func make() -> BurgerDescribing {
switch self {
case .bigKahuna:
return BigKahunaBurger().make()
case .jackInTheBox:
return JackInTheBox().make()
}
}
}
```

### 用法

```swift
let bigKahuna = BurgerFactoryType.bigKahuna.make()
let jackInTheBox = BurgerFactoryType.jackInTheBox.make()
```

👷 生成器(Builder)
--------------

一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。

### 示例:

```swift
final class DeathStarBuilder {

var x: Double?
var y: Double?
var z: Double?

typealias BuilderClosure = (DeathStarBuilder) -> ()

init(buildClosure: BuilderClosure) {
buildClosure(self)
}
}

struct DeathStar : CustomStringConvertible {

let x: Double
let y: Double
let z: Double

init?(builder: DeathStarBuilder) {

if let x = builder.x, let y = builder.y, let z = builder.z {
self.x = x
self.y = y
self.z = z
} else {
return nil
}
}

var description:String {
return "Death Star at (x:\(x) y:\(y) z:\(z))"
}
}
```

### 用法

```swift
let empire = DeathStarBuilder { builder in
builder.x = 0.1
builder.y = 0.2
builder.z = 0.3
}

let deathStar = DeathStar(builder:empire)
```

🏭 工厂方法(Factory Method)
-----------------------

定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

### 示例:

```swift
protocol CurrencyDescribing {
var symbol: String { get }
var code: String { get }
}

final class Euro: CurrencyDescribing {
var symbol: String {
return "€"
}

var code: String {
return "EUR"
}
}

final class UnitedStatesDolar: CurrencyDescribing {
var symbol: String {
return "$"
}

var code: String {
return "USD"
}
}

enum Country {
case unitedStates
case spain
case uk
case greece
}

enum CurrencyFactory {
static func currency(for country: Country) -> CurrencyDescribing? {

switch country {
case .spain, .greece:
return Euro()
case .unitedStates:
return UnitedStatesDolar()
default:
return nil
}

}
}
```

### 用法

```swift
let noCurrencyCode = "No Currency Code Available"

CurrencyFactory.currency(for: .greece)?.code ?? noCurrencyCode
CurrencyFactory.currency(for: .spain)?.code ?? noCurrencyCode
CurrencyFactory.currency(for: .unitedStates)?.code ?? noCurrencyCode
CurrencyFactory.currency(for: .uk)?.code ?? noCurrencyCode
```

🔂 单态(Monostate)
------------

单态模式是实现单一共享的另一种方法。不同于单例模式,它通过完全不同的机制,在不限制构造方法的情况下实现单一共享特性。
因此,在这种情况下,单态会将状态保存为静态,而不是将整个实例保存为单例。
[单例和单态 - Robert C. Martin](http://staff.cs.utu.fi/~jounsmed/doos_06/material/SingletonAndMonostate.pdf)

### 示例:

```swift
class Settings {

enum Theme {
case `default`
case old
case new
}

private static var theme: Theme?

var currentTheme: Theme {
get { Settings.theme ?? .default }
set(newTheme) { Settings.theme = newTheme }
}
}
```

### 用法:

```swift
import SwiftUI

// 改变主题
let settings = Settings() // 开始使用主题 .old
settings.currentTheme = .new // 改变主题为 .new

// 界面一
let screenColor: Color = Settings().currentTheme == .old ? .gray : .white

// 界面二
let screenTitle: String = Settings().currentTheme == .old ? "Itunes Connect" : "App Store Connect"
```

🃏 原型(Prototype)
--------------

通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。

### 示例:

```swift
class MoonWorker {

let name: String
var health: Int = 100

init(name: String) {
self.name = name
}

func clone() -> MoonWorker {
return MoonWorker(name: name)
}
}
```

### 用法

```swift
let prototype = MoonWorker(name: "Sam Bell")

var bell1 = prototype.clone()
bell1.health = 12

var bell2 = prototype.clone()
bell2.health = 23

var bell3 = prototype.clone()
bell3.health = 0
```

💍 单例(Singleton)
--------------

单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为

### 示例:

```swift
final class ElonMusk {

static let shared = ElonMusk()

private init() {
// Private initialization to ensure just one instance is created.
}
}
```

### 用法

```swift
let elon = ElonMusk.shared // There is only one Elon Musk folks.
```

结构型模式(Structural)
====================

> 在软件工程中结构型模式是设计模式,借由一以贯之的方式来了解元件间的关系,以简化设计。
>
>**来源:** [维基百科](https://zh.wikipedia.org/wiki/%E7%B5%90%E6%A7%8B%E5%9E%8B%E6%A8%A1%E5%BC%8F)

🔌 适配器(Adapter)
--------------

适配器模式有时候也称包装样式或者包装(wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

### 示例:

```swift
protocol NewDeathStarSuperLaserAiming {
var angleV: Double { get }
var angleH: Double { get }
}
```

**被适配者**

```swift
struct OldDeathStarSuperlaserTarget {
let angleHorizontal: Float
let angleVertical: Float

init(angleHorizontal: Float, angleVertical: Float) {
self.angleHorizontal = angleHorizontal
self.angleVertical = angleVertical
}
}
```

**适配器**

```swift
struct NewDeathStarSuperlaserTarget: NewDeathStarSuperLaserAiming {

private let target: OldDeathStarSuperlaserTarget

var angleV: Double {
return Double(target.angleVertical)
}

var angleH: Double {
return Double(target.angleHorizontal)
}

init(_ target: OldDeathStarSuperlaserTarget) {
self.target = target
}
}
```

### 用法

```swift
let target = OldDeathStarSuperlaserTarget(angleHorizontal: 14.0, angleVertical: 12.0)
let newFormat = NewDeathStarSuperlaserTarget(target)

newFormat.angleH
newFormat.angleV
```

🌉 桥接(Bridge)
-----------

桥接模式将抽象部分与实现部分分离,使它们都可以独立的变化。

### 示例:

```swift
protocol Switch {
var appliance: Appliance { get set }
func turnOn()
}

protocol Appliance {
func run()
}

final class RemoteControl: Switch {
var appliance: Appliance

func turnOn() {
self.appliance.run()
}

init(appliance: Appliance) {
self.appliance = appliance
}
}

final class TV: Appliance {
func run() {
print("tv turned on");
}
}

final class VacuumCleaner: Appliance {
func run() {
print("vacuum cleaner turned on")
}
}
```

### 用法

```swift
let tvRemoteControl = RemoteControl(appliance: TV())
tvRemoteControl.turnOn()

let fancyVacuumCleanerRemoteControl = RemoteControl(appliance: VacuumCleaner())
fancyVacuumCleanerRemoteControl.turnOn()
```

🌿 组合(Composite)
--------------

将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

### 示例:

组件(Component)

```swift
protocol Shape {
func draw(fillColor: String)
}
```

叶子节点(Leafs)

```swift
final class Square: Shape {
func draw(fillColor: String) {
print("Drawing a Square with color \(fillColor)")
}
}

final class Circle: Shape {
func draw(fillColor: String) {
print("Drawing a circle with color \(fillColor)")
}
}

```

组合

```swift
final class Whiteboard: Shape {

private lazy var shapes = [Shape]()

init(_ shapes: Shape...) {
self.shapes = shapes
}

func draw(fillColor: String) {
for shape in self.shapes {
shape.draw(fillColor: fillColor)
}
}
}
```

### 用法

```swift
var whiteboard = Whiteboard(Circle(), Square())
whiteboard.draw(fillColor: "Red")
```

🍧 修饰(Decorator)
--------------

修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。
就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。

### 示例:

```swift
protocol CostHaving {
var cost: Double { get }
}

protocol IngredientsHaving {
var ingredients: [String] { get }
}

typealias BeverageDataHaving = CostHaving & IngredientsHaving

struct SimpleCoffee: BeverageDataHaving {
let cost: Double = 1.0
let ingredients = ["Water", "Coffee"]
}

protocol BeverageHaving: BeverageDataHaving {
var beverage: BeverageDataHaving { get }
}

struct Milk: BeverageHaving {

let beverage: BeverageDataHaving

var cost: Double {
return beverage.cost + 0.5
}

var ingredients: [String] {
return beverage.ingredients + ["Milk"]
}
}

struct WhipCoffee: BeverageHaving {

let beverage: BeverageDataHaving

var cost: Double {
return beverage.cost + 0.5
}

var ingredients: [String] {
return beverage.ingredients + ["Whip"]
}
}
```

### 用法

```swift
var someCoffee: BeverageDataHaving = SimpleCoffee()
print("Cost: \(someCoffee.cost); Ingredients: \(someCoffee.ingredients)")
someCoffee = Milk(beverage: someCoffee)
print("Cost: \(someCoffee.cost); Ingredients: \(someCoffee.ingredients)")
someCoffee = WhipCoffee(beverage: someCoffee)
print("Cost: \(someCoffee.cost); Ingredients: \(someCoffee.ingredients)")
```

🎁 外观(Facade)
-----------

外观模式为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。

### 示例:

```swift
final class Defaults {

private let defaults: UserDefaults

init(defaults: UserDefaults = .standard) {
self.defaults = defaults
}

subscript(key: String) -> String? {
get {
return defaults.string(forKey: key)
}

set {
defaults.set(newValue, forKey: key)
}
}
}
```

### 用法

```swift
let storage = Defaults()

// Store
storage["Bishop"] = "Disconnect me. I’d rather be nothing"

// Read
storage["Bishop"]
```

🍃 享元(Flyweight)
--------------

使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。

### 示例:

```swift
// 特指咖啡生成的对象会是享元
struct SpecialityCoffee {
let origin: String
}

protocol CoffeeSearching {
func search(origin: String) -> SpecialityCoffee?
}

// 菜单充当特制咖啡享元对象的工厂和缓存
final class Menu: CoffeeSearching {

private var coffeeAvailable: [String: SpecialityCoffee] = [:]

func search(origin: String) -> SpecialityCoffee? {
if coffeeAvailable.index(forKey: origin) == nil {
coffeeAvailable[origin] = SpecialityCoffee(origin: origin)
}

return coffeeAvailable[origin]
}
}

final class CoffeeShop {
private var orders: [Int: SpecialityCoffee] = [:]
private let menu: CoffeeSearching

init(menu: CoffeeSearching) {
self.menu = menu
}

func takeOrder(origin: String, table: Int) {
orders[table] = menu.search(origin: origin)
}

func serve() {
for (table, origin) in orders {
print("Serving \(origin) to table \(table)")
}
}
}
```

### 用法

```swift
let coffeeShop = CoffeeShop(menu: Menu())

coffeeShop.takeOrder(origin: "Yirgacheffe, Ethiopia", table: 1)
coffeeShop.takeOrder(origin: "Buziraguhindwa, Burundi", table: 3)

coffeeShop.serve()
```

☔ 保护代理模式(Protection Proxy)
------------------

在代理模式中,创建一个类代表另一个底层类的功能。
保护代理用于限制访问。

### 示例:

```swift
protocol DoorOpening {
func open(doors: String) -> String
}

final class HAL9000: DoorOpening {
func open(doors: String) -> String {
return ("HAL9000: Affirmative, Dave. I read you. Opened \(doors).")
}
}

final class CurrentComputer: DoorOpening {
private var computer: HAL9000!

func authenticate(password: String) -> Bool {

guard password == "pass" else {
return false
}

computer = HAL9000()

return true
}

func open(doors: String) -> String {

guard computer != nil else {
return "Access Denied. I'm afraid I can't do that."
}

return computer.open(doors: doors)
}
}
```

### 用法

```swift
let computer = CurrentComputer()
let podBay = "Pod Bay Doors"

computer.open(doors: podBay)

computer.authenticate(password: "pass")
computer.open(doors: podBay)
```

🍬 虚拟代理(Virtual Proxy)
----------------

在代理模式中,创建一个类代表另一个底层类的功能。
虚拟代理用于对象的需时加载。

### 示例:

```swift
protocol HEVSuitMedicalAid {
func administerMorphine() -> String
}

final class HEVSuit: HEVSuitMedicalAid {
func administerMorphine() -> String {
return "Morphine administered."
}
}

final class HEVSuitHumanInterface: HEVSuitMedicalAid {

lazy private var physicalSuit: HEVSuit = HEVSuit()

func administerMorphine() -> String {
return physicalSuit.administerMorphine()
}
}
```

### 用法

```swift
let humanInterface = HEVSuitHumanInterface()
humanInterface.administerMorphine()
```

Info
====

📖 Descriptions from: [Gang of Four Design Patterns Reference Sheet](http://www.blackwasp.co.uk/GangOfFour.aspx)