├── .gitignore ├── 01-Simple_Factory_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 02-Factory_Method_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 03-Abstract_Factory_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 04-Strategy_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 05-Decorator_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 06-Proxy_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 07-Prototype_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 08-Template_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 09-Facade_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 10-Builder_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 11-Observer_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 12-Delegate_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 13-State_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 14-Adapter_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 15-Memento_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 16-Composite_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 17-Iterator_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 18-Singleton_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 19-Bridge_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 20-Command_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 21-Chain_of_Responsibility_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 22-Mediator_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 23-Flyweight_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 24-Interpreter_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── 25-Visitor_Pattern.playground ├── Contents.swift └── contents.xcplayground ├── LICENSE ├── README.md └── README_CN.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /01-Simple_Factory_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol Operator { 8 | var nums: (Double, Double) { get set } 9 | 10 | func getResult() -> Double? 11 | } 12 | 13 | // 遵守协议 14 | struct Addition: Operator { 15 | var nums = (0.0, 0.0) 16 | 17 | func getResult() -> Double? { 18 | return nums.0 + nums.1 19 | } 20 | } 21 | 22 | struct Subtraction: Operator { 23 | var nums = (0.0, 0.0) 24 | 25 | func getResult() -> Double? { 26 | return nums.0 - nums.1 27 | } 28 | } 29 | 30 | struct Multiplication: Operator { 31 | var nums = (0.0, 0.0) 32 | 33 | func getResult() -> Double? { 34 | return nums.0 * nums.1 35 | } 36 | } 37 | 38 | struct Division: Operator { 39 | var nums = (0.0, 0.0) 40 | 41 | func getResult() -> Double? { 42 | guard nums.1 != 0 else { 43 | return nil 44 | } 45 | 46 | return nums.0 / nums.1 47 | } 48 | } 49 | 50 | // 操作符枚举 51 | enum Operators { 52 | case addition, subtraction, multiplication, division 53 | } 54 | 55 | // 工厂 56 | struct OperatorFactory { 57 | static func calculateForOperator(_ opt: Operators) -> Operator { 58 | switch opt { 59 | case .addition: 60 | return Addition() 61 | case .subtraction: 62 | return Subtraction() 63 | case .multiplication: 64 | return Multiplication() 65 | case .division: 66 | return Division() 67 | } 68 | } 69 | } 70 | 71 | var testDivision = OperatorFactory.calculateForOperator(.division) 72 | testDivision.nums = (1, 0) 73 | print(testDivision.getResult() ?? "Error") 74 | 75 | var testAddition = OperatorFactory.calculateForOperator(.addition) 76 | testAddition.nums = (1, 1) 77 | print(testAddition.getResult() ?? "Error") 78 | -------------------------------------------------------------------------------- /01-Simple_Factory_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /02-Factory_Method_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol Operator { 8 | var nums: (Double, Double) { get set } 9 | 10 | func getResult() -> Double? 11 | // 工厂 12 | static func createOperation() -> Operator 13 | } 14 | 15 | // 遵守协议 16 | struct Addition: Operator { 17 | static func createOperation() -> Operator { 18 | return Addition() 19 | } 20 | 21 | var nums = (0.0, 0.0) 22 | 23 | func getResult() -> Double? { 24 | return nums.0 + nums.1 25 | } 26 | } 27 | 28 | struct Subtraction: Operator { 29 | static func createOperation() -> Operator { 30 | return Subtraction() 31 | } 32 | 33 | var nums = (0.0, 0.0) 34 | 35 | func getResult() -> Double? { 36 | return nums.0 - nums.1 37 | } 38 | } 39 | 40 | struct Multiplication: Operator { 41 | static func createOperation() -> Operator { 42 | return Multiplication() 43 | } 44 | 45 | var nums = (0.0, 0.0) 46 | 47 | func getResult() -> Double? { 48 | return nums.0 * nums.1 49 | } 50 | } 51 | 52 | struct Division: Operator { 53 | static func createOperation() -> Operator { 54 | return Division() 55 | } 56 | 57 | var nums = (0.0, 0.0) 58 | 59 | func getResult() -> Double? { 60 | guard nums.1 != 0 else { 61 | return nil 62 | } 63 | return nums.0 / nums.1 64 | } 65 | } 66 | 67 | var testAddition = Addition.createOperation() 68 | testAddition.nums = (2, 3) 69 | print(testAddition.getResult() ?? "Error") 70 | 71 | var testDivision = Division.createOperation() 72 | testDivision.nums = (2, 0) 73 | print(testDivision.getResult() ?? "Error") 74 | -------------------------------------------------------------------------------- /02-Factory_Method_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /03-Abstract_Factory_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | struct User {} 7 | 8 | // 协议 9 | protocol UserProtocol { 10 | func insert(_ user: User) 11 | func get(_ id: Int) -> User 12 | } 13 | 14 | struct SQLServerUser: UserProtocol { 15 | func insert(_ user: User) { 16 | print("\(#function) user") 17 | } 18 | 19 | func get(_ id: Int) -> User { 20 | print("\(#function) user") 21 | return User() 22 | } 23 | } 24 | 25 | struct AccessUser: UserProtocol { 26 | func insert(_ user: User) { 27 | print("\(#function) user") 28 | } 29 | 30 | func get(_ id: Int) -> User { 31 | print("\(#function) user") 32 | return User() 33 | } 34 | } 35 | 36 | struct Department {} 37 | 38 | // 协议 39 | protocol DepartmentProtocol { 40 | func insert(_ department: Department) 41 | func get(_ id: Int) -> Department 42 | } 43 | 44 | struct SQLServerDepartment: DepartmentProtocol { 45 | func insert(_ department: Department) { 46 | print("\(#function) department") 47 | } 48 | 49 | func get(_ id: Int) -> Department { 50 | print("\(#function) department") 51 | return Department() 52 | } 53 | } 54 | 55 | struct AccessDepartment: DepartmentProtocol { 56 | func insert(_ department: Department) { 57 | print("\(#function) department") 58 | } 59 | 60 | func get(_ id: Int) -> Department { 61 | print("\(#function) department") 62 | return Department() 63 | } 64 | } 65 | 66 | // 工厂协议 67 | protocol FactoryProtocol { 68 | func createUser() -> UserProtocol 69 | func createDepartment() -> DepartmentProtocol 70 | } 71 | 72 | struct SqlServerFactory: FactoryProtocol { 73 | func createUser() -> UserProtocol { 74 | return SQLServerUser() 75 | } 76 | 77 | func createDepartment() -> DepartmentProtocol { 78 | return SQLServerDepartment() 79 | } 80 | } 81 | 82 | struct AccessFactory: FactoryProtocol { 83 | func createUser() -> UserProtocol { 84 | return AccessUser() 85 | } 86 | 87 | func createDepartment() -> DepartmentProtocol { 88 | return AccessDepartment() 89 | } 90 | } 91 | 92 | let userA = User() 93 | let departmentA = Department() 94 | 95 | let factory: FactoryProtocol 96 | factory = AccessFactory() 97 | 98 | let iuA = factory.createUser() 99 | iuA.insert(userA) 100 | iuA.get(1) 101 | 102 | let idA = factory.createDepartment() 103 | idA.insert(departmentA) 104 | idA.get(1) 105 | 106 | // 简单工厂 + 抽象工厂 107 | enum Database { 108 | case sqlServer, access 109 | } 110 | 111 | struct DataAccess { 112 | static var database: Database = .access 113 | 114 | static func createUser() -> UserProtocol { 115 | switch database { 116 | case .sqlServer: 117 | return SQLServerUser() 118 | case .access: 119 | return AccessUser() 120 | } 121 | } 122 | 123 | static func createDepartment() -> DepartmentProtocol { 124 | switch database { 125 | case .sqlServer: 126 | return SQLServerDepartment() 127 | case .access: 128 | return AccessDepartment() 129 | } 130 | } 131 | } 132 | 133 | let userB = User() 134 | let departmentB = Department() 135 | 136 | DataAccess.database = .sqlServer 137 | let iuB = DataAccess.createUser() 138 | iuB.insert(userB) 139 | iuB.get(1) 140 | 141 | let idB = DataAccess.createDepartment() 142 | idB.insert(departmentB) 143 | idB.get(1) 144 | -------------------------------------------------------------------------------- /03-Abstract_Factory_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04-Strategy_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol CashSuper { 8 | func acceptCash(_ money: Double) -> Double 9 | } 10 | 11 | // 普通 12 | struct CashNormal: CashSuper { 13 | func acceptCash(_ money: Double) -> Double { 14 | return money 15 | } 16 | } 17 | 18 | // 打折 19 | struct CashRebate: CashSuper { 20 | let monenyRebate: Double 21 | 22 | init(_ moneyRebate: Double) { 23 | self.monenyRebate = moneyRebate 24 | } 25 | 26 | func acceptCash(_ money: Double) -> Double { 27 | return money * monenyRebate 28 | } 29 | } 30 | 31 | // 满减 32 | struct CashReturn: CashSuper { 33 | let moneyCondition: Double 34 | let moneyReturn: Double 35 | 36 | init(_ moneyCondition: Double, _ moneyReturn: Double) { 37 | self.moneyCondition = moneyCondition 38 | self.moneyReturn = moneyReturn 39 | } 40 | 41 | func acceptCash(_ money: Double) -> Double { 42 | var result = money 43 | 44 | if result >= moneyCondition { 45 | result = money - Double(Int(money / moneyCondition)) * moneyReturn 46 | } 47 | return result 48 | } 49 | } 50 | 51 | // 优惠方式 52 | enum DiscountWays { 53 | case byDefault, twentyPersentOff, every300Get100Return 54 | } 55 | 56 | struct CashContext { 57 | private let cs: CashSuper 58 | 59 | init(_ cs: CashSuper) { 60 | self.cs = cs 61 | } 62 | 63 | func getResult(_ money: Double) -> Double { 64 | return cs.acceptCash(money) 65 | } 66 | } 67 | 68 | struct CashContextWithSimpleFactoryPattern { 69 | private let cs: CashSuper 70 | 71 | init(_ type: DiscountWays) { 72 | switch type { 73 | case .twentyPersentOff: 74 | cs = CashRebate(0.8) 75 | case .every300Get100Return: 76 | cs = CashReturn(300, 100) 77 | default: 78 | cs = CashNormal() 79 | } 80 | } 81 | 82 | func getResult(_ money: Double) -> Double { 83 | return cs.acceptCash(money) 84 | } 85 | } 86 | 87 | // 策略模式 88 | var type = DiscountWays.twentyPersentOff 89 | var cc: CashContext 90 | switch type { 91 | case .twentyPersentOff: 92 | cc = CashContext(CashRebate(0.8)) 93 | case .every300Get100Return: 94 | cc = CashContext(CashReturn(300, 100)) 95 | default: 96 | cc = CashContext(CashNormal()) 97 | } 98 | cc.getResult(200) 99 | 100 | // 策略模式与简单工厂模式结合 101 | var cs = CashContextWithSimpleFactoryPattern(.byDefault) 102 | cs.getResult(100) 103 | 104 | cs = CashContextWithSimpleFactoryPattern(.twentyPersentOff) 105 | cs.getResult(200.5) 106 | 107 | cs = CashContextWithSimpleFactoryPattern(.every300Get100Return) 108 | cs.getResult(650) 109 | -------------------------------------------------------------------------------- /04-Strategy_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /05-Decorator_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol Person { 8 | func show() 9 | } 10 | 11 | // 遵守协议 12 | struct Boy: Person { 13 | var name = "" 14 | 15 | init() {} 16 | init(_ name: String) { 17 | self.name = name 18 | } 19 | 20 | func show() { 21 | print("\(name)") 22 | } 23 | } 24 | 25 | // 饰物遵守协议 26 | class Finery: Person { 27 | var component: Person 28 | 29 | init(_ component: Person) { 30 | self.component = component 31 | } 32 | 33 | func show() { 34 | component.show() 35 | } 36 | } 37 | 38 | // 继承 39 | class TShirt: Finery { 40 | override func show() { 41 | print("T 恤", separator: "", terminator: " + ") 42 | super.show() 43 | } 44 | } 45 | 46 | // 继承 47 | class ChineseTunicSuit: Finery { 48 | override func show() { 49 | print("中山装", separator: "", terminator: " + ") 50 | super.show() 51 | } 52 | } 53 | 54 | var b = Boy("Kingcos") 55 | 56 | // 按顺序装饰 57 | let tShirtA = TShirt(b) 58 | let chineseTunicSuitA = ChineseTunicSuit(tShirtA) 59 | 60 | chineseTunicSuitA.show() 61 | 62 | let chineseTunicSuitB = ChineseTunicSuit(b) 63 | let tShirtB = TShirt(chineseTunicSuitB) 64 | 65 | tShirtB.show() 66 | -------------------------------------------------------------------------------- /05-Decorator_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /06-Proxy_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol GiveGift { 8 | func giveDolls() 9 | func giveFlowers() 10 | func giveChocolate() 11 | } 12 | 13 | // 被追求者 14 | struct SchoolGirl { 15 | var name = "" 16 | } 17 | 18 | // 追求者 19 | struct Pursuit: GiveGift { 20 | var mm = SchoolGirl() 21 | 22 | func giveDolls() { 23 | print("追求者送 \(mm.name) 洋娃娃") 24 | } 25 | 26 | func giveFlowers() { 27 | print("追求者送 \(mm.name) 鲜花") 28 | } 29 | 30 | func giveChocolate() { 31 | print("追求者送 \(mm.name) 巧克力") 32 | } 33 | } 34 | 35 | // 代理 36 | struct Proxy: GiveGift { 37 | var gg: Pursuit 38 | 39 | init(_ mm: SchoolGirl) { 40 | self.gg = Pursuit(mm: mm) 41 | } 42 | 43 | func giveDolls() { 44 | gg.giveDolls() 45 | } 46 | 47 | func giveFlowers() { 48 | gg.giveFlowers() 49 | } 50 | 51 | func giveChocolate() { 52 | gg.giveChocolate() 53 | } 54 | } 55 | 56 | var girl = SchoolGirl() 57 | girl.name = "Jane" 58 | 59 | let p = Proxy(girl) 60 | 61 | // 代理替追求者执行 62 | p.giveDolls() 63 | p.giveFlowers() 64 | p.giveChocolate() 65 | -------------------------------------------------------------------------------- /06-Proxy_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /07-Prototype_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 工作经历 7 | class WorkExperience { 8 | var workDate = "" 9 | var company = "" 10 | 11 | init() {} 12 | 13 | init(_ workDate: String, _ company: String) { 14 | self.workDate = workDate 15 | self.company = company 16 | } 17 | 18 | // 克隆 19 | func clone() -> WorkExperience { 20 | return WorkExperience(workDate, company) 21 | } 22 | } 23 | 24 | // 简历 25 | class Resume { 26 | private var name = "" 27 | private var sex = "" 28 | private var age = "" 29 | 30 | var work: WorkExperience 31 | 32 | init(_ name: String) { 33 | self.name = name 34 | self.work = WorkExperience() 35 | } 36 | 37 | init(_ work: WorkExperience) { 38 | self.work = work.clone() 39 | } 40 | 41 | func setPersonalInfo(_ sex: String, _ age: String) { 42 | self.sex = sex 43 | self.age = age 44 | } 45 | 46 | func setWorkExperience(_ workDate: String, _ company: String) { 47 | work.workDate = workDate 48 | work.company = company 49 | } 50 | 51 | func display() { 52 | print("个人信息:\(name) \(sex) \(age)") 53 | print("工作经历:\(work.workDate) \(work.company)") 54 | } 55 | 56 | // 克隆 57 | func clone() -> Resume { 58 | let resume = Resume(work) 59 | resume.name = name 60 | resume.sex = sex 61 | resume.age = age 62 | return resume 63 | } 64 | } 65 | 66 | let resumeA = Resume("Kingcos") 67 | resumeA.setPersonalInfo("Boy", "21") 68 | resumeA.setWorkExperience("2016.8", "School") 69 | 70 | let resumeB = resumeA.clone() 71 | resumeB.setWorkExperience("2016.9-2016.12", "School") 72 | 73 | let resumeC = resumeA.clone() 74 | resumeC.setWorkExperience("2014-2018", "University") 75 | 76 | // 深拷贝 77 | resumeA.display() 78 | resumeB.display() 79 | resumeC.display() 80 | -------------------------------------------------------------------------------- /07-Prototype_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /08-Template_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 考试协议 7 | protocol Exam { 8 | func questionA() 9 | func questionB() 10 | func questionC() 11 | 12 | func answerA() -> String 13 | func answerB() -> String 14 | func answerC() -> String 15 | } 16 | 17 | // 试卷 18 | class TestPaper: Exam { 19 | // 模版方法 20 | func questionA() { 21 | print("Q&A 1 \(answerA())") 22 | } 23 | 24 | func questionB() { 25 | print("Q&A 2 \(answerB())") 26 | } 27 | 28 | func questionC() { 29 | print("Q&A 3 \(answerC())") 30 | } 31 | 32 | func answerA() -> String { 33 | return "" 34 | } 35 | 36 | func answerB() -> String { 37 | return "" 38 | } 39 | 40 | func answerC() -> String { 41 | return "" 42 | } 43 | } 44 | 45 | // A 的试卷 46 | class TestPaperA: TestPaper { 47 | override func answerA() -> String { 48 | return "A" 49 | } 50 | 51 | override func answerB() -> String { 52 | return "B" 53 | } 54 | 55 | override func answerC() -> String { 56 | return "C" 57 | } 58 | } 59 | 60 | // B 的试卷 61 | class TestPaperB: TestPaper { 62 | override func answerA() -> String { 63 | return "C" 64 | } 65 | 66 | override func answerB() -> String { 67 | return "B" 68 | } 69 | 70 | override func answerC() -> String { 71 | return "A" 72 | } 73 | } 74 | 75 | let pA = TestPaperA() 76 | 77 | pA.questionA() 78 | pA.questionB() 79 | pA.questionC() 80 | 81 | let pB = TestPaperB() 82 | 83 | pB.questionA() 84 | pB.questionB() 85 | pB.questionC() 86 | -------------------------------------------------------------------------------- /08-Template_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /09-Facade_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 股票协议 7 | protocol Stock { 8 | func sell() 9 | func buy() 10 | } 11 | 12 | // 股票 A 13 | struct StockA: Stock { 14 | func sell() { 15 | print("StockA 卖出") 16 | } 17 | 18 | func buy() { 19 | print("StockA 买入") 20 | } 21 | } 22 | 23 | // 股票 B 24 | struct StockB: Stock { 25 | func sell() { 26 | print("StockB 卖出") 27 | } 28 | 29 | func buy() { 30 | print("StockB 买入") 31 | } 32 | } 33 | 34 | // 股票 C 35 | struct StockC: Stock { 36 | func sell() { 37 | print("StockC 卖出") 38 | } 39 | 40 | func buy() { 41 | print("StockC 买入") 42 | } 43 | } 44 | 45 | // 基金 46 | struct Fund { 47 | var stockA: StockA 48 | var stockB: StockB 49 | var stockC: StockC 50 | 51 | init() { 52 | stockA = StockA() 53 | stockB = StockB() 54 | stockC = StockC() 55 | } 56 | 57 | func sellAB() { 58 | stockA.sell() 59 | stockB.sell() 60 | } 61 | 62 | func buyBC() { 63 | stockB.buy() 64 | stockC.buy() 65 | } 66 | 67 | func sellABC() { 68 | stockA.sell() 69 | stockB.sell() 70 | stockC.sell() 71 | } 72 | 73 | func buyABC() { 74 | stockA.buy() 75 | stockB.buy() 76 | stockC.buy() 77 | } 78 | } 79 | 80 | let fundManager = Fund() 81 | fundManager.buyBC() 82 | fundManager.buyABC() 83 | fundManager.sellAB() 84 | -------------------------------------------------------------------------------- /09-Facade_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /10-Builder_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol PersonBuilder { 8 | func buildHead() 9 | func buildBody() 10 | func buildLeftArm() 11 | func buildRightArm() 12 | func buildLeftLeg() 13 | func buildRightLeg() 14 | 15 | func createPerson() 16 | } 17 | 18 | // ThinPerson 遵守协议 19 | struct ThinPerson: PersonBuilder { 20 | func createPerson() { 21 | buildHead() 22 | buildBody() 23 | buildLeftArm() 24 | buildRightArm() 25 | buildLeftLeg() 26 | buildRightLeg() 27 | } 28 | 29 | func buildHead() { 30 | print(#function) 31 | } 32 | 33 | func buildBody() { 34 | print(#function) 35 | } 36 | 37 | func buildLeftArm() { 38 | print(#function) 39 | } 40 | 41 | func buildRightArm() { 42 | print(#function) 43 | } 44 | 45 | func buildLeftLeg() { 46 | print(#function) 47 | } 48 | 49 | func buildRightLeg() { 50 | print(#function) 51 | } 52 | } 53 | 54 | // FatPerson 遵守协议 55 | struct FatPerson: PersonBuilder { 56 | func createPerson() { 57 | buildHead() 58 | buildBody() 59 | buildLeftArm() 60 | buildRightArm() 61 | buildLeftLeg() 62 | buildRightLeg() 63 | } 64 | 65 | func buildHead() { 66 | print(#function) 67 | } 68 | 69 | func buildBody() { 70 | print(#function) 71 | } 72 | 73 | func buildLeftArm() { 74 | print(#function) 75 | } 76 | 77 | func buildRightArm() { 78 | print(#function) 79 | } 80 | 81 | func buildLeftLeg() { 82 | print(#function) 83 | } 84 | 85 | func buildRightLeg() { 86 | print(#function) 87 | } 88 | } 89 | 90 | let pA = ThinPerson() 91 | pA.createPerson() 92 | 93 | let pB = FatPerson() 94 | pB.createPerson() 95 | -------------------------------------------------------------------------------- /10-Builder_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /11-Observer_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol Subject { 8 | func attach(_ observer: Observer) 9 | func detach(_ observer: Observer) 10 | func notify() 11 | } 12 | 13 | // 观察者 14 | class Observer: Hashable { 15 | var name: String 16 | var sub: Subject 17 | 18 | var hashValue: Int { 19 | return "\(name)".hashValue 20 | } 21 | 22 | static func ==(l: Observer, r: Observer) -> Bool { 23 | return l.hashValue == r.hashValue 24 | } 25 | 26 | init(_ name: String, _ sub: Subject) { 27 | self.name = name 28 | self.sub = sub 29 | } 30 | 31 | func update() {} 32 | } 33 | 34 | class Boss: Subject { 35 | var observers = Set() 36 | 37 | func attach(_ observer: Observer) { 38 | observers.insert(observer) 39 | } 40 | 41 | func detach(_ observer: Observer) { 42 | observers.remove(observer) 43 | } 44 | 45 | func notify() { 46 | for o in observers { 47 | o.update() 48 | } 49 | } 50 | } 51 | 52 | // 看股票 53 | class StockObserver: Observer { 54 | override func update() { 55 | print("\(name) 关闭股票,继续工作") 56 | } 57 | } 58 | 59 | // 看 NBA 60 | class NBAObserver: Observer { 61 | override func update() { 62 | print("\(name) 关闭 NBA,继续工作") 63 | } 64 | } 65 | 66 | let boss = Boss() 67 | let colleagueA = StockObserver("A", boss) 68 | let colleagueB = NBAObserver("B", boss) 69 | 70 | // 添加通知者 71 | boss.attach(colleagueA) 72 | boss.attach(colleagueB) 73 | 74 | // 移除通知者 75 | boss.detach(colleagueA) 76 | 77 | // 发出通知 78 | boss.notify() 79 | -------------------------------------------------------------------------------- /11-Observer_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /12-Delegate_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | protocol Subject { 8 | var updates: [() -> ()] { get } 9 | func notify() 10 | } 11 | 12 | class Boss: Subject { 13 | var updates: [() -> ()] = [] 14 | 15 | func notify() { 16 | for i in 0.. 2 | 3 | 4 | -------------------------------------------------------------------------------- /13-State_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 工作类 7 | class Work { 8 | var hour = 0 9 | var state: State = ForenoonState() 10 | var isFinish = false 11 | 12 | func writeProgram() { 13 | state.writeProgram(self) 14 | } 15 | } 16 | 17 | // 协议 18 | protocol State { 19 | func writeProgram(_ work: Work) 20 | } 21 | 22 | // 上午状态 23 | struct ForenoonState: State { 24 | func writeProgram(_ work: Work) { 25 | if work.hour < 12 { 26 | print("\(work.hour) 上午") 27 | } else { 28 | work.state = NoonState() 29 | work.writeProgram() 30 | } 31 | } 32 | } 33 | 34 | // 中午状态 35 | struct NoonState: State { 36 | func writeProgram(_ work: Work) { 37 | if work.hour < 13 { 38 | print("\(work.hour) 中午") 39 | } else { 40 | work.state = AfternoonState() 41 | work.writeProgram() 42 | } 43 | } 44 | } 45 | 46 | // 下午状态 47 | struct AfternoonState: State { 48 | func writeProgram(_ work: Work) { 49 | if work.hour < 17 { 50 | print("\(work.hour) 下午") 51 | } else { 52 | work.state = EveningState() 53 | work.writeProgram() 54 | } 55 | } 56 | } 57 | 58 | // 晚上状态 59 | struct EveningState: State { 60 | func writeProgram(_ work: Work) { 61 | if work.isFinish { 62 | work.state = RestState() 63 | work.writeProgram() 64 | } else { 65 | if work.hour < 21 { 66 | print("\(work.hour) 晚上") 67 | } else { 68 | work.state = SleepingState() 69 | work.writeProgram() 70 | } 71 | } 72 | } 73 | } 74 | 75 | // 睡觉状态 76 | struct SleepingState: State { 77 | func writeProgram(_ work: Work) { 78 | print("\(work.hour) 睡觉") 79 | } 80 | } 81 | 82 | // 休息状态 83 | struct RestState: State { 84 | func writeProgram(_ work: Work) { 85 | print("\(work.hour) 休息") 86 | } 87 | } 88 | 89 | let work = Work() 90 | 91 | for i in stride(from: 9, through: 22, by: 1) { 92 | if i == 17 { 93 | work.isFinish = true 94 | } 95 | work.hour = i 96 | work.writeProgram() 97 | } 98 | -------------------------------------------------------------------------------- /13-State_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /14-Adapter_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-3-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 球员协议 7 | protocol Player { 8 | var name: String { get } 9 | 10 | func attack() 11 | func defense() 12 | } 13 | 14 | // 前锋 15 | struct Forwards: Player { 16 | var name: String 17 | 18 | func attack() { 19 | print("前锋 \(name) 进攻") 20 | } 21 | 22 | func defense() { 23 | print("前锋 \(name) 防守") 24 | } 25 | } 26 | 27 | // 中锋 28 | struct Center: Player { 29 | var name: String 30 | 31 | func attack() { 32 | print("中锋 \(name) 进攻") 33 | } 34 | 35 | func defense() { 36 | print("中锋 \(name) 防守") 37 | } 38 | } 39 | 40 | // 后卫 41 | struct Guards: Player { 42 | var name: String 43 | 44 | func attack() { 45 | print("后卫 \(name) 进攻") 46 | } 47 | 48 | func defense() { 49 | print("后卫 \(name) 防守") 50 | } 51 | } 52 | 53 | // 外籍中锋 54 | struct ForeignCenter { 55 | var name: String 56 | 57 | func jinGong() { 58 | print("外籍中锋 \(name) 进攻") 59 | } 60 | 61 | func fangShou() { 62 | print("外籍中锋 \(name) 防守") 63 | } 64 | } 65 | 66 | // 翻译 67 | struct Translator: Player { 68 | var name: String 69 | var foreignCenter: ForeignCenter 70 | 71 | init(name: String) { 72 | self.name = name 73 | self.foreignCenter = ForeignCenter(name: name) 74 | } 75 | 76 | func attack() { 77 | foreignCenter.jinGong() 78 | } 79 | 80 | func defense() { 81 | foreignCenter.fangShou() 82 | } 83 | } 84 | 85 | let playerA = Forwards(name: "Shane Battier") 86 | playerA.attack() 87 | 88 | let playerB = Guards(name: "Tracy McGrady") 89 | playerB.defense() 90 | 91 | let playerC = Translator(name: "Ming Yao") 92 | playerC.attack() 93 | playerC.defense() 94 | -------------------------------------------------------------------------------- /14-Adapter_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /15-Memento_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 游戏角色 7 | struct GameRole { 8 | var vit: Int 9 | var atk: Int 10 | var def: Int 11 | 12 | init() { 13 | vit = 100 14 | atk = 100 15 | def = 100 16 | } 17 | 18 | func stateDisplay() { 19 | print("生命值:\(vit)") 20 | print("攻击力:\(atk)") 21 | print("防御力:\(def)") 22 | } 23 | 24 | func saveState() -> RoleStateMemento { 25 | return RoleStateMemento(vit: vit, atk: atk, def: def) 26 | } 27 | 28 | mutating func recoverState(_ memento: RoleStateMemento) { 29 | vit = memento.vit 30 | atk = memento.atk 31 | def = memento.def 32 | } 33 | 34 | mutating func fight() { 35 | vit = 0 36 | atk = 0 37 | def = 0 38 | } 39 | } 40 | 41 | // 游戏状态备忘 42 | struct RoleStateMemento { 43 | var vit: Int 44 | var atk: Int 45 | var def: Int 46 | } 47 | 48 | // 游戏状态管理 49 | struct RoleStateCaretaker { 50 | var memento: RoleStateMemento 51 | } 52 | 53 | var p = GameRole() 54 | p.stateDisplay() 55 | 56 | let stateAdmin = RoleStateCaretaker(memento: p.saveState()) 57 | 58 | p.fight() 59 | p.stateDisplay() 60 | 61 | p.recoverState(stateAdmin.memento) 62 | p.stateDisplay() 63 | -------------------------------------------------------------------------------- /15-Memento_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /16-Composite_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 协议 7 | class Company: Hashable { 8 | var name: String 9 | 10 | init(_ name: String) { 11 | self.name = name 12 | } 13 | 14 | var hashValue: Int { 15 | return "\(name)".hashValue 16 | } 17 | 18 | static func ==(l: Company, r: Company) -> Bool { 19 | return l.hashValue == r.hashValue 20 | } 21 | 22 | func add(_ c: Company) {} 23 | func remove(_ c: Company) {} 24 | func display(_ depth: Int) {} 25 | func lineOfDuty() {} 26 | } 27 | 28 | // 具体公司 29 | class ConcreteCompany: Company { 30 | var children = Set() 31 | 32 | override func add(_ c: Company) { 33 | children.insert(c) 34 | } 35 | 36 | override func remove(_ c: Company) { 37 | children.remove(c) 38 | } 39 | 40 | override func display(_ depth: Int) { 41 | for _ in 0.. 2 | 3 | 4 | -------------------------------------------------------------------------------- /17-Iterator_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // Crowd 序列 7 | struct Crowd: Sequence { 8 | let end: Int 9 | 10 | func makeIterator() -> CrowdIterator { 11 | return CrowdIterator(self) 12 | } 13 | } 14 | 15 | // Crowd 迭代器 16 | struct CrowdIterator: IteratorProtocol { 17 | var crowd: Crowd 18 | var times: Int 19 | 20 | init(_ crowd: Crowd) { 21 | self.crowd = crowd 22 | times = crowd.end - 1 23 | } 24 | 25 | mutating func next() -> Int? { 26 | let nextNumber = crowd.end - times 27 | guard nextNumber <= crowd.end else { return nil } 28 | 29 | times -= 1 30 | return nextNumber 31 | } 32 | } 33 | 34 | // 迭代 35 | for i in Crowd(end: 10) { 36 | print(i) 37 | } 38 | -------------------------------------------------------------------------------- /17-Iterator_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /18-Singleton_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 单例 7 | class SingletonClass { 8 | var foo = 0 9 | 10 | // 静态常量 11 | static let shared = SingletonClass() 12 | 13 | private init() {} 14 | } 15 | 16 | let i = SingletonClass.shared 17 | i.foo = 100 18 | 19 | let j = SingletonClass.shared 20 | print(j.foo) 21 | -------------------------------------------------------------------------------- /18-Singleton_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /19-Bridge_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 手机软件协议 7 | protocol HandsetSoft { 8 | func run() 9 | } 10 | 11 | // 手机游戏 12 | struct HandsetGame: HandsetSoft { 13 | func run() { 14 | print("Run GAME") 15 | } 16 | } 17 | 18 | // 手机通讯录 19 | struct HandsetAddressList: HandsetSoft { 20 | func run() { 21 | print("Run ADDRESS LIST") 22 | } 23 | } 24 | 25 | // 手机品牌协议 26 | protocol HandsetBrand { 27 | var soft: HandsetSoft { get } 28 | 29 | func run() 30 | } 31 | 32 | // 品牌 A 33 | struct HandsetBrandA: HandsetBrand { 34 | var soft: HandsetSoft 35 | 36 | func run() { 37 | soft.run() 38 | } 39 | } 40 | 41 | // 品牌 B 42 | struct HandsetBrandB: HandsetBrand { 43 | var soft: HandsetSoft 44 | 45 | func run() { 46 | soft.run() 47 | } 48 | } 49 | 50 | var hs = HandsetBrandA(soft: HandsetGame()) 51 | hs.run() 52 | 53 | hs.soft = HandsetAddressList() 54 | hs.run() 55 | -------------------------------------------------------------------------------- /19-Bridge_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /20-Command_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 烧烤 7 | struct Barbecuer { 8 | enum BBQ: String { 9 | case mutton = "烤羊肉串" 10 | case chickenWing = "烤鸡翅" 11 | } 12 | 13 | var state: BBQ = .mutton 14 | 15 | mutating func bakeMutton() { 16 | state = .mutton 17 | print("\(state.rawValue)") 18 | } 19 | 20 | mutating func backChickenWing() { 21 | state = .chickenWing 22 | print("\(state.rawValue)") 23 | } 24 | } 25 | 26 | // 命令 27 | class Command: Hashable { 28 | var bbq: Barbecuer 29 | 30 | init(_ bbq: Barbecuer) { 31 | self.bbq = bbq 32 | } 33 | 34 | var hashValue: Int { 35 | return bbq.state.hashValue 36 | } 37 | 38 | static func ==(l: Command, r: Command) -> Bool { 39 | return l.hashValue == r.hashValue 40 | } 41 | 42 | func executeCommand() {} 43 | } 44 | 45 | // 烤羊肉串命令 46 | class BakeMuttonCommand: Command { 47 | override init(_ bbq: Barbecuer) { 48 | super.init(bbq) 49 | self.bbq.state = .mutton 50 | } 51 | 52 | override func executeCommand() { 53 | bbq.bakeMutton() 54 | } 55 | } 56 | 57 | // 烤鸡翅命令 58 | class BakeChickenWingCommand: Command { 59 | override init(_ bbq: Barbecuer) { 60 | super.init(bbq) 61 | self.bbq.state = .chickenWing 62 | } 63 | 64 | override func executeCommand() { 65 | bbq.backChickenWing() 66 | } 67 | } 68 | 69 | // 服务员 70 | struct Waiter { 71 | var cmdSet = Set() 72 | 73 | mutating func setOrder(_ command: Command) { 74 | if command.bbq.state == .chickenWing { 75 | print("没有鸡翅了,请点别的烧烤") 76 | } else { 77 | cmdSet.insert(command) 78 | print("增加订单:\(command.bbq.state.rawValue)") 79 | } 80 | } 81 | 82 | mutating func removeOrder(_ command: Command) { 83 | cmdSet.remove(command) 84 | print("取消订单:\(command.bbq.state.rawValue)") 85 | } 86 | 87 | func notify() { 88 | for command in cmdSet { 89 | command.executeCommand() 90 | } 91 | } 92 | } 93 | 94 | let bbq = Barbecuer() 95 | let muttonA = BakeMuttonCommand(bbq) 96 | let muttonB = BakeMuttonCommand(bbq) 97 | let chickenWingA = BakeChickenWingCommand(bbq) 98 | 99 | var waiter = Waiter() 100 | 101 | waiter.setOrder(muttonA) 102 | waiter.setOrder(muttonB) 103 | waiter.setOrder(chickenWingA) 104 | -------------------------------------------------------------------------------- /20-Command_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /21-Chain_of_Responsibility_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 请求 7 | struct Request { 8 | enum RequestType: String { 9 | case leave = "请假" 10 | case salary = "加薪" 11 | } 12 | 13 | var requestType: RequestType 14 | var requestContent: String 15 | var number: Int 16 | } 17 | 18 | // 经理协议 19 | protocol Manager { 20 | var name: String { get } 21 | var superior: Manager? { get } 22 | 23 | func requestApplications(_ request: Request) 24 | } 25 | 26 | // 普通经理 27 | struct CommonManager: Manager { 28 | var name: String 29 | var superior: Manager? 30 | 31 | func requestApplications(_ request: Request) { 32 | if request.requestType == .leave && request.number <= 2 { 33 | print("CommonManager 批准:\(request.requestType.rawValue) \(request.number) 天") 34 | } else { 35 | superior!.requestApplications(request) 36 | } 37 | } 38 | } 39 | 40 | // 总监 41 | struct Majordomo: Manager { 42 | var name: String 43 | var superior: Manager? 44 | 45 | func requestApplications(_ request: Request) { 46 | if request.requestType == .leave && request.number <= 5 { 47 | print("Majordomo 批准:\(request.requestType.rawValue) \(request.number) 天") 48 | } else { 49 | superior!.requestApplications(request) 50 | } 51 | } 52 | } 53 | 54 | // 总经理 55 | struct GeneralManager: Manager { 56 | var name: String 57 | var superior: Manager? 58 | 59 | init(_ name: String) { 60 | self.name = name 61 | } 62 | 63 | func requestApplications(_ request: Request) { 64 | if request.requestType == .leave { 65 | print("GeneralManager 批准:\(request.requestType.rawValue) \(request.number) 天") 66 | } else if request.requestType == .salary 67 | && request.number <= 500 { 68 | print("GeneralManager 批准:\(request.requestType.rawValue) \(request.number) 元") 69 | } else if request.requestType == .salary 70 | && request.number > 500 { 71 | print("GeneralManager 考虑考虑") 72 | } 73 | } 74 | } 75 | 76 | let generalMng = GeneralManager("总经理") 77 | let majordomo = Majordomo(name: "总监", superior: generalMng) 78 | let commonMng = CommonManager(name: "普通经理", superior: majordomo) 79 | 80 | let rqA = Request(requestType: .leave, requestContent: "小菜请假", number: 1) 81 | commonMng.requestApplications(rqA) 82 | 83 | let rqB = Request(requestType: .leave, requestContent: "小菜请假", number: 4) 84 | commonMng.requestApplications(rqB) 85 | 86 | let rqC = Request(requestType: .salary, requestContent: "小菜加薪", number: 200) 87 | commonMng.requestApplications(rqC) 88 | 89 | let rqD = Request(requestType: .salary, requestContent: "小菜加薪", number: 1000) 90 | commonMng.requestApplications(rqD) 91 | -------------------------------------------------------------------------------- /21-Chain_of_Responsibility_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /22-Mediator_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 国家协议 7 | protocol Country { 8 | var mediator: UnitedNations { get } 9 | } 10 | 11 | // 联合国协议 12 | protocol UnitedNations { 13 | func declare(_ message: String, _ colleague: Country) 14 | } 15 | 16 | // A 国 17 | class CountryA: Country { 18 | var mediator: UnitedNations 19 | 20 | init(_ mediator: UnitedNations) { 21 | self.mediator = mediator 22 | } 23 | 24 | func declare(_ message: String) { 25 | mediator.declare(message, self) 26 | } 27 | 28 | func getMessage(_ message: String) { 29 | print("A 国获得消息:\(message)") 30 | } 31 | } 32 | 33 | // B 国 34 | class CountryB: Country { 35 | var mediator: UnitedNations 36 | 37 | init(_ mediator: UnitedNations) { 38 | self.mediator = mediator 39 | } 40 | 41 | func declare(_ message: String) { 42 | mediator.declare(message, self) 43 | } 44 | 45 | func getMessage(_ message: String) { 46 | print("B 国获得消息:\(message)") 47 | } 48 | } 49 | 50 | // 联合国安理会 51 | class UnitedNationsSecurityCouncil: UnitedNations { 52 | var cA: CountryA? 53 | var cB: CountryB? 54 | 55 | func declare(_ message: String, _ colleague: Country) { 56 | if type(of: colleague) == type(of: cA!) { 57 | cB!.getMessage(message) 58 | } else { 59 | cA!.getMessage(message) 60 | } 61 | } 62 | } 63 | 64 | var unsc = UnitedNationsSecurityCouncil() 65 | let cA = CountryA(unsc) 66 | let cB = CountryB(unsc) 67 | 68 | unsc.cA = cA 69 | unsc.cB = cB 70 | 71 | cA.declare("Message A") 72 | cB.declare("Message B") 73 | -------------------------------------------------------------------------------- /22-Mediator_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /23-Flyweight_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 网站协议 7 | protocol Website { 8 | func use() 9 | } 10 | 11 | // 具体网站 12 | struct ConcreteWebsite: Website { 13 | var name: String 14 | 15 | func use() { 16 | print("name: \(name)") 17 | } 18 | } 19 | 20 | // 网站工厂 21 | struct WebsiteFactory { 22 | var flyweights = Dictionary() 23 | 24 | mutating func getWebsiteCategory(_ key: String) -> Website { 25 | if !flyweights.keys.contains(key) { 26 | flyweights[key] = ConcreteWebsite(name: key) 27 | } 28 | return flyweights[key]! 29 | } 30 | 31 | func getWebsiteCount() -> Int { 32 | return flyweights.count 33 | } 34 | } 35 | 36 | var f = WebsiteFactory() 37 | 38 | let wsA = f.getWebsiteCategory("产品展示") 39 | wsA.use() 40 | 41 | let wsB = f.getWebsiteCategory("产品展示") 42 | wsB.use() 43 | 44 | let wsC = f.getWebsiteCategory("博客") 45 | wsC.use() 46 | 47 | let wsD = f.getWebsiteCategory("博客") 48 | wsD.use() 49 | 50 | let wsE = f.getWebsiteCategory("博客") 51 | wsE.use() 52 | 53 | print("分类数:\(f.getWebsiteCount())") 54 | -------------------------------------------------------------------------------- /23-Flyweight_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /24-Interpreter_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 演奏内容 7 | struct PlayContext { 8 | var text: String 9 | } 10 | 11 | // 表达式 12 | class Expression { 13 | func interpret(_ context: inout PlayContext) { 14 | if context.text.count != 0 { 15 | let rangeA = Range(uncheckedBounds: (context.text.index(after: context.text.startIndex), context.text.index(context.text.startIndex, offsetBy: 2))) 16 | 17 | let playKey = String(context.text[rangeA]) 18 | let index = context.text.index(context.text.startIndex, offsetBy: 3) 19 | context.text = String(context.text[index...]) 20 | 21 | let rangeB = Range(uncheckedBounds: (context.text.characters.startIndex, context.text.characters.index(of: " ")!)) 22 | let playValue = context.text[rangeB] 23 | 24 | context.text = context.text.substring(from: context.text.characters.index(of: " ")!) 25 | execute(playKey, value: Double(playValue)!) 26 | } 27 | } 28 | 29 | func execute(_ key: String, value: Double) {} 30 | } 31 | 32 | // 音符 33 | class Note: Expression { 34 | override func execute(_ key: String, value: Double) { 35 | var note: String 36 | 37 | switch key { 38 | case "C": 39 | note = "1" 40 | case "D": 41 | note = "2" 42 | case "E": 43 | note = "3" 44 | case "F": 45 | note = "4" 46 | case "G": 47 | note = "5" 48 | case "A": 49 | note = "6" 50 | default: 51 | note = "" 52 | } 53 | 54 | print("\(note)", separator: "", terminator: " ") 55 | } 56 | } 57 | 58 | // 音域 59 | class Scale: Expression { 60 | override func execute(_ key: String, value: Double) { 61 | var scale: String 62 | 63 | switch value { 64 | case 1: 65 | scale = "低音" 66 | case 2: 67 | scale = "中音" 68 | case 3: 69 | scale = "高音" 70 | default: 71 | scale = "" 72 | } 73 | 74 | print("\(scale)", separator: "", terminator: " ") 75 | } 76 | } 77 | 78 | // 音速 79 | class Speed: Expression { 80 | override func execute(_ key: String, value: Double) { 81 | var speed: String 82 | 83 | if value >= 1000 { 84 | speed = "高速" 85 | } else if value < 500 { 86 | speed = "低速" 87 | } else { 88 | speed = "中速" 89 | } 90 | 91 | print("\(speed)", separator: "", terminator: " ") 92 | } 93 | } 94 | 95 | var context = PlayContext(text: 96 | " T 400 O 2 E 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 " 97 | ) 98 | 99 | while context.text.characters.count > 1 { 100 | let range = Range(uncheckedBounds: (context.text.index(after: context.text.startIndex), context.text.index(context.text.startIndex, offsetBy: 2))) 101 | let str = context.text.substring(with: range) 102 | 103 | var expression = Expression() 104 | 105 | switch str { 106 | case "T": 107 | expression = Speed() 108 | case "O": 109 | expression = Scale() 110 | case "C", "D", "E", "F", "G", "A", "B", "P": 111 | expression = Note() 112 | default: break 113 | } 114 | expression.interpret(&context) 115 | } 116 | -------------------------------------------------------------------------------- /24-Interpreter_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /25-Visitor_Pattern.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // Powered by https://maimieng.com from https://github.com/kingcos/Swift-X-Design-Patterns 3 | 4 | import UIKit 5 | 6 | // 人 7 | class Person: Hashable { 8 | var name: String 9 | 10 | init(_ name: String) { 11 | self.name = name 12 | } 13 | 14 | var hashValue: Int { 15 | return name.hashValue 16 | } 17 | 18 | static func ==(l: Person, r: Person) -> Bool { 19 | return l.hashValue == r.hashValue 20 | } 21 | 22 | func accept(_ visitor: Action) {} 23 | } 24 | 25 | // 男 26 | class Man: Person { 27 | override func accept(_ visitor: Action) { 28 | visitor.getManConclusion(self) 29 | } 30 | } 31 | 32 | // 女 33 | class Woman: Person { 34 | override func accept(_ visitor: Action) { 35 | visitor.getWomanConclusion(self) 36 | } 37 | } 38 | 39 | // 行为 协议 40 | protocol Action { 41 | func getManConclusion(_ elemA: Man) 42 | func getWomanConclusion(_ elemB: Woman) 43 | } 44 | 45 | // 成功 46 | struct Success: Action { 47 | func getManConclusion(_ elemA: Man) { 48 | print("\(type(of: elemA)) \(type(of: self))") 49 | } 50 | 51 | func getWomanConclusion(_ elemB: Woman) { 52 | print("\(type(of: elemB)) \(type(of: self))") 53 | } 54 | } 55 | 56 | // 失败 57 | struct Failing: Action { 58 | func getManConclusion(_ elemA: Man) { 59 | print("\(type(of: elemA)) \(type(of: self))") 60 | } 61 | 62 | func getWomanConclusion(_ elemB: Woman) { 63 | print("\(type(of: elemB)) \(type(of: self))") 64 | } 65 | } 66 | 67 | // 恋爱 68 | struct Amativeness: Action { 69 | func getManConclusion(_ elemA: Man) { 70 | print("\(type(of: elemA)) \(type(of: self))") 71 | } 72 | 73 | func getWomanConclusion(_ elemB: Woman) { 74 | print("\(type(of: elemB)) \(type(of: self))") 75 | } 76 | } 77 | 78 | // 结婚 79 | struct Marriage: Action { 80 | func getManConclusion(_ elemA: Man) { 81 | print("\(type(of: elemA)) \(type(of: self))") 82 | } 83 | 84 | func getWomanConclusion(_ elemB: Woman) { 85 | print("\(type(of: elemB)) \(type(of: self))") 86 | } 87 | } 88 | 89 | // 对象结构 90 | struct ObjectStructure { 91 | var elements = Set() 92 | 93 | mutating func attach(_ element: Person) { 94 | elements.insert(element) 95 | } 96 | 97 | mutating func detach(_ element: Person) { 98 | elements.remove(element) 99 | } 100 | 101 | func display(_ visitor: Action) { 102 | for e in elements { 103 | e.accept(visitor) 104 | } 105 | } 106 | } 107 | 108 | var os = ObjectStructure() 109 | os.attach(Man("Kingcos")) 110 | os.attach(Woman("Jane")) 111 | 112 | let success = Success() 113 | os.display(success) 114 | 115 | let failing = Success() 116 | os.display(failing) 117 | 118 | let loving = Amativeness() 119 | os.display(loving) 120 | 121 | let marriage = Marriage() 122 | os.display(marriage) 123 | -------------------------------------------------------------------------------- /25-Visitor_Pattern.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swift-X-Design-Patterns 2 | 3 | Design patterns implemented in Swift X. 4 | 5 | [![GitHub license](https://img.shields.io/github/license/kingcos/Swift-X-Design-Patterns.svg?style=for-the-badge)](https://github.com/kingcos/Swift-X-Design-Patterns/blob/master/LICENSE) [![Swift 4.2](https://img.shields.io/badge/Swift-4.2-orange.svg?style=for-the-badge)](https://github.com/apple/swift/releases/tag/swift-4.2-RELEASE) 6 | 7 | English | [中文](README_CN.md) 8 | 9 | ## Introduction 10 | 11 | Hello! 12 | 13 | Please forgive my poor English. I am a college student who loved Swift programming language and iOS development from China. This repository is to demonstrate design patterns in Swift X (`let X = 4.2`). As we know, Swift is an awesome programming language around the world and it's growth so rapidly. These design patterns will be updated with my new articles in Chinese. 14 | 15 | If my code did help you, would you please give me a Star 🌟? It will courage me to move on! Thank you! 16 | 17 | **No doubt that I would made some mistakes in it, if you find some bugs, please issue me. I am looking forward to discuss with you about the magic of Swift! Thank you!** 18 | 19 | - [Perspective - GitHub](https://github.com/kingcos/Perspective) 20 | 21 | ## Contents 22 | 23 | 1. [Simple Factory Pattern](01-Simple_Factory_Pattern.playground/Contents.swift) 24 | 2. [Factory Method Pattern](02-Factory_Method_Pattern.playground/Contents.swift) 25 | 3. [Abstract Factory Pattern](03-Abstract_Factory_Pattern.playground/Contents.swift) 26 | 4. [Strategy Pattern](04-Strategy_Pattern.playground/Contents.swift) 27 | 5. [Decorator Pattern](05-Decorator_Pattern.playground/Contents.swift) 28 | 6. [Proxy Pattern](06-Proxy_Pattern.playground/Contents.swift) 29 | 7. [Prototype Pattern](07-Prototype_Pattern.playground/Contents.swift) 30 | 8. [Template Pattern](08-Template_Pattern.playground/Contents.swift) 31 | 9. [Facade Pattern](09-Facade_Pattern.playground/Contents.swift) 32 | 10. [Builder Pattern](10-Builder_Pattern.playground/Contents.swift) 33 | 11. [Observer Pattern](11-Observer_Pattern.playground/Contents.swift) 34 | 12. [Delegate Pattern](12-Delegate_Pattern.playground/Contents.swift) 35 | 13. [State Pattern](13-State_Pattern.playground/Contents.swift) 36 | 14. [Adapter Pattern](14-Adapter_Pattern.playground/Contents.swift) 37 | 15. [Memento Pattern](15-Memento_Pattern.playground/Contents.swift) 38 | 16. [Composite Pattern](16-Composite_Pattern.playground/Contents.swift) 39 | 17. [Iterator Pattern](17-Iterator_Pattern.playground/Contents.swift) 40 | 18. [Singleton Pattern](18-Singleton_Pattern.playground/Contents.swift) 41 | 19. [Bridge Pattern](19-Bridge_Pattern.playground/Contents.swift) 42 | 20. [Command Pattern](20-Command_Pattern.playground/Contents.swift) 43 | 21. [Chain of Responsibility Pattern](21-Chain_of_Responsibility_Pattern.playground/Contents.swift) 44 | 22. [Mediator Pattern](22-Mediator_Pattern.playground/Contents.swift) 45 | 23. [Flyweight Pattern](23-Flyweight_Pattern.playground/Contents.swift) 46 | 24. [Interpreter Pattern](24-Interpreter_Pattern.playground/Contents.swift) 47 | 25. [Visitor Pattern](25-Visitor_Pattern.playground/Contents.swift) 48 | 49 | ## Reference 50 | 51 | - [大话设计模式](https://book.douban.com/subject/2334288/) 52 | - [ochococo/Design-Patterns-In-Swift](https://github.com/ochococo/Design-Patterns-In-Swift) 53 | 54 | ## License 55 | 56 | - Apache-2.0 57 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | # Swift-X-Design-Patterns 2 | 3 | 使用 Swift X 实现的设计模式。 4 | 5 | [![GitHub license](https://img.shields.io/github/license/kingcos/Swift-X-Design-Patterns.svg?style=for-the-badge)](https://github.com/kingcos/Swift-X-Design-Patterns/blob/master/LICENSE) [![Swift 4.2](https://img.shields.io/badge/Swift-4.2-orange.svg?style=for-the-badge)](https://github.com/apple/swift/releases/tag/swift-4.2-RELEASE) 6 | 7 | [English](README.md) | 中文 8 | 9 | ## 前言 10 | 11 | 最近在看《大话设计模式》一书,深感设计模式的重要性,因此将 Swift X(`let X = 4.2`)的实现版本发布于此,方便自己学习并与大家交流。 12 | 13 | 由于设计模式较多,且个个之间并非完全独立,有许多思想是相通的,我将每个设计模式单独为一个 playground 文件,内部的代码规范、命名规则我将尽力遵守,总体顺序、思想、命名参考《大话设计模式》。 14 | 15 | 本仓库的更新将跟随笔记同步发布,暂定个小目标:将书中的所有设计模式实现。笔记发布于简书和个人博客,同时投稿掘金,如果确有帮助到您,您可以根据需要点个喜欢 ❤️,加个 Star 🌟,那就再好不过啦。 16 | 17 | **由于能力有限,虽在不断学习,但不免有错误,希望您能在 GitHub 中提出 Issue 或者评论告诉我,我都会细心研究,改正错误。谢谢!** 18 | 19 | - [Perspective - GitHub](https://github.com/kingcos/Perspective) 20 | 21 | ## 目录 22 | 23 | 1. [简单工厂模式(Simple Factory Pattern)](01-Simple_Factory_Pattern.playground/Contents.swift) 24 | 2. [工厂方法模式(Factory Method Pattern)](02-Factory_Method_Pattern.playground/Contents.swift) 25 | 3. [抽象工厂模式(Abstract Factory Pattern)](03-Abstract_Factory_Pattern.playground/Contents.swift) 26 | 4. [策略模式(Strategy Pattern)](04-Strategy_Pattern.playground/Contents.swift) 27 | 5. [装饰模式(Decorator Pattern)](05-Decorator_Pattern.playground/Contents.swift) 28 | 6. [代理模式(Proxy Pattern)](06-Proxy_Pattern.playground/Contents.swift) 29 | 7. [原型模式(Prototype Pattern)](07-Prototype_Pattern.playground/Contents.swift) 30 | 8. [模版模式(Template Pattern)](08-Template_Pattern.playground/Contents.swift) 31 | 9. [外观模式(Facade Pattern)](09-Facade_Pattern.playground/Contents.swift) 32 | 10. [建造者模式(Builder Pattern)](10-Builder_Pattern.playground/Contents.swift) 33 | 11. [观察者模式(Observer Pattern)](11-Observer_Pattern.playground/Contents.swift) 34 | 12. [委托模式(Delegate Pattern)](12-Delegate_Pattern.playground/Contents.swift) 35 | 13. [状态模式(State Pattern)](13-State_Pattern.playground/Contents.swift) 36 | 14. [适配器模式(Adapter Pattern)](14-Adapter_Pattern.playground/Contents.swift) 37 | 15. [备忘录模式(Memento Pattern)](15-Memento_Pattern.playground/Contents.swift) 38 | 16. [组合模式(Composite Pattern)](16-Composite_Pattern.playground/Contents.swift) 39 | 17. [迭代器模式(Iterator Pattern)](17-Iterator_Pattern.playground/Contents.swift) 40 | 18. [单例模式(Singleton Pattern)](18-Singleton_Pattern.playground/Contents.swift) 41 | 19. [桥接模式(Bridge Pattern)](19-Bridge_Pattern.playground/Contents.swift) 42 | 20. [命令模式(Command Pattern)](20-Command_Pattern.playground/Contents.swift) 43 | 21. [职责链模式(Chain of Responsibility Pattern)](21-Chain_of_Responsibility_Pattern.playground/Contents.swift) 44 | 22. [中介者模式(Mediator Pattern)](22-Mediator_Pattern.playground/Contents.swift) 45 | 23. [享元模式(Flyweight Pattern)](23-Flyweight_Pattern.playground/Contents.swift) 46 | 24. [解释器模式(Interpreter Pattern)](24-Interpreter_Pattern.playground/Contents.swift) 47 | 25. [访问者模式(Visitor Pattern)](25-Visitor_Pattern.playground/Contents.swift) 48 | 49 | ## 文章 50 | 51 | - [Swift 中的值类型与引用类型](http://www.jianshu.com/p/ba12b64f6350) 52 | - [Swift 中的字符串截取](http://www.jianshu.com/p/94310202ba1b) 53 | 54 | ## 参考资料 55 | 56 | - [大话设计模式](https://book.douban.com/subject/2334288/) 57 | - [ochococo/Design-Patterns-In-Swift](https://github.com/ochococo/Design-Patterns-In-Swift) 58 | 59 | ## 许可 60 | 61 | - Apache-2.0 62 | --------------------------------------------------------------------------------