{"id":15038065,"url":"https://github.com/vamshiiitbhu14/designpatternsinswift","last_synced_at":"2025-06-17T01:03:21.479Z","repository":{"id":201839873,"uuid":"156999377","full_name":"VamshiIITBHU14/DesignPatternsInSwift","owner":"VamshiIITBHU14","description":"This repository contains all the code from my book 'Design Patterns in Swift', live at https://www.amazon.com/dp/B07FYXHBKZ. All code written in Swift4. Do give a star if you like the work.","archived":false,"fork":false,"pushed_at":"2018-11-12T11:09:32.000Z","size":603,"stargazers_count":335,"open_issues_count":0,"forks_count":43,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-06-17T01:03:21.102Z","etag":null,"topics":["coding-practices","computer-science","designpatterns","gang-of-four","swift4"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/VamshiIITBHU14.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-11-10T16:29:22.000Z","updated_at":"2025-03-19T15:53:49.000Z","dependencies_parsed_at":"2024-02-17T22:31:38.061Z","dependency_job_id":null,"html_url":"https://github.com/VamshiIITBHU14/DesignPatternsInSwift","commit_stats":null,"previous_names":["vamshiiitbhu14/designpatternsinswift"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/VamshiIITBHU14/DesignPatternsInSwift","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VamshiIITBHU14%2FDesignPatternsInSwift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VamshiIITBHU14%2FDesignPatternsInSwift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VamshiIITBHU14%2FDesignPatternsInSwift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VamshiIITBHU14%2FDesignPatternsInSwift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/VamshiIITBHU14","download_url":"https://codeload.github.com/VamshiIITBHU14/DesignPatternsInSwift/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VamshiIITBHU14%2FDesignPatternsInSwift/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260269419,"owners_count":22983642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coding-practices","computer-science","designpatterns","gang-of-four","swift4"],"created_at":"2024-09-24T20:36:57.514Z","updated_at":"2025-06-17T01:03:21.440Z","avatar_url":"https://github.com/VamshiIITBHU14.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DesignPatternsInSwift\nThis repository contains all the code from my book 'Design Patterns in Swift', live at https://www.amazon.com/dp/B07FYXHBKZ. All code written in Swift4. Do give a star if you like the work.\n\nPersonally, cricket is something that I understand in and out. I can almost relate anything under the sun to a situation in cricket (okay, that’s a bit of an exaggeration).\nSo, I decided, instead of using different contexts for each of the design pattern examples, I would be using cricketing terms for all the examples I would be coding. I believe cricket is a very simple game, and even for those who do not follow the game, it should not be a big effort to relate to the cricketing terms.\n\nThat’s when I decided instead of just letting the code reside on my Mac, I would put a little more effort to take it to book form. That’s how this book was born, and I am sure your understanding on design patterns will be enhanced by the time you finish coding these examples.\n\nI would suggest you code the examples (not copy-paste, but type each and every line of the code) in your Xcode playground and see the results for yourself. Then imagine a\nscenario where you would apply such a design pattern, and code an example for yourself.\nI believe that’s how coding is learned. Happy learning!\n\nThere are **28 design patterns** divided into **SOLID, Creational, Structural, Behavioral** categories. You can take code from each of the swift files and run in Xcode playground to see the output.\n\n**1) SOLID - Open Closed Principle : **\n\nDefinition:\n\nSingle responsibility principle says a class should have one, and only one, reason to change. Every class should be responsible for a single part of the functionality, and that responsibility should be entirely encapsulated by the class. This makes your software easier to implement and prevents unexpected side-effects of future changes.\n\nUsage:\n\nLet us design an imaginary operation system for a Cricket tournament. For the sake of simplicity, let us have two major operations. A TeamRegister class which helps for checking-in and checking-out cricketers. A TeamConveyance class which is used to drop the players from hotel to stadium and pick them up from stadium after the match is over.\n\nEvery class is assigned its own responsibility and they will be responsible only for that action.\n\n```swift\nimport UIKit\nimport Foundation\n \nclass TeamRegister : CustomStringConvertible{\n    \n    var teamMembers = [String]()\n    var memberCount = 0\n    \n    func checkInGuest (_ name : String) -\u003e Int{\n        \n        memberCount += 1\n        teamMembers.append(\"\\(memberCount) - \\(name)\")\n        return memberCount - 1\n        \n    }\n    \n    func checkOutGuest (_ index : Int) {\n        teamMembers.remove(at: index)\n    }\n    \n    var description: String{\n        return teamMembers.joined(separator: \"\\n\")\n    }\n}\n```\n\nTeamRegister class conforms to CustomStringConvertible. It has two variables defined, an array named teamMembers of type String and memberCount of type Integer.\n\nWe also define two methods. checkInGuest method takes the guest name as parameter of type String and appends the guest to teamMembers array and returns array count.\n\ncheckOutGuest takes index of type Integer as parameter and removes the guest from register.\n\n```swift\nclass TeamConveyance {\n    \n    func takePlayersToStadium(_ teamRegister : TeamRegister){\n        print(\"Taking players \\n \\(teamRegister.description) \\n to the Stadium\")\n    }\n    \n    func dropPlayersBackAtHotel(){\n        print(\"Dropping all the players back at Hotel\")\n    } \n}\n```\n\nTeamConveyance class has two responsibilites majorly. takePlayersToStadium takes paramter of type TeamRegister and drops all the players at the stadium. dropPlayersBackAtHotel gets back all the players to hotel after the match is over. It is not concerned about anything else.\n\nLet us now write a function called main and see the code in action:\n\n```swift\nfunc main(){\n    let teamRegister = TeamRegister()\n    let player1 = teamRegister.checkInGuest(\"PlayerOne\")\n    let player2 = teamRegister.checkInGuest(\"PlayerTwo\")\n    \n    print(teamRegister)\n}\n \nmain()\n```\n\nWe take an instance of TeamRegister class and check-in few guests passing their names as parameters.\n \nOutput in the Xcode console:\n \n1 - PlayerOne\n2 - PlayerTwo\n\nLet us now check-out a guest and add one more guest to the team. Change the main function to :\n\n```swift\nfunc main(){\n    let teamRegister = TeamRegister()\n    let player1 = teamRegister.checkInGuest(\"PlayerOne\")\n    let player2 = teamRegister.checkInGuest(\"PlayerTwo\")\n    \n    print(teamRegister)\n    \n    teamRegister.checkOutGuest(1)\n    print(\"------------------------------------\")\n    print(teamRegister)\n    \n    let player3 = teamRegister.checkInGuest(\"PlayerThree\")\n \n    print(\"------------------------------------\")\n    print(teamRegister)\n}\n \nmain()\n```\n\nWe checked-out ‘PlayerTwo’ and then checked-in another guest named ‘PlayerThree’.\n \n \nOutput in the Xcode console:\n \n1 - PlayerOne\n2 - PlayerTwo\n\n1 - PlayerOne\n\n1 - PlayerOne\n3 - PlayerThree\n\n\nNow change the main method to following:\n \n```swift\nfunc main(){\n    let teamRegister = TeamRegister()\n    let player1 = teamRegister.checkInGuest(\"PlayerOne\")\n    let player2 = teamRegister.checkInGuest(\"PlayerTwo\")\n    \n    print(teamRegister)\n    \n    teamRegister.checkOutGuest(1)\n    print(\"------------------------------------\")\n    print(teamRegister)\n    \n    let player3 = teamRegister.checkInGuest(\"PlayerThree\")\n \n    print(\"------------------------------------\")\n    print(teamRegister)\n    \n    print(\"------------------------------------\")\n    let teamBus = TeamConveyance()\n    teamBus.takePlayersToStadium(teamRegister)\n    \n    print(\"-------Match Over ----------\")\n    teamBus.dropPlayersBackAtHotel()\n}\n \nmain()\n```\n\nWe are taking an instance of TeamConveyance to drop players at stadium and get them back at hotel after the match is over.\n \nOutput in the Xcode console:\n \n1 - PlayerOne\n2 - PlayerTwo\n\n1 - PlayerOne\n\n1 - PlayerOne\n3 - PlayerThree\n\nTaking players \n 1 - PlayerOne\n3 - PlayerThree \n to the Stadium\n\n-------Match Over ----------\nDropping all the players back at Hotel\n\n\n**2) SOLID - Single Responsibility Principle : **\n\nDefinition:\n\nOpen closed principle says one should be able to extend a class behavior without modifying it. As Robert C. Martin says, this principle is the foundation for building code that is maintainable and reusable.\n\nAny class following OCP should fulfill two criteria:\n\nOpen for extension: This ensures that the class behavior can be extended. In a real world scenario, requirements keep changing and in order for us to be able to accommodate those changes , classes should be open for extension so that they can behave in a new way.\n\nClosed for modification: Code inside the class is written in such a way that no one is allowed to modify the existing code under any circumstances.\n\nUsage:\n\nLet us consider an example where we have an array of cricketers’ profiles where each entity has the name of cricketer, his team and his specialisation as the attributes. Now we want to build a system where the client can apply filters on the data based on different criteria like team , role of the player etc. Let us see how we can use OCP to build this:\n\n```swift\nimport Foundation\nimport UIKit\n \nenum Team{\n    case india\n    case australia\n    case pakistan\n    case england\n}\n \nenum Role{\n    case batsman\n    case bowler\n    case allrounder\n}\n \n```\n\nEnumeration is a data type that allows us to define list of possible values. We define enums for the available names of the teams and roles of the cricketers.\n\n```swift\nclass Cricketer{\n    \n    var name:String\n    var team:Team\n    var role:Role\n    \n    init(_ name:String, _ team:Team, _ role:Role) {\n        self.name = name\n        self.team = team\n        self.role = role\n    }\n    \n}\n```\n\nWe then define a class called Cricketer which takes three parameters during its initialisation, name of type String, team of type Team and role of type Role.\n \nNow assume, one of the client requirements is to provide a filter of cricketers based on their team. \n\n```swift\nclass CricketerFilter{\n \n     func filterByTeam(_ cricketers:[Cricketer], _ team:Team) -\u003e [Cricketer]{\n        var filteredResults = [Cricketer]()\n        for item in cricketers{\n            if item.team == team{\n                filteredResults.append(item)\n            }\n        }\n        return filteredResults\n    }\n \n}\n```\n\nWe write a class called CricketerFilter and define a method filterByTeam to filter the player profiles based on their team. It takes an array of type Cricketer and team of type Team as parameters and returns a filtered array of type Cricketer. \n \nFor each cricketer in the given array, we check if his team is same as that of the given team for filter, add him to the filtered array. Let us see this code in action. Add the below code after CricketerFilter class.\n\n```swift\nfunc main(){\n    let dhoni = Cricketer(\"Dhoni\", .india, .batsman)\n    let kohli = Cricketer(\"Kohli\",  .india, .batsman)\n    let maxi = Cricketer(\"Maxwell\", .australia, .allrounder)\n    let smith = Cricketer(\"Smith\", .australia, .batsman)\n    let symo = Cricketer(\"Symonds\", .australia, .allrounder)\n    let broad = Cricketer(\"Broad\", .england, .bowler)\n    let ali  = Cricketer(\"Ali\", .pakistan, .batsman)\n    let stokes = Cricketer(\"Stokes\", .england, .allrounder)\n    \n    let cricketers = [dhoni, kohli, maxi, broad, ali, stokes ,smith, symo]\n    print(\" Indian Cricketers\")\n    let cricketerFilter = CricketerFilter()\n    for item in cricketerFilter.filterByTeam(cricketers, .india){\n        print(\" \\(item.name) belongs to Indian Team\")\n    }\n}\n \nmain()\n```\n\nOutput in the Xcode console:\n \n Indian Cricketers\n Dhoni belongs to Indian Team\n Kohli belongs to Indian Team\n \nAssume, after a few days, we got a new requirement to be able to filter by role of the cricketer and then to filter by both team and role at once. Our CricketerFilter class would look something like this:\n\n```swift\nclass CricketerFilter{\n \n    func filterByRole(_ cricketers:[Cricketer], _ role:Role) -\u003e [Cricketer]{\n        var filteredResults = [Cricketer]()\n        for item in cricketers{\n            if item.role == role{\n                filteredResults.append(item)\n            }\n        }\n        return filteredResults\n    }\n \n    func filterByTeam(_ cricketers:[Cricketer], _ team:Team) -\u003e [Cricketer]{\n        var filteredResults = [Cricketer]()\n        for item in cricketers{\n            if item.team == team{\n                filteredResults.append(item)\n            }\n        }\n        return filteredResults\n    }\n    \n    func filterByRoleAndTeam(_ cricketers:[Cricketer], _ role:Role, _ team:Team) -\u003e [Cricketer]{\n        var filteredResults = [Cricketer]()\n        for item in cricketers{\n            if item.role == role \u0026\u0026 item.team == team{\n                filteredResults.append(item)\n            }\n        }\n        return filteredResults\n    }\n \n}\n```\n\nThis logic is quite similar to filterByTeam method. Only that, for filterByRole, we check if the player’s role is same as that of given role. For filterByRoleAndTeam method, we use AND statement to check if the given condition is met.\n \nBut the OCP states that classes should be closed for modification and open for extension. But here we are clearly breaking this principle. Let us see how the same use-case can be served with the help of OCP.\n\n```swift\n//Conditions\nprotocol Condition{\n    associatedtype T\n    func isConditionMet(_ item: T) -\u003e Bool\n}\n```\n\nWe begin by defining a protocol called Condition which basically checks if a particular item satisfies some criteria. We have a function called isConditionMet which takes an item of generic type T and returns a boolean indicating whether the item meets the given criteria.\n\n```swift\nprotocol Filter\n{\n    associatedtype T\n    func filter\u003cCond: Condition\u003e(_ items: [T], _ cond: Cond) -\u003e [T]\n    where Cond.T == T;\n}\n```\n\nWe then define a protocol named Filter which has a function called filter which takes an array of items of generic type T and a condition of type Condition as parameters and returns the filtered array.\n \nWe now use the above generic type Filter to write conditions for role and team.\n\n```swift\nclass RoleCondition : Condition\n{\n    typealias T = Cricketer\n    let role: Role\n    init(_ role: Role)\n    {\n        self.role = role\n    }\n    \n    func isConditionMet(_ item: Cricketer) -\u003e Bool {\n        return item.role == role\n    }\n}\n \nclass TeamCondition : Condition\n{\n    typealias T = Cricketer\n    let team: Team\n    init(_ team: Team)\n    {\n        self.team = team\n    }\n    \n    func isConditionMet(_ item: Cricketer) -\u003e Bool {\n        return item.team == team\n    }\n}\n\n```\n\nIn each of the methods, we write the logic of isConditionMet protocol method to see if the item meets the criteria and return a boolean.\n\n```swift\nclass OCPCricketFilter : Filter\n{\n    typealias T = Cricketer\n    \n    func filter\u003cCond: Condition\u003e(_ items: [Cricketer], _ cond: Cond)\n        -\u003e [T] where Cond.T == T\n    {\n        var filteredItems = [Cricketer]()\n        for i in items\n        {\n            if cond.isConditionMet(i)\n            {\n                filteredItems.append(i)\n            }\n        }\n        return filteredItems\n    }\n}\n```\n\nNow we define a brand new filter called OCPCricketFilter, usage of which does not violate OCP. We take items of type Cricketer, check for the condition of type Condition and return the filtered array.\n \nLet us now see the code in action. Change the main method to following.\n\n```swift\nfunc main(){\n    let dhoni = Cricketer(\"Dhoni\", .india, .batsman)\n    let kohli = Cricketer(\"Kohli\",  .india, .batsman)\n    let maxi = Cricketer(\"Maxwell\", .australia, .allrounder)\n    let smith = Cricketer(\"Smith\", .australia, .batsman)\n    let symo = Cricketer(\"Symonds\", .australia, .allrounder)\n    let broad = Cricketer(\"Broad\", .england, .bowler)\n    let ali  = Cricketer(\"Ali\", .pakistan, .batsman)\n    let stokes = Cricketer(\"Stokes\", .england, .allrounder)\n    \n    let cricketers = [dhoni, kohli, maxi, broad, ali, stokes ,smith, symo]\n \n    let ocpFilter = OCPCricketFilter()\n \n    print(\" England Cricketers\")\n    for item in ocpFilter.filter(cricketers, TeamCondition(.england)){\n        print(\" \\(item.name) belongs to English Team\" )\n    }\n}\n```\n\nWe take an instance of OCPFilter and just pass the team name parameter to TeamCondition. \n \nOutput in the Xcode console:\n \n England Cricketers\n Broad belongs to English Team\n Stokes belongs to English Team\n \nIn the similar way, without modifying any existing classes, we can extend the OCPCricketFilter class to as many filters as we need. Now we will see how we can write a filter for AND condition ( role and team for example):\n\n```swift\nclass AndCondition\u003cT,\n    CondA: Condition,\n    CondB: Condition\u003e : Condition\n    where T == CondA.T, T == CondB.T\n{\n    \n    let first: CondA\n    let second: CondB\n    init(_ first: CondA, _ second: CondB)\n    {\n        self.first = first\n        self.second = second\n    }\n    \n    func isConditionMet(_ item: T) -\u003e Bool {\n        return first.isConditionMet(item) \u0026\u0026 second.isConditionMet(item)\n    }\n}\n```\nThis is very much similar to other filters with the only change that it takes two conditions as arguments for its initialisation.\n \nChange the main method to below code :\n\n```swift\nfunc main(){\n    let dhoni = Cricketer(\"Dhoni\", .india, .batsman)\n    let kohli = Cricketer(\"Kohli\",  .india, .batsman)\n    let maxi = Cricketer(\"Maxwell\", .australia, .allrounder)\n    let smith = Cricketer(\"Smith\", .australia, .batsman)\n    let symo = Cricketer(\"Symonds\", .australia, .allrounder)\n    let broad = Cricketer(\"Broad\", .england, .bowler)\n    let ali  = Cricketer(\"Ali\", .pakistan, .batsman)\n    let stokes = Cricketer(\"Stokes\", .england, .allrounder)\n    \n    let cricketers = [dhoni, kohli, maxi, broad, ali, stokes ,smith, symo]\n \n    let ocpFilter = OCPCricketFilter()\n \n    print(\" Australian Allrounders\")\n    \n    for item in ocpFilter.filter(cricketers, AndCondition(TeamCondition(.australia), RoleCondition(.allrounder))){\n        print(\" \\(item.name) belongs to Australia Team and is an Allrounder\" )\n    }\n}\n\n```\n\nOutput in the Xcode console:\n \n Australian Allrounders\n Maxwell belongs to Australia Team and is an Allrounder\n Symonds belongs to Australia Team and is an Allrounder\n \nWe can write n number of filters without modifying any existing classes but by just extending the Filter class. \n\n**3) SOLID - Liskov Substitution Principle (LSP):**\n\nDefinition: \n\nLiskov substitution principle named after Barbara Liskov states that one should always be able to substitute a base type for a subtype. LSP is a way of ensuring that inheritance is used correctly. If a module is using a base class, then the reference to the base class can be replaced with a derived class without affecting the functionality of the module.\n\nUsage:\n\nLet us understand LSP’s usage with a simple example. \n\n```swift\nimport UIKit\nimport Foundation\n \nprotocol Cricketer {\n    func canBat()\n    func canBowl()\n    func canField()\n}\n```\n\nWe define a protocol called Cricketer which implements three methods of canBat, canBowl, canField.\n\n```swift\nclass AllRounder : Cricketer{\n    func canBat() {\n        print(\"I can bat\")\n    }\n    \n    func canBowl() {\n        print(\"I can bowl\")\n    }\n    \n    func canField() {\n        print(\"I can field\")\n    }\n}\n```\nWe then define a class called AllRounder conforming to Cricketer protocol. An all-rounder in cricket is someone who can bat, bowl and field.\n\n```swift\nclass Batsman : Cricketer{\n    func canBat() {\n        print(\"I can bat\")\n    }\n    \n    func canBowl() {\n        print(\"I cannot bowl\")\n    }\n    \n    func canField() {\n        print(\"I can field\")\n    }\n}\n\n```\n\nWe then define a class called Batsman conforming to Cricketer protocol. This is violation of LSP as a batsman is a cricketer but cannot use Cricketer protocol because he cannot bowl. Let us now see how we can use LSP in this scenario:\n\n```swift\nprotocol Cricketer {\n    func canBat()\n    func canField()\n}\n \nclass Batsman : Cricketer{\n    func canBat() {\n        print(\"I can bat\")\n    }\n    \n    func canField() {\n        print(\"I can field\")\n    }\n}\n```\nWe change the Cricketer protocol and now make the Batsman class conform to Cricketer protocol.\n\n```swift\nclass BatsmanWhoCanBowl : Cricketer{\n \n    func canBat() {\n        print(\"I can bat\")\n    }\n    \n    func canField() {\n        print(\"I can field\")\n    }\n    \n    func canBowl() {\n        print(\"I can bowl\")\n    }\n \n}\n \nclass AllRounder : BatsmanWhoCanBowl{\n    \n}\n\n```\n\nWe then define a new class named BatsmanWhoCanBowl with super class as Cricketer and define the extra method of  canBowl in this class.\n\n**4) SOLID - Interface Segregation Principle (ISP):**\n\nDefinition:\n \nThe only motto of Interface segregation principle is that the clients should not be forced to implement interfaces they don’t use. Client should not have the dependency on the interfaces that they do not use.\n \nUsage:\n \nLet us assume we are building a screen display for mobile, tablet, desktop interfaces of an app which is used to display live scores of a cricket match.\nWe will see how this can be achieved without using ISP and then using ISP.\n \n\n```swift\nimport UIKit\nimport Foundation\n \n// Before ISP\nprotocol MatchSummaryDisplay{\n    func showLiveScore()\n    func showCommentary()\n    func showLiveTwitterFeed()\n    func showSmartStats()\n}\n \n```\n\n\nWe define a protocol named MatchSummaryDisplay which has four methods to show live score, commentary, twitter feed about the match and statistics of the players.\n\n```swift\nenum NoScreenEstate : Error\n{\n    case doesNotShowLiveTwitterFeed\n    case doesNotShowSmartStats\n}\n \nextension NoScreenEstate: LocalizedError {\n    public var errorDescription: String? {\n        switch self {\n        case .doesNotShowLiveTwitterFeed:\n            return NSLocalizedString(\"No Screen Estate to show Live Twitter Feed\", comment: \"Error\")\n        case .doesNotShowSmartStats:\n            return NSLocalizedString(\"No Screen Estate to show Smart Stats\", comment: \"Error\")\n        }\n    }\n}\n\n```\n\nBy default, we want to show live score and commentary on the all types of devices like mobile, tablet, desktop. Showing twitter feed and statistics are optional, depending on the screen estate available on the device. So, we define an enum called NoScreenEstate with two possible cases. We also write an extension to it just to make the error descriptions more clear.\n\n```swift\nclass DesktopDisplay:MatchSummaryDisplay{\n    func showLiveScore() {\n        print(\"Showing Live Score On Desktop\")\n    }\n    \n    func showCommentary() {\n        print(\"Showing Commentary On Desktop\")\n    }\n    \n    func showLiveTwitterFeed() {\n        print(\"Showing Live Twitter Feed On Desktop\")\n    }\n    \n    func showSmartStats() {\n        print(\"Showing Smart Stats On Desktop\")\n    }\n}\n```\n\nWe start the interface design by defining a class called DesktopDisplay conforming to MatchSummaryDisplay. A desktop has enough screen space available and we show all the available data to the user.\n\n```swift\nclass TabletDisplay:MatchSummaryDisplay{\n    func showLiveScore() {\n        print(\"Showing Live Score On Tablet\")\n    }\n    \n    func showCommentary() {\n        print(\"Showing Commentary On Tablet\")\n    }\n    \n    func showLiveTwitterFeed() {\n        print(\"Showing Live Twitter Feed On Tablet\")\n    }\n    \n    func showSmartStats() {\n        do{\n            let error: Error = NoScreenEstate.doesNotShowSmartStats\n            print(error.localizedDescription)\n            throw error\n        } catch{\n            \n        }\n    }\n}\n```\n\n \nWe then define another class called called TabletDisplay conforming to MatchSummaryDisplay. As the screen size of tablet is less when compared to desktop, we do not show smart stats on iPad display. We throw an error in showSmartStats method.\n\n```swift\nclass MobileDisplay:MatchSummaryDisplay{\n    func showLiveScore() {\n        print(\"Showing Live Score On Mobile\")\n    }\n    \n    func showCommentary() {\n        print(\"Showing Commentary On Mobile\")\n    }\n    \n    func showLiveTwitterFeed() {\n        do{\n            let error: Error = NoScreenEstate.doesNotShowLiveTwitterFeed\n            print(error.localizedDescription)\n            throw error\n        } catch{\n            \n        }\n    }\n    \n    func showSmartStats() {\n        do{\n            let error: Error = NoScreenEstate.doesNotShowSmartStats\n            print(error.localizedDescription)\n            throw error\n        } catch{\n            \n        }\n    }\n}\n```\n\nWe then define another class called called MobileDisplay conforming to MatchSummaryDisplay. As the screen size of mobile is small when compared to desktop and tablet, we do not show smart stats and twitter feed on mobile display. We throw an error in showLiveTwitterFeed and showSmartStats methods.\n \nAs you can see, this approach violates ISP because TabletDisplay and MobileDisplay are forced to implement methods they are not using. Let’s see how we can use ISP in this scenario.\n\n```swift\n//Following ISP\n \nprotocol LiveScoreDisplay{\n    func showLiveScore()\n    func showCommentary()\n}\n \nprotocol TwitterFeedDisplay{\n    func showLiveTwitterFeed()\n}\n \nprotocol SmartStatsDisplay{\n    func showSmartStats()\n}\n```\n\nHere we define a protocol named LiveScoreDisplay which is mandatory for all the screen sizes of the devices. Then we define different protocols called TwitterFeedDisplay and SmartStatsDisplay so that only the devices with enough screen sizes can conform to required protocols.\n\n```swift\nclass ISPMobileDisplay:LiveScoreDisplay{\n    func showLiveScore() {\n        print(\"Showing Live Score On Mobile\")\n    }\n    \n    func showCommentary() {\n        print(\"Showing Commentary On Mobile\")\n    }\n}\n \n```\n\n \nWe define a class called ISPMobileDisplay which conforms only to LiveScoreDisplay and we don’t have to force the class to implement any unwanted methods. \n\n```swift\nclass ISPTabletDisplay:LiveScoreDisplay, TwitterFeedDisplay{\n    \n    func showLiveScore() {\n        print(\"Showing Live Score On Tablet\")\n    }\n    \n    func showCommentary() {\n        print(\"Showing Commentary On Tablet\")\n    }\n    \n    func showLiveTwitterFeed() {\n        print(\"Showing Live Twitter Feed On Tablet\")\n    }\n    \n}\n```\n\nWe then define a class called ISPTabletDisplay which conforms to TwitterFeedDisplay along with LiveScoreDisplay.\n \nWe can define desktop interface as follows.\n\n```swift\nclass ISPDesktopDisplay:LiveScoreDisplay, TwitterFeedDisplay, SmartStatsDisplay{\n    \n    func showLiveScore() {\n        print(\"Showing Live Score On Desktop\")\n    }\n    \n    func showCommentary() {\n        print(\"Showing Commentary On Desktop\")\n    }\n    \n    func showLiveTwitterFeed() {\n        print(\"Showing Live Twitter Feed On Desktop\")\n    }\n    \n    func showSmartStats() {\n        print(\"Showing Smart Stats On Desktop\")\n    }\n}\n```\n\nWe can observe that, in all the above three classes, we are not forcing any class to implement a method that they do not use. We achieved ISP by defining multiple protocols.\n\n**5) SOLID - Dependency Inversion Principle (DIP):**\n\nDefinition:\n \nIn short, Dependency inversion principle says, depend on abstractions, not on concretions. High level modules should not depend upon low level modules. Both should depend upon abstractions.\n \nAbstractions should not depend upon details. Details should depend upon abstractions. By depending on higher-level abstractions, we can easily change one instance with another instance in order to change the behavior. DIP increases the reusability and flexibility of our code.\n \nUsage:\n \nLet us assume we are designing a small system where we want to list all the wickets taken by a bowler in his cricketing career from the database.\n\n```swift\nimport Foundation\nimport UIKit\n \nenum WicketsColumn{\n    case wicketTakenBy\n    case wicketGivenTo\n}\n \nclass Cricketer{\n    var name = \"\"\n    \n    init(_ name:String){\n        self.name = name\n    }\n    \n}\n```\nWe define an enum called WicketsColumn with a list of two possible cases. We then define a class called Cricketer which takes the parameter of name of type String for its initialisation.\n\n```swift\nprotocol WicketsTallyBrowser{\n    func returnAllWicketsTakenByBowler(_ name:String) -\u003e [Cricketer]\n}\n```\n\nWe define a protocol named WicketsTallyBrowser which has a function to return all the wickets taken by a given bowler as array of type Cricketer.\n \nWe will now define a class/ a storage which stores relationship between bowlers and batsmen.\n\n```swift\nclass WicketsTally : WicketsTallyBrowser { //Low Level\n     var wickets = [(Cricketer, WicketsColumn, Cricketer)]()\n    \n    func addToTally(_ bowler : Cricketer,_ batsman : Cricketer){\n        wickets.append((bowler, .wicketTakenBy, batsman))\n        wickets.append((batsman, .wicketGivenTo, bowler))\n    }\n    \n    func returnAllWicketsTakenByBowler(_ name: String) -\u003e [Cricketer] {\n        return wickets.filter({$0.name == name \u0026\u0026 $1 == WicketsColumn.wicketTakenBy \u0026\u0026 $2 != nil})\n            .map({$2})\n    }\n    \n}\n```\n\nWe define a class called WicketsTally conforming to WicketsTallyBrowser protocol. It has a variable called wickets which is an array of tuples where each of the tuples has three attributes, one each of type Cricketer, WicketsColumn and Cricketer in the order.\n \nThen we define a method called addToTally which takes parameters of bowler and batsman of type Cricketer. It appends the same to wickets array but with different relationships available from WicketsColumn enum.\n \nIn the definition of protocol method returnAllWicketsTakenByBowler, we filter the wickets array by comparing first attribute of tuple to the name of given bowler.\n\n```swift\nclass PlayerStats{ //High Level\n    init(_ wicketsTally : WicketsTally){\n        let wickets = wicketsTally.wickets\n        for w in wickets where w.0.name == \"BrettLee\" \u0026\u0026 w.1 == .wicketTakenBy{\n            print(\"Brett Lee has a wicket of \\(w.2.name)\")\n        }\n    }\n}\n```\nWe now define a class called PlayerStats where we use the logic written in WicketsTally class to return all the wickets taken by a particular bowler.\n \nLet us now write a main method to see this code in action:\n\n```swift\nfunc main(){\n    let bowler = Cricketer(\"BrettLee\")\n    let batsman1 = Cricketer(\"Sachin\")\n    let batsman2 = Cricketer(\"Dhoni\")\n    let batsman3 = Cricketer(\"Dravid\")\n    \n    let wicketsTally = WicketsTally()\n    wicketsTally.addToTally(bowler, batsman1)\n    wicketsTally.addToTally(bowler, batsman2)\n    wicketsTally.addToTally(bowler, batsman3)\n    \n    let _ = PlayerStats(wicketsTally)\n    \n}\n```\n\nOutput in the Xcode console:\n \nBrett Lee has a wicket of Sachin\nBrett Lee has a wicket of Dhoni\nBrett Lee has a wicket of Dravid\n\nThe issue with the above approach is its violation of DIP (it states that the high level modules should not directly depend on low level modules) as our PlayerStats class depends upon wickets array of WicketsTally class. It should be declared as a private variable so that no other class can manipulate the data directly.\n \nLet us now change the WicketsTally class this way:\n\n```swift\nclass WicketsTally : WicketsTallyBrowser { //Low Level\n     private var wickets = [(Cricketer, WicketsColumn, Cricketer)]()\n    \n    func addToTally(_ bowler : Cricketer,_ batsman : Cricketer){\n        wickets.append((bowler, .wicketTakenBy, batsman))\n        wickets.append((batsman, .wicketGivenTo, bowler))\n    }\n    \n    func returnAllWicketsTakenByBowler(_ name: String) -\u003e [Cricketer] {\n        return wickets.filter({$0.name == name \u0026\u0026 $1 == WicketsColumn.wicketTakenBy \u0026\u0026 $2 != nil})\n            .map({$2})\n    }\n    \n}\n```\nNow change the PlayerStats class to:\n\n```swift\nclass PlayerStats{ //High Level\n    init(_ browser : WicketsTallyBrowser){\n        for w in browser.returnAllWicketsTakenByBowler(\"BrettLee\"){\n            print(\"Brett Lee has a wicket of \\(w.name)\")\n        }\n    }\n}\n```\nHere we can observe that, instead of directly depending on wickets array from WicketsTally, PlayerStats is dependent on abstraction from WicketsTallyBrowser. Output in the Xcode console remains same but we are now adhering to DIP.\n\nOutput in the Xcode console:\n \nBrett Lee has a wicket of Sachin\nBrett Lee has a wicket of Dhoni\nBrett Lee has a wicket of Dravid\n\n**6) Creational - Factories Design Pattern:**\n\nDefinition:\n\nFactory Method Pattern is also known as Virtual Constructor. It is a creational design pattern that defines an abstract class for creating objects in super class but allows the subclasses decide which class to instantiate.\n\nUsage:\n\nAssume there is a BowlingMachine which delivers Red Cricket Balls (used for Test Cricket) and White Crikcet Balls (used for Limited Overs Cricket) based on user input.\n\n```swift\nimport UIKit\n \nprotocol CricketBall{\n    func hitMe()\n}\n\nAny class conforming to CricketBall must implement hitMe method.\n\nclass RedBall : CricketBall{\n    func hitMe() {\n        print(\"This ball is good for Test Cricket\")\n    }\n}\n \nclass WhiteBall : CricketBall{\n    func hitMe() {\n        print(\"This ball is good for Limited Overs Cricket\")\n    }\n}\n\n```\n\nLet us start defining factories now.\n\n```swift\nprotocol CricketBallFactory{\n \n    init()\n    func deliverTheBall (_ speed : Int) -\u003e CricketBall\n}\n```\nFactories conforming to CricketBallFactory must implement deliverTheBall. We should also give some input like the speed at which we want the ball to be delivered.\n\nNow, moving out of abstract classes creating objects, we start defining subclasses for object creation.\n\n```swift\nclass RedBallFactory{\n    func deliverTheBall (_ speed : Int) -\u003e CricketBall{\n          print(\"Releasing Red Ball at \\(speed) speed\")\n          return RedBall()\n    }\n}\n \nclass WhiteBallFactory{\n    func deliverTheBall (_ speed : Int) -\u003e CricketBall{\n        print(\"Releasing White Ball at \\(speed) speed\")\n        return WhiteBall()\n    }\n}\n```\nHere we are defining two factories to deliver different colours of balls. We input the speed of the ball and get a red/ white ball in return.\n\nIt’s time we go to the machine and give an input to deliver the balls.\n\n```swift\nclass BowlingMachine{\n    enum AvailableBall : String{ \n        case redBall = \"RedBall\"\n        case whiteBall = \"WhiteBall\"\n        \n        static let all = [redBall, whiteBall]\n    }\n    \n    internal var factories = [AvailableBall : CricketBallFactory]()\n    internal var namedFactories = [(String, CricketBallFactory)] ()\n    \n    init() {\n        for ball in AvailableBall.all{\n            let type = NSClassFromString(\"FactoryDesignPattern.\\(ball.rawValue)Factory\")\n            let factory = (type as! CricketBallFactory.Type).init()\n            factories[ball] = factory\n            namedFactories.append((ball.rawValue, factory))\n        }\n    }\n    \n    func setTheBall () -\u003e CricketBall{\n        for i in 0..\u003cnamedFactories.count{\n            let tuple = namedFactories[i]\n            print(\"\\(i) : \\(tuple.0)\")\n        }\n        \n        let input = Int(readLine()!)!\n        return namedFactories[input].1.deliverTheBall(120)\n        \n    }\n}\n```\nWe define a class called BowlingMachine. We have an enum of available balls with redBall and whiteBall as the options. Then we have an array of all the available balls.\n \nWe have an internal variable called factories which is a dictionary with key as the AvailableDrink and value as CricketBallFactory. Then we define a variable called namedFactories which is a list of tuples where each entry has the name of the factory and the instance of the factory.\n\nIn the initialiser method, we initialise the factory. For each ball in available balls, we get the type from actual class. Then we construct the factory by taking the type and casting it as a CricketBallFactory and initialising it. Then we append each factory to the array of factories.\n \nWe then define a function which asks us to set the ball and returns a cricket ball. For each factory , we print out the index and the name of the factory. Then based on the input entered by the user, we return cricketBall at given speed.\n \nLet’s now define a function called main and see the code in action.\n\n```swift\nfunc main(){\n    let bowlingMachine = BowlingMachine()\n    print(bowlingMachine.namedFactories.count)\n    let ball = bowlingMachine.setTheBall()\n    ball.hitMe()\n}\n \nmain()\n```\n\nHere we initialise the BowlingMachine and set the ball. Then we call the hitMe method on the instance of each ball the user inputs.\n\nOutput in the Xcode console:\n \n2\nAvailableBalls\n0 : RedBall\n1: WhiteBall\n \nIf we choose 0, we print ‘Releasing Red Ball at 20 speed’.\nIf we choose 1, we print ‘Releasing White Ball at 20 speed’. \n \nSummary:\n \nWhen you are in a situation where a class does not know what subclasses will be required to create or when a class wants its subclasses specify the objects to be created, go for Factory design pattern.\n\n**7) Creational - Builder Design Pattern :**\n\nDefinition:\n \nBuilder is a creational design pattern that helps in piecewise construction of  complex objects avoiding too many initializer arguments. It lets us produce different types and representations of an object using the same process of building.\n \nThis pattern majorly involves three types. \n \nProduct - complex object to be created\nBuilder - handles the creation of product\nDirector - accepts inputs and coordinates with the builder\n \nUsage:\n\nLet us assume we are creating a cricket team which consists of a captain, batsmen and bowlers. We will see how we can use builder pattern in this context. \n\nWe start with the Product part first.\n\n```swift\nimport UIKit\n \n//MARK: -Product\npublic struct CricketTeam{\n    public let captain : Captain\n    public let batsmen : Batsmen\n    public let bowlers : Bowlers\n}\n\nextension CricketTeam : CustomStringConvertible{\n    public var description : String{\n        return \"Team with captain \\(captain.rawValue)\"\n    }\n}\n```\nWe first define CricketTeam, which has properties for captain, batsmen and bowlers. Once a team is set, we shouldn’t be able to change its composition. We also make CricketTeam conform to CustomStringConvertible.\n\n```swift\npublic enum Captain : String{\n    case Dhoni\n    case Kohli\n    case Rahane\n}\n```\nWe declare Captain as enum. Each team can have only one captain.\n\n```swift\npublic struct Batsmen : OptionSet{\n    public static let topOrderBatsman = Batsmen(rawValue: 1 \u003c\u003c 0)\n    public static let middleOrderBatsman = Batsmen(rawValue: 1 \u003c\u003c 1)\n    public static let lowerOrderBatsman = Batsmen(rawValue: 1 \u003c\u003c 2)\n    \n    public let rawValue : Int\n    public init(rawValue : Int){\n        self.rawValue = rawValue\n    }\n}\n \npublic struct Bowlers : OptionSet{\n    public static let fastBowler = Bowlers(rawValue: 1 \u003c\u003c 0)\n    public static let mediumPaceBowler = Bowlers(rawValue: 1 \u003c\u003c 1)\n    public static let spinBowler = Bowlers(rawValue: 1 \u003c\u003c 2)\n    \n    public let rawValue : Int\n    public init(rawValue : Int){\n        self.rawValue = rawValue\n    }\n}\n```\n\nWe define Batsmen and Bowlers as OptionSet. This allows us to try different combination of batsmen together. Like a team with two topOrderBatsman, one middleOrderBatsman. Same with Bowlers where we can choose a combination of fastBowler, mediumPaceBowler and a spin bowler for the team.\n\nAdd the following code to make Builder.\n\n```swift\n//MARK: -Builder\npublic class CricketTeamBuilder{\n    \n    public enum Error:Swift.Error{\n        case alreadyTaken\n    }\n    \n    public private(set) var captain : Captain = .Dhoni\n    public private(set) var batsmen : Batsmen = []\n    public private(set) var bowlers : Bowlers = []\n    private var soldOutCaptains : [Captain] = [.Dhoni]\n    \n    public func addBatsman(_ batsman : Batsmen){\n        batsmen.insert(batsman)\n    }\n    \n    public func removeBatsman(_ batsman: Batsmen) {\n        batsmen.remove(batsman)\n    }\n    \n    public func addBowler(_ bowler : Bowlers){\n        bowlers.insert(bowler)\n    }\n    \n    public func removeBowler(_ bowler: Bowlers) {\n        bowlers.remove(bowler)\n    }\n \n    public func pickCaptain(_ captain: Captain) throws {\n        guard isAvailable(captain) else { throw Error.alreadyTaken }\n        self.captain = captain\n    }\n    \n    public func isAvailable(_ captain: Captain) -\u003e Bool {\n        return !soldOutCaptains.contains(captain)\n    }\n    \n \n    public func makeTeam() -\u003e CricketTeam{\n        return CricketTeam(captain: captain, batsmen: batsmen, bowlers: bowlers)\n    }\n \n}\n```\n\nWe declare properties for captain, batsmen, bowlers. These are declared as var so that we can change the team’s composition based on the requirement. We are using private(set) for each to ensure only CricketTeamBuilder can set them directly. \n\nSince each property is declared private, we need to provide public methods to change them. We defined methods like addBatsman, removeBatsman, addBowler, removeBowler etc for the purpose of building team.\n\nWe have an interesting thing to note here. Every team by default should have a captain. Assume, you are starting a team with Dhoni as captain. What if some other team tries to choose Dhoni as captain too? We should throw some error using the array of soldOutCaptains. We check the availability of the captains via isAvailable method.\n\nWe are done with the Builder. Now, let’s build our Director.\n\n```swift\n//MARK: -Director/ Maker\npublic class TeamOwner {\n    \n    public func createTeam1() throws -\u003e CricketTeam {\n        let teamBuilder = CricketTeamBuilder()\n        try teamBuilder.pickCaptain(.Kohli)\n        teamBuilder.addBatsman(.topOrderBatsman)\n        teamBuilder.addBowler([.fastBowler, .spinBowler])\n        return teamBuilder.makeTeam()\n    }\n \n \n    \n    public func createTeam2() throws -\u003e CricketTeam {\n        let teamBuilder = CricketTeamBuilder()\n        try teamBuilder.pickCaptain(.Dhoni)\n        teamBuilder.addBatsman([.topOrderBatsman, .lowerOrderBatsman])\n        teamBuilder.addBowler([.mediumPaceBowler, .spinBowler])\n        return teamBuilder.makeTeam()\n    }\n \n}\n```\n\nWe have a class called TeamOwner who builds their teams from the available options. Each team is built taking an instance of CricketTeamBuilder, picking up a captain and arrays of different types of batsman and bowlers.\n\nNow, let’s define a function called main to see the code in action.\n\n```swift\nfunc main(){\n    let owner = TeamOwner()\n    if let team = try? owner.createTeam1(){\n        print(\"Hello! \" + team.description)\n    }\n  \n}\n \nmain()\n```\n\nWe try to use method createTeam1 with captain as Kohli. \n\nOutput in the Xcode console:\n\nHello! Team with captain Kohli\n\nNow, change the main() to following:\n\n```swift\nfunc main(){\n    let owner = TeamOwner()\n    if let team = try? owner.createTeam1(){\n        print(\"Hello! \" + team.description)\n    }\n    \n    if let team = try? owner.createTeam2(){\n        print(\"Hello! \" + team.description)\n    } else{\n        print(\"Sorry! Captain already taken\")\n    }\n}\n \nmain()\n\n```\n\nAfter Team1, we are trying to create  a Team2 with the help of createTeam2() with Dhoni as captain. But Dhoni is already taken and we throw the error. \n\nOutput in the Xcode console:\n\nHello! Team with captain Kohli\nSorry! Captain already taken\n\n\nSummary:\n\nIf you are trying to use the same code for building different products to isolate the complex construction code from business logic ,Builder design pattern fits the best.\n\nAlso be careful that when your product does not require multiple parameters for initialisation or construction, it’s advised to stay away from Builder pattern.\n\n**8) Creational - Prototype Design Pattern:**\n\nDefinition:\n\nPrototype is a creational design pattern used in situations which lets us produce new objects, that are almost similar state or differs little. A prototype is basically a template of any object before the actual object is constructed. The Prototype pattern delegates cloning process to objects themselves.\n\nUsage:\n\nLet us consider a simple use case where we want to create the profile of two cricketers which includes their name, and a custom profile which includes runs scored and wickets taken. \n\n```swift\nimport UIKit\n \nclass Profile : CustomStringConvertible{\n    var runsScored : Int\n    var wicketsTaken : Int\n    \n    init(_ runsScored : Int, _ wicketsTaken : Int) {\n        self.runsScored = runsScored\n        self.wicketsTaken = wicketsTaken\n    }\n    \n    var description: String{\n        return \"\\(runsScored) Runs Scored \u0026 \\(wicketsTaken) Wickets Taken\"\n    }\n}\n\n```\n\nFirst, we create a Profile class which conforms to CustomStringConvertible. It has two properties runsScored and wicketsTaken of type int. It takes the same parameters during its initialisation.\n\nThen we define a Cricketer class conforms to CustomStringConvertible. It has two properties, name of type String and profile of custom type Profile which we just created.\n\n```swift\nclass Cricketer : CustomStringConvertible {\n    var name : String\n    var profile : Profile\n    \n    init(_ name :String , _ profile : Profile) {\n        self.name = name\n        self.profile = profile\n    }\n    var description: String{\n        return \"\\(name) : Profile : \\(profile)\"\n    }\n    \n}\n```\n\nLet us now write a function called main to see the things in action.\n\n```swift\nfunc main (){\n    let profile = Profile(1200, 123)\n    let bhuvi = Cricketer(\"Bhuvi\", profile)\n    print(bhuvi.description)\n}\n \nmain()\n```\n\nIt prints \n\nBhuvi : Profile : 1200 Runs Scored \u0026 123 Wickets Taken in the Xcode console.\n\nNow we need to talk about copying the objects.\n\nJust before print statement in the main function, add the following lines .\n\n```swift\nvar ishant = bhuvi\nishant.name = \"Ishant\"\nprint(ishant.description)\n ```\n It prints\nIshant : Profile : 1200 Runs Scored \u0026 123 Wickets Taken\nIshant : Profile : 1200 Runs Scored \u0026 123 Wickets Taken\n \nin the Xcode console.\n \nThis is because we are only copying the references. \n \nNow add this line just before printing ishant’s description.\n\n```swift\nishant.profile.runsScored = 600\n```\n\nIt prints\nIshant : Profile : 600 Runs Scored \u0026 123 Wickets Taken\nIshant : Profile : 600 Runs Scored \u0026 123 Wickets Taken\n \nin the Xcode console.\n \nNow, we need to make sure bhuvi and ishant actually refer to different objects. \n \nHere, we use the concept of Deep Copy. When we deep copy objects, the system will copy references and each copied reference will be pointing to its own copied memory object. Let us now see how to implement Deep Copy interface for our use case.\n\n```swift\nprotocol DeepCopy{\n    func createDeepCopy () -\u003e Self\n}\n\n```\n\nFirst, we create a DeepCopy protocol which defines a function called createDeepCopy returning self.\n \nThen make the classes Profile and Cricketer conform to DeepCopy protocol. Classes now look like:\n\n```swift\nclass Profile : CustomStringConvertible, DeepCopy{\n    var runsScored : Int\n    var wicketsTaken : Int\n    \n    init(_ runsScored : Int, _ wicketsTaken : Int) {\n        self.runsScored = runsScored\n        self.wicketsTaken = wicketsTaken\n    }\n    \n    var description: String{\n        return \"\\(runsScored) Runs Scored \u0026 \\(wicketsTaken) Wickets Taken\"\n    }\n    \n    func createDeepCopy() -\u003e Self {\n        return deepCopyImplementation()\n    }\n    \n    private func deepCopyImplementation \u003cT\u003e () -\u003e T{\n        return Profile(runsScored, wicketsTaken) as! T\n    }\n}\n```\n\nWe have a private method called deepCopyImplementation which is generic and and able to figure out the type correctly. It has a type parameter ‘T’ which is actually going to be inferred (we don’t provide this type parameter anywhere) and a return type of ‘T’. We return a Profile objects and force cast it to T.\n \nCricketer class now looks like:\n\n```swift\nclass Cricketer : CustomStringConvertible ,DeepCopy{\n    var name : String\n    var profile : Profile\n    \n    init(_ name :String , _ profile : Profile) {\n        self.name = name\n        self.profile = profile\n    }\n    \n    var description: String{\n        return \"\\(name) : Profile : \\(profile)\"\n    }\n    \n    func createDeepCopy() -\u003e Self {\n        return deepCopyImplementation()\n    }\n    \n    private func deepCopyImplementation \u003cT\u003e () -\u003e T{\n        return Cricketer(name, profile) as! T\n    }\n    \n}\n```\nLet us define our main method as below and see the results:\n\n```swift\nfunc main(){\n    let profile = Profile(1200, 123)\n    let bhuvi = Cricketer(\"Bhuvi\", profile)\n    let ishant = bhuvi.createDeepCopy()\n    ishant.name = \"Ishant\"\n    ishant.profile = bhuvi.profile.createDeepCopy()\n    ishant.profile.wicketsTaken = 140\n    print(bhuvi.description)\n    print(ishant.description)\n}\n \nmain()\n```\n\nOutput in the Xcode console:\n \nBhuvi : Profile : 1200 Runs Scored \u0026 123 Wickets Taken\nIshant : Profile : 1200 Runs Scored \u0026 140 Wickets Taken\n \nWe can see that bhuvi and ishant are two different objects now and this is how deep copy is implemented.\n \nSummary:\n \nWhen you are in a situation to clone objects without coupling to their concrete classes, you can opt for Prototype design pattern which also helps in reducing repetitive initialization code.\n\n**9) Creational - Singleton Design Pattern:**\n\nWhen discussing which patterns to drop, we found that we still love them all (Not really - I am in favour of dropping Singleton. Its usage is almost always a design smell) - Erich Gamma (one of the Gang Four)\n\nDesign pattern everyone loves to hate. Is it because it is actually bad or is it because of its abuse by the developers? Let’s see.\n\nDefinition:\n\nSingleton is a creational design pattern that provides us with one of the best ways to create an object. This pattern ensures a class has only one instance and provides a global access to it so that the object can be used by all the other classes.\n\nUsage:\n\nLet us take the case of an API which returns some JSON response which when parsed looks like this:\n\n[\"Sachin\" : 1, \"Sehwag\" : 2 , \"Dravid\" : 3, \"Kohli\" : 4, \"Yuvraj\" : 5 ,\"Dhoni\" : 6 ,\"Jadeja\" : 7 ,\"Ashwin\" : 8, \"Zaheer\" : 9 ,\"Bhuvi\" : 10, \"Bumrah\" : 11]\n\nThis data-structure is an Array where each object is a key-value pair. Key represents the name of Indian Cricketer and Value represents the position at which the cricketer bats.\n\nWe would need only one instance of the SingletonDatabase class in order to save this data to our database. There is no point in initialising database class more than once as it would just waste memory. Our code looks like this:\n\n```swift\nimport UIKit\nclass SingletonDatabase{\n    var dataSource = [\"Sachin\" : 1, \"Sehwag\" : 2 , \"Dravid\" : 3, \"Kohli\" : 4, \"Yuvraj\" : 5   ,\"Dhoni\" : 6 ,\"Jadeja\" : 7 ,\"Ashwin\" : 8, \"Zaheer\" : 9 ,\"Bhuvi\" : 10, \"Bumrah\" : 11]\n \n    var cricketers = [String:Int]()\n \n    static let instance = SingletonDatabase()\n    static var instanceCount = 0\n \n    private init(){\n        print(\"Initialising the singleton\")\n        type(of: self).instanceCount += 1\n        for dataElement in dataSource{\n             cricketers[dataElement.key] = dataElement.value\n        }\n    }\n \n}\n```\n\nWe first make a private initialiser which does not take any arguments. And that’s the like the simplest way to create on object. As it is private, no one can make another instance of the class.\n \nBut how do we let someone access the SingletonDatabase? That’s where the Singleton pattern comes to play.\n \nWe initialise a static variable with the only instance of SingletonDatabase class. Making it static restricts the ability to create multiple instances of class. \n \nNow we add the data coming from API call to our array of cricketers. That’s it! We have our database ready.\n \nNow, how does someone have access to this database? Assume we want to know the position at which a cricketer bats. We write a function for that just after the private init() method in SingletonDatabase class.\n\n```swift\nfunc getRunsScoredByCricketer(name:String) -\u003e Int{\n        if let position = cricketers[name]{\n            print(\"\\(name) bats at number \\(position) for Indian Crikcet Team\")\n            return cricketers[name]!\n        }\n \n       print(\"Cricketer with name \\(name) not found\")\n       return 0\n}\n```\nThis method is straightforward which takes name of the cricketer as an argument and returns his position in the line-up.\n \nInorder for us to access this class at some point in our code, we write it this way:\n\n```swift\nfunc main(){\n    let singleton = SingletonDatabase.instance\n    singleton.getRunsScoredByCricketer(name: \"Sachin\")\n}\n```\n\nVery simple and short. We create a variable named singleton which helps us in accessing all the functions in our SingletonDatabase class. \n \nNow run the main() method.\n\n```swift\nmain()\n```\n\nOutput in the Xcode console:\n\nInitialising the singleton\nSachin bats at number 1 for Indian Cricket Team\n\nChange the name parameter to “Sach” and the output is:\n\nInitialising the singleton\nCricketer with name Sach not found\n\nWe missed out discussing variable named instanceCount in our private init() method. We can use this variable to show that there is only one instance of the SingletonDatabase class.\n \n \nChange the main method this way.\n\n```swift\nfunc main(){\n    let singleton1 = SingletonDatabase.instance\n    print(SingletonDatabase.instanceCount)\n    \n    let singleton2 = SingletonDatabase.instance\n    print(SingletonDatabase.instanceCount)\n \n}\n```\n\nOutput in the Xcode console:\n\nInitialising the singleton\n1\n1\n\nInstance count remains 1 even though we initialised the class more than once. \n\nAdding the code snippet for another self explanatory example here which would enhance your understanding:\n\n```swift\nimport UIKit\n \nclass PlayerRating : CustomStringConvertible{\n    private static var _nameOfThePlayer = \"\"\n    private static var _ratingForThePlayer = 0\n \n    var nameOfThePlayer : String{\n        get {return type(of: self)._nameOfThePlayer}\n        set(value) {type(of: self)._nameOfThePlayer = value}\n    }\n \n    var ratingForThePlayer : Int{\n        get {return type(of: self)._ratingForThePlayer}\n        set(value) {type(of: self)._ratingForThePlayer = value}\n    }\n \n    var description: String{\n        return \"\\(nameOfThePlayer) has got a rating of \\(ratingForThePlayer)\"\n    }\n}\n \nfunc main(){\n    let playerRating1 = PlayerRating()\n    playerRating1.nameOfThePlayer = \"Dhoni\"\n    playerRating1.ratingForThePlayer = 8\n \n    let playerRating2 = PlayerRating()\n    playerRating2.ratingForThePlayer = 7\n \n    print(playerRating1)\n    print(playerRating2)\n}\nmain()\n \n```\n\nOutput in the Xcode console:\n \nDhoni has got a rating of 7\nDhoni has got a rating of 7\n\nSummary:\n \nWe should use Singleton pattern only when we have a scenario forcing us to use a single instance of an object at multiple places. \n\n\n**10) Structural - Adapter Design Pattern:**\nDefinition:\n \nAdapter is a structural design pattern converts the interface of a class into another interface clients expect. This lets classes with incompatible interfaces to collaborate.\n \nUsage:\n\nSuppose you have a TestBatsman class with fieldWell() and makeRuns()methods. And also a T20Batsman class with batAggressively() method.\n\nLet’s assume that you are short on T20Batsman objects and you would like to use TestBatsman objects in their place. TestBatsmen have some similar functionality but implement a different interface (they can bat but cannot bat in the way needed for a T20 match), so we can’t use them directly. \n\nSo we will use adapter pattern. Here our client would be T20Batsman and adaptee would be TestBatsman. \n\nLet us now write code:\n\n```swift\nimport UIKit\n \nprotocol TestBatsman {\n    func makeRuns()\n    func fieldWell()\n}\n```\n\nA simple protocol named TestBatsman defining two methods, makeRuns and fieldWell.\n\n```swift\nclass Batsman1 : TestBatsman{\n    func makeRuns() {\n        print(\"I can bat well but only at StrikeRate of 80\")\n    }\n    \n    func fieldWell() {\n        print(\"I can field well\")\n    }\n}\n```\n\nWe define a Batsman1 class conforming to TestBatsman protocol. This type of batsman can make runs at a strike rate of 80.\n```swift\nprotocol T20Batsman{\n    func batAggressively()\n}\n```\n\nWe have one more protocol named T20Batsman which defines batAggressively method.\n```swift\nclass Batsman2 : T20Batsman{\n    func batAggressively() {\n         print(\"I need to bat well at a StrikeRate of more than 130\")\n    }\n}\n```\n\nWe define a Batsman2 class conforming to T20Batsman protocol. This type of batsman can make runs at a strike rate of 130.\n \nNow considering our situation, we need to make an adapter in such a way that TestBatsman can fit to be a T20Batsman.\n\n```swift\nclass TestBatsmanAdapter : T20Batsman{\n    let testBatsman : TestBatsman\n    init (_ testBatsman : TestBatsman){\n        self.testBatsman = testBatsman\n    }\n    \n    func batAggressively() {\n        testBatsman.makeRuns()\n    }\n}\n```\n \nWe write a class named TestBatsmanAdapter whose superclass is T20Batsman. It has a property of type TestBatsman and it takes an object of type TestBatsman for its initialisation. It is this object which we make adaptable to batAggressively method by calling makeRuns method.\n \n \nOutput in the Xcode console:\n \nTest Batsman\nI can field well\nI can bat well but only at StrikeRate of 80\nT20 Batsman\nI need to bat well at a StrikeRate of more than 130\nTestBatsmanAdapter\nI can bat well but only at StrikeRate of 80\n \nSummary:\n \nWhen you are in a situation where you have an object that should be able to do the same task but in lots of different ways and you do not want to expose algorithm's implementation details to other classes, opt for Adapter design pattern.\n \n  \n**11) Structural - Bridge Design Pattern:**\n\nDefinition:\nBridge is a structural design pattern which lets us connect components together through abstraction.It enables the separation of implementation hierarchy from interface hierarchy and improves the extensibility.\nUsage:\nLet us suppose that we have a protocol named Batsman whose main function is to make runs for his team.\n\n```swift\nimport Foundation\nimport UIKit\n \nprotocol Batsman\n{\n    func makeRuns(_ numberOfBalls: Int)\n}\n```\n\nmakeRuns takes a parameter named numberOfBalls of type Int. \nLet us now define three different classes of batsmen conforming to Batsman protocol.\n\n```swift\nclass TestBatsman : Batsman\n{\n    func makeRuns(_ numberOfBalls: Int) {\n        print(\"I am a Test Batsman and I score \\(0.6 * Double(numberOfBalls)) runs in \\(numberOfBalls) balls\")\n    }\n}\n \nclass ODIBatsman : Batsman\n{\n    func makeRuns(_ numberOfBalls: Int) {\n        print(\"I am a ODI Batsman and I score \\(1 * Double(numberOfBalls)) runs in \\(numberOfBalls) balls\")\n    }\n}\n \nclass T20IBatsman : Batsman\n{\n    func makeRuns(_ numberOfBalls: Int) {\n        print(\"I am a T20 Batsman and I score \\(1.4 * Double(numberOfBalls)) runs in \\(numberOfBalls) balls\")\n    }\n}\n\n```\n\nWe have three types of batsmen with the only difference between them being the number of runs they score in a given number of balls.\n\nLet us now define a protocol Player whose main function is to play.\n\n```swift\nprotocol Player\n{\n    func play()\n}\n```\nWe now define a Cricketer class conforming to Player protocol.\n```swift\nclass Cricketer : Player\n{\n    var numberOfBalls: Int\n    var batsman: Batsman\n    \n    init(_ batsman: Batsman, _ numberOfBalls: Int)\n    {\n        self.batsman = batsman\n        self.numberOfBalls = numberOfBalls\n    }\n    \n    func play() {\n        batsman.makeRuns(numberOfBalls)\n    }\n   \n}\n```\n\nCricketer class takes two parameters, one of type Batsman and the other of type Int during its initialisation. This is where we are bridging between Batsman class and Player class by calling makeRuns method of batsman in the play method.\n\nLet us now define our main function and see how this design pattern works.\n\n```swift\nfunc main()\n{\n    let testBatsman = TestBatsman()\n    let odiBatsman = ODIBatsman()\n    let t20Batsman = T20IBatsman()\n    \n    let cricketer1 = Cricketer(testBatsman, 20)\n    let cricketer2 = Cricketer(odiBatsman, 20)\n    let cricketer3 = Cricketer(t20Batsman, 20)\n    \n    cricketer1.play()\n    cricketer2.play()\n    cricketer3.play()\n    \n}\n \nmain()\n```\n\nOutput in the Xcode console:\n\nI am a Test Batsman and I score 12.0 runs in 20 balls\nI am a ODI Batsman and I score 20.0 runs in 20 balls\nI am a T20 Batsman and I score 28.0 runs in 20 balls\n\nSummary:\n\nWhen you are in a situation where you have to change the implementation object inside the abstraction and when you need to extend a class in several independent dimensions, Bridge design pattern serves the best.\n\n**12) Structural - Composite Design Pattern:**\n\nDefinition:\n\nComposite is a structural design pattern that lets us compose objects into tree structures and allows clients to work with these structures as if they were individual objects. Composition lets us make compound objects.\n\nUsage:\n\nAssume we are building a tree structure of a cricket team where each entity contains name, role, grade of contract as attributes. Let’s see how we can use composite design pattern to build such system.\n\n```swift\nimport UIKit\nimport Foundation\n \nclass CricketTeamMember : CustomStringConvertible{\n    \n    var name : String\n    var role : String\n    var grade : String\n    var teamMembers : [CricketTeamMember]\n    \n    init(name:String, role : String, grade : String) {\n        self.name = name\n        self.role = role\n        self.grade = grade\n        self.teamMembers = [CricketTeamMember]()\n    }\n    \n    func addMember(member : CricketTeamMember){\n        teamMembers.append(member)\n    }\n    \n    func removeMember(member : CricketTeamMember){\n        teamMembers.append(member)\n    }\n    \n    func getListOfTeamMembers() -\u003e [CricketTeamMember]{\n        return teamMembers\n    }\n    var description: String\n    {\n        let demo = \"\\(name)  \\(role) \\(grade)\"\n        return demo\n        \n    }\n}\n```\nLet’s start with defining a class called CricketTeamMember conforming to CustomStringConvertible. It has got four properties like name of type string, role of type string, grade of type string and an array of teamMembers of type CricketTeamMember. It takes three parameters, namely name, role, grade of type String for its initialisation.\n\nWe define a function called addMember which takes a CricketTeamMember object as parameter and appends it to the teamMembers array.\n\nWe have a function named removeMember which takes a CricketTeamMember object as parameter and removes it from  teamMembers array.\n\nWe have another function called getListOfTeamMembers which returns list of team members.\n\nLet us now define main function and see how the composite pattern can be used to define a tree structure.\n\n```swift\nfunc main(){\n \n//1\n \n    let headCoach = CricketTeamMember(name: \"HeadCoach\", role: \"HeadCoach\", grade: \"A\")\n    let captain = CricketTeamMember(name: \"TeamCaptain\", role: \"Captain\", grade: \"B\")\n    let bowlingCoach = CricketTeamMember(name: \"BowlingCoach\", role: \"Coach\", grade: \"B\")\n    let battingCoach = CricketTeamMember(name: \"BattingCoach\", role: \"Coach\", grade: \"B\")\n    let fieldingCoach = CricketTeamMember(name: \"FieldingCoach\", role: \"Coach\", grade: \"B\")\n    let asstBowlingCoach = CricketTeamMember(name: \"ABoC1\", role: \"AsstCoach\", grade: \"C\")\n    let asstBattingCoach = CricketTeamMember(name: \"ABaC1\", role: \"AsstCoach\", grade: \"C\")\n    let asstFieldingCoach = CricketTeamMember(name: \"ABfC1\", role: \"AsstCoach\", grade: \"C\")\n    let teamMember1 = CricketTeamMember(name: \"TM1\", role: \"Player\", grade: \"B\")\n    let teamMember2 = CricketTeamMember(name: \"TM2\", role: \"Player\", grade: \"B\")\n    \n  //2\n \n    headCoach.addMember(member: captain)\n    headCoach.addMember(member: bowlingCoach)\n    headCoach.addMember(member: battingCoach)\n    headCoach.addMember(member: fieldingCoach)\n    \n    captain.addMember(member: teamMember1)\n    captain.addMember(member: teamMember2)\n    \n    bowlingCoach.addMember(member: asstBowlingCoach)\n    battingCoach.addMember(member: asstBattingCoach)\n    fieldingCoach.addMember(member: asstFieldingCoach)\n \n//3\n \n    print(headCoach.description)\n    for member in headCoach.getListOfTeamMembers(){\n        print(member.description)\n        for member in member.getListOfTeamMembers(){\n             print(member.description)\n        }\n    }\n}\n \nmain()\n```\n\nLet’s read this method step by step now.\n \nHere we define different team members using the instance of CricketTeamMember. We can see different roles like HeadCoach, TeamCaptain, BowlingCoach etc.\n \nWe then start forming trees by adding all the captains and coaches under head coach. Adding team members under team captain etc.\n \nHere we start printing the trees. Initially we print the description of HeadCoach and then we loop through all the team members added under him and print their descriptions too.\n \n    \nOutput in the Xcode console:\n \nHeadCoach  HeadCoach A\nTeamCaptain  Captain B\nTM1  Player B\nTM2  Player B\nBowlingCoach  Coach B\nABoC1  AsstCoach C\nBattingCoach  Coach B\nABaC1  AsstCoach C\nFieldingCoach  Coach B\nABfC1  AsstCoach C\n \nSummary:\n \nWhen you are in a situation to simplify the code at client’s end that has to interact with a complex tree structure, then go for Composite design pattern. In other words, it should be used when clients need to ignore the difference between compositions of objects and individual objects.\n\n**13) Structural - Decorator Design Pattern:**\n\nDefinition:\n\nDecorator is a structural design pattern lets us add new behavior to the objects without altering the class itself. It helps us in keeping the new functionalities separate without having to rewrite existing code.\n\nUsage:\n\nAssume we are checking if a player is fit for playing T20 game of cricket as a bowler or batsman or both or none based on his batting and bowling statistics. Let us see how Decorator design pattern can help us here.\n```swift\nimport UIKit\nimport Foundation\n \nclass T20Batsman{\n    \n    var strikeRate : Int = 0\n    \n    func makeRuns() -\u003e String{\n        return (strikeRate \u003e 130) ? \"Fit for T20 Team as Batsman\" : \"Too slow Batsman for T20 Team\"\n    }\n    \n}\n```\nWe write a class called T20Batsman with a property called strikeRate of type Int. It has a function defined called makeRuns which tells us if the batsman is fit for T20 team based on his strikeRate. If the strike rate is more than 130, he is fit as T20 batsman, else he is too slow for the game.\n\n```swift\nclass T20Bolwer{\n    \n    var economyRate : Float = 0\n    \n    func bowlEconomically () -\u003e String{\n        return (economyRate \u003c 8.0) ? \"Fit for T20 Team as Bowler\" : \"Too expensive as a Bowler\"\n    }\n    \n}\n```\n\nWe then define a class called T20Bolwer with a property called economyRate of type Float. It has a function defined called bowlEconomically which tells us if the bowler is fit for T20 team based on his economyRate. If the economy rate is less than 8.0, he is fit as T20 bowler, else he is too expensive as a bowler for the game.\n \n```swift\nclass T20AllRounder : CustomStringConvertible{\n    private var _strikeRate : Int = 0\n    private var _economyRate : Float = 0\n    \n    private let t20Batsman = T20Batsman()\n    private let t20Bowler = T20Bolwer()\n    \n    \n    func makeRuns() -\u003e String{\n        return t20Batsman.makeRuns()\n    }\n    \n    func bowlEconomically() -\u003e String{\n        return t20Bowler.bowlEconomically()\n    }\n    \n    var strikeRate : Int{\n        get {return _strikeRate}\n        set(value){\n            t20Batsman.strikeRate = value\n            _strikeRate = value\n        }\n    }\n    \n    var economyRate : Float{\n        get {return _economyRate}\n        set(value){\n            t20Bowler.economyRate = value\n            _economyRate = value\n        }\n    }\n    \n    var description: String{\n        if t20Batsman.strikeRate \u003e 130 \u0026\u0026 t20Bowler.economyRate \u003c 8 {\n            return \"Fit as T20 AllRounder\"\n        }\n        else{\n        var buffer = \"\"\n        buffer += t20Batsman.makeRuns()\n        buffer += \" \u0026 \" + t20Bowler.bowlEconomically()\n        return buffer\n        }\n    }\n}\n```\n\nWe now define a class for T20AllRounder conforming to CustomStringConvertible. All rounder is someone in cricket who can bat and bowl reasonably good. It has got four private variables strikeRate and economyRate of type Int and Float respectively. Two more variables of type T20Batsman and T20Bowler.\n \nNow this allrounder should be able to make runs and bowl well. So it has got two functions defined:\n \nmakeRuns: Here we use the instance of T20Batsman variable to call the makeRuns method and see if he is fit as T20Batsman based on defined criteria for strike rate\n \nbowlEconomically: Here we use the instance of T20Bowler variable to call the bowlEconomically method and see if he is fit as T20Bowler based on defined criteria for economy rate.\n  \nIn case, in future if we want to change the conditions for batsmen or bowler or both, we do not have to disturb the code written for allrounder class. Just changing the code in T20Batsman and T20Bowler classes will be enough.\n \nLet us now write a main function to see the code in action:\n\n```swift\nfunc main(){\n    \n    let t20AllRounder = T20AllRounder()\n    t20AllRounder.strikeRate = 120\n    t20AllRounder.economyRate = 7\n    print(t20AllRounder.description)\n \n}\n \nmain()\n```\n\nWe take an instance of T20AllRounder class and feed in the strikeRate and economyRate and see if certain player is fit or not.\n \nOutput in the Xcode console:\n \nToo slow Batsman for T20 Team \u0026 Fit for T20 Team as Bowler\n \nKeep changing the inputs for strikeRate and economyRate and see if the player is fit for T20 game of cricket.\n\n```swift\nt20AllRounder.strikeRate = 150\nt20AllRounder.economyRate = 7\n```\n \nPrints : Fit as T20 AllRounder\n \n```swift\nt20AllRounder.strikeRate = 150\nt20AllRounder.economyRate = 9\n```\n \nPrints: Fit for T20 Team as Batsman \u0026 Too expensive as a Bowler\n \n```swift\nt20AllRounder.strikeRate = 120\nt20AllRounder.economyRate = 9\n```\n \nPrints: Too slow Batsman for T20 Team \u0026 Too expensive as a Bowler\n \nSummary:\n \nIf you are in a situation where you are looking for something flexible than class inheritance and need to edit/ update behaviors at runtime, then Decorator design pattern serves you better.\n\n\n**14) Structural - Facade Design Pattern:**\n\nDefinition:\n \nFacade is a structural design pattern that lets us expose several patterns through a single, easy to use interface. Facade defines a higher level interface that makes the subsystem easier to use by wrapping a complicated subsystem with a simpler interface.\n \nUsage:\n \nAssume we are building an imaginary player auction system for a private cricket league. Any team with an id and a name can buy players who have an id, role in the team and a price. Let’s write some code for this:\n \n```swift\nimport UIKit\nimport Foundation\n \n//Team represents an object that can buy a player\npublic struct Team {\n    \n    public let teamId: String\n    public var teamName: String\n}\n \npublic struct Player {\n    public let playerId: String\n    public var primaryRole: String\n    public var price: Double\n}\n```\n\nWe define Team struct that holds the properties of teamId and teamName as String. Then there is another struct for Player that holds playerId, primaryRole as String and price as Double.\n\n```swift\n//Any Swift type that conforms the Hashable protocol must also conform the Equatable protocol. Because Hashable protocol is inherited from Equatable protocol\n \nextension Team: Hashable {\n    \n    public var hashValue : Int{\n        return teamId.hashValue\n    }\n \n    public static func == (lhs : Team, rhs : Team) -\u003e Bool{\n        return lhs.teamId == rhs.teamId\n    }\n \n}\n \nextension Player : Hashable{\n    \n    public var hashValue : Int{\n        return playerId.hashValue\n    }\n    \n    public static func ==(lhs:Player, rhs:Player) -\u003eBool{\n        return lhs.playerId == rhs.playerId\n    }\n}\n \n```\n\nWe write a couple of extensions, one for Team and one for Player, each conforming to Hashable protocol. When we conform to a hashable protocol we must have a hashValue property.\n \nHashable is a type that has hashValue in the form of an integer that can be compared across different types. We get the hashValue as teamId.hashValue.  \n \nApple definesEquatable as a type that can be compared for value equality, which is part of the working definition for a hashable protocol.\n \nWe then use mandatory method related to Hashable protocol that compares the type and checks to see if they are equal.\n\n```swift\npublic class AvailablePlayersList{\n    public var availablePlayers : [Player : Int] = [:]\n    \n    public init(availablePlayers : [Player:Int]){\n        self.availablePlayers = availablePlayers\n    }\n    \n}\n \npublic class SoldPlayersList{\n    public var soldPlayers : [Team:[Player]] = [:]\n}\n```\n\nWe define a class AvailablePlayersList which has a variable named availablePlayers of type Dictionary with Player type as key and their availability in number as int as value.\n \nThen we have another class SoldPlayerList which has a variable called soldPlayers which basically maintains a list of players bought by a certain team.\n \nNow we define our facade with the help of classes defined above!\n\n```swift\npublic class AuctionFacade{\n    \n    public let availablePlayersList : AvailablePlayersList\n    public let soldPlayersList : SoldPlayersList\n    \n    public init(availablePlayersList:AvailablePlayersList, soldPlayersList:SoldPlayersList){\n        self.availablePlayersList = availablePlayersList\n        self.soldPlayersList = soldPlayersList\n    }\n    \n    public func buyAPlayer(for player: Player,\n                           by team: Team) {\n        \n        print(\"Ready to buy \\(player.primaryRole) with id '\\(player.playerId)' - '\\(team.teamName)'\")\n        \n        let count = availablePlayersList.availablePlayers[player, default: 0]\n        guard count \u003e 0 else {\n            print(\"'\\(player.primaryRole)' is sold out\")\n            return\n        }\n     \n        availablePlayersList.availablePlayers[player] = count - 1\n \n        var soldOuts =\n            soldPlayersList.soldPlayers[team, default: []]\n        soldOuts.append(player)\n        soldPlayersList.soldPlayers[team] = soldOuts\n        \n        print(\"\\(player.primaryRole) with \\(player.playerId) \" + \"bought by '\\(team.teamName)'\")\n    }\n    \n}\n```\n\nAuctionFacade takes two parameters, one of type AvailablePlayersList and one of type SoldPlayerList during its initialisation. We then define a public method buyAplayer.\n \nAs and when a player is bought, the count for that type of player is reduced by one in availablePlayerList. The same player is appended to the list of soldPlayersList.\n \nLet’s now write a main function to see facade in action.\n \n```swift\nfunc main(){\n    let bowler1 = Player(playerId: \"12345\", primaryRole: \"Bowler\", price: 123)\n    let batsman1 = Player(playerId: \"12365\", primaryRole: \"Batsman\", price: 152)\n    \n    let availablePlayerList = AvailablePlayersList(availablePlayers: [bowler1 : 3, batsman1:45])\n    let auctionFacade = AuctionFacade(availablePlayersList: availablePlayerList, soldPlayersList: SoldPlayersList())\n    let team1 = Team(teamId: \"XYZ-123\", teamName: \"Sydney\")\n    auctionFacade.buyAPlayer(for: bowler1, by: team1)\n}\n \nmain()\n```\nWe define bowler1 and batsman1 as Player type objects. We then initialise AvailablePlayerList with 3 bowler1 type Players and 45 batsman1 type Players.\n \nWe then take an instance of AuctionFacade and provide availablePlayerList and instance of SoldPlayerList as parameters.\n \nOutput in the Xcode console:\n \nReady to buy Bowler with id '12345' - 'Sydney'\nBowler with 12345 bought by 'Sydney'\n \nSummary:\n \nWhen you want to provide simple interface to a complex sub-system and have a single interface for traversing different data structures, Facade design patterns works the best.\n\n**15) Structural - FlyWeight Design Pattern:**\n\nDefinition:\n\nFlyWeight is a structural design pattern that helps in avoiding redundancy while storing data. It helps fitting more objects in the available amount of RAM by reusing already existing similar kind of objects by storing them and creating a new object when no matching object is found.\n\nAssume you are storing first and last names of persons in memory. When there are many people with identical first/ last names, there is no point storing them again and again as a new entity. Instead we use something like FlyWeight design pattern to save the storage space.\n\nUsage:\n\nLet us consider a situation where we are storing player profiles where each entity consists of player’s name of type String and the teams he played for of type String array as attributes. \n\nWe write the code without using FlyWeight design pattern and check the memory occupied.\n\n```swift\nimport UIKit\nimport Foundation\n \nclass PlayerProfile{\n    var fullName : String\n    var teamsPlayedFor : [String]\n    \n    init(_ fullName : String, _ teamsPlayedFor : [String]) {\n        self.fullName = fullName\n        self.teamsPlayedFor = teamsPlayedFor\n    }\n    \n    var charCount: Int\n    {\n        var count = 0\n        for team in teamsPlayedFor{\n            count += team.utf8.count\n        }\n        count += fullName.utf8.count\n        return count\n    }\n}\n```\n\nWe define a class called PlayerProfile which takes fullName of type String and teamsPlayedFor of type String array as parameters during its initialisation.\n\nWe then define a variable called charCount which is indicator of the memory occupied. Let us write our main function anc check the character count.\n\n```swift\nfunc main()\n{\n    let dhoni = PlayerProfile(\"Mahendra Dhoni\",[\"India ,Chennai\"])\n    let kohli = PlayerProfile(\"Virat Kohli\",[\"India , Bangalore\"])\n    let yuvi = PlayerProfile(\"Yuvraj Singh\",[\"India , Punjab\"])\n    print(\"Total number of chars used:\"  ,dhoni.charCount + kohli.charCount + yuvi.charCount)\n    \n}\n \nmain()\n```\nWe define few instances of PlayerProfile by passing the players’ names and their teams as parameters. Then we use the charCount property on all the instances and print it to the console.\n\n\nOutput in the Xcode console:\n\nTotal number of chars used: 82\n\nLet us now use FlyWeight design pattern for the same use case.\n\n```swift\nclass PlayerProfileOptimised{\n    static var stringsArray = [String]()\n    private var genericNames = [Int]()\n    \n    init(_ fullName: String, _ teamsPlayedFor : [String])\n    {\n        func getOrAdd(_ s: String) -\u003e Int\n        {\n            if let idx = type(of: self).stringsArray.index(of: s)\n            {\n                return idx\n            }\n            else\n            {\n                type(of: self).stringsArray.append(s)\n                return type(of: self).stringsArray.count - 1\n            }\n        }\n        genericNames = fullName.components(separatedBy: \" \").map { getOrAdd($0) }\n        for team in teamsPlayedFor{\n            genericNames = team.components(separatedBy: \" \").map {getOrAdd($0) }\n        }\n    }\n    \n    static var charCount: Int\n    {\n        return stringsArray.map{ $0.utf8.count }.reduce(0, +)\n    }\n}\n\n```\n\nWe define a class called PlayerProfileOptimised. Here we define a static variable called as stringsArray which stores different strings that may or may not be repeated. We then define a non-static variable called as genericNames which is going to keep an array of indices into this array.\n\nIn initialisation method, we have an inner function called getOrAdd which takes a string as a parameter and returns the index of the string in stringsArray if already existing, or return the index by adding it to the stringsArray array at the tail end.\n\nWe then initialise the genericNames array by taking the full name and split it into component separated by space and mapping it by calling the function getOrAdd with a parameter. This lets us get genericNames to be initialised to a set of indices which corresponds to the strings inside the stringsArray array.\n\nLet us now write main function and check the character count:\n\n```swift\nfunc main()\n{\n    let dhoni1 = PlayerProfileOptimised(\"Mahendra Dhoni\",[\"India ,Chennai\"])\n    let kohli1 = PlayerProfileOptimised(\"Virat Kohli\",[\"India , Bangalore\"])\n    let yuvi1 = PlayerProfileOptimised(\"Yuvraj Singh\",[\"India , Punjab\"])\n    print(\"Total number of chars used:\"  ,PlayerProfileOptimised.charCount)\n}\n \nmain()\n```\nOutput in the Xcode console:\n \nTotal number of chars used: 63\n \nFor the same data, the number of characters reduced significantly. That’s how FlyWeight design pattern can be used for efficient storage of data.\n \nSummary:\n \nWhen you are in a situation to store data that might contain significant amount of duplicate data, you can use FlyWeight design pattern. This helps in reduction in the usage of available RAM.\n\n**16) Structural - Proxy Design Pattern:**\n\nDefinition:\n\nTalking in terms of real world, your debit card is a proxy of your bank account. It’s not real money but can be substituted for money when you want to buy something.\n\nProxy is a structural design pattern which uses wrapper classes to create a stand-in for a real resource. It is also called surrogate, handle and wrapper. Proxy is used to cover the main object’s complex logic from the client using it.\n\nUsage:\n\nAssume we are designing a small software to filter applicants for the position of head coach of a cricket team. The client only passes the number of years of experience of the applicant and we need to write a logic without disturbing the client to say if the applicant is fit for the role or not.\n\nLet us see how we can use Proxy design pattern here:\n\n```swift\nimport UIKit\nimport Foundation\n \nprotocol Coach\n{\n    func mentorTheTeam()\n}\n \nclass CricketCoach : Coach\n{\n    \n    func mentorTheTeam() {\n        print(\"Mentoring the Cricket Team\")\n    }\n   \n}\n```\n\nWe define a protocol called Coach whose main job is to mentor the team.\nThen we define a class called CricketCoach conforming to Coach protocol. \n\n```swift\nclass CoachApplicant\n{\n    var numberOfYearsOfExperience: Int\n    \n    init(numberOfYearsOfExperience: Int)\n    {\n        self.numberOfYearsOfExperience = numberOfYearsOfExperience\n    }\n}\n```\n\nWe write a class called CoachApplicant which takes numberOfYearsOfExperience of type Int as parameter during its initialisation.\n \nNow we write a proxy conforming to Coach protocol to define the logic to filter applicants.\n\n```swift\nclass CricketCoachProxy : Coach\n{\n    private let cricketCoach = CricketCoach()\n    private let coachApplicant: CoachApplicant\n    \n    init(coachApplicant: CoachApplicant)\n    {\n        self.coachApplicant = coachApplicant\n    }\n    \n    func mentorTheTeam() {\n        if coachApplicant.numberOfYearsOfExperience \u003e= 8{\n            cricketCoach.mentorTheTeam()\n        } else{\n            print(\"Not enough experience to coach the team\")\n        }\n    }\n   \n}\n```\n\nIt has got two private variables, one of type CricketCoach and one of type CoachApplicant. In mentorTheTeam method, we define the logic. If the experience of coach applicant is more than 8 years, he is through, else he is rejected.\n\nLet us now write our main method:\n \n```swift\nfunc main()\n{\n    let coach : Coach = CricketCoachProxy(coachApplicant: CoachApplicant(numberOfYearsOfExperience: 8))\n    coach.mentorTheTeam()\n}\n \nmain()\n```\n \nOutput in the Xcode console:\n \nMentoring the Cricket Team\n\nKeep changing the experience parameter and check the output.\n \n```swift\nfunc main()\n{\n    let coach : Coach = CricketCoachProxy(coachApplicant: CoachApplicant(numberOfYearsOfExperience: 5))\n    coach.mentorTheTeam()\n}\n \nmain()\n```\n \nOutput in the Xcode console:\n\nNot enough experience to coach the team\n \nIn future, if we want to change the criteria from 8 years to 10 years or 6 years, we do not have to change any code at client’s end. We can just change the logic in the proxy and things will work just good.\n \nSummary:\n \nWhen you want to create a wrapper around main object to hide its complexity from client, Proxy design pattern suits the best. It also helps in delaying the object’s initialisation so that you can load the objects only when it is needed.\n\n\n**17) Behavioral - Chain of Responsibility Design Pattern:**\n\nDefinition:\n\nChain of Responsibility is a behavioral design pattern that lets us avoid coupling the sender of a request to its receiver by giving multiple objects a chance to handle the request. \n\nUsage:\n\nAssume we are building a small cricket video game where we choose the player characters with their default skills. But then we also give provision to add skill boosters to the player characters as gamers gain some credits. Let us see how we can use Chain of Responsibility to design such system.\n\n```swift\nimport Foundation\n \nclass Cricketer : CustomStringConvertible{\n    var name : String\n    var battingSkillRating : Int\n    var bowlingSkillRating : Int\n    var fieldingSkillRating : Int\n    \n    init(_ name:String, _ battingSkillRating:Int, _ bowlingSkillRating:Int, _ fieldingSkillRating:Int) {\n        self.name = name\n        self.battingSkillRating = battingSkillRating\n        self.bowlingSkillRating  =  bowlingSkillRating\n        self.fieldingSkillRating = fieldingSkillRating\n    }\n    \n    var description: String{\n        return \"Cricketer : \\(name) with battingRating : \\(battingSkillRating), bowlingRating : \\(bowlingSkillRating), fieldingRating : \\(fieldingSkillRating)\"\n    }\n}\n```\n\nWe define a class called Cricketer conforming to CustomStringConvertible. It takes parameters of name of type String, battingSkillRating of type Int, bowlingSkillRating of type Int, fieldingSkillRating of type Int during its initialisation.\n \n```swift\nclass SkillBooster{\n    let cricketer : Cricketer\n    var skillBooster : SkillBooster?\n    \n    init(_ cricketer : Cricketer) {\n        self.cricketer = cricketer\n    }\n    \n    func addBooster(_ booster : SkillBooster){\n        if skillBooster != nil{\n            skillBooster!.addBooster(booster)\n        } else{\n            skillBooster = booster\n        }\n    }\n    \n    func playTheGame(){\n        skillBooster?.playTheGame()\n    }\n}\n```\n\nWe then define a class called SkillBooster which is meant to be a base class for different types of boosters. It takes a parameter of type Cricketer during its initialisation. We also define an optional private variable of type SkillBooster.\n\nIt has two methods defined addBooster and playTheGame. addBooster takes a parameter of type SkillBooster and checks if optional skillBooster is not equal to nil and add the incoming booster to existing ones. Else, skillBooster is assigned the value of incoming booster.\n\n```swift\nclass BattingSkillBooster : SkillBooster{\n    override func playTheGame() {\n        print(\"Adding Hook Shot to \\(cricketer.name) 's Batting\")\n        cricketer.battingSkillRating += 1\n        super.playTheGame()\n    }\n}\n \nclass BowlingSkillBooster : SkillBooster{\n    override func playTheGame() {\n        print(\"Adding Reverse Swing to \\(cricketer.name) 's Bowling\")\n        cricketer.bowlingSkillRating += 1\n        super.playTheGame()\n    }\n}\n \nclass FieldingSkillBooster : SkillBooster{\n    override func playTheGame() {\n        print(\"Adding Dive Catches to \\(cricketer.name) 's Fielding\")\n        cricketer.fieldingSkillRating += 1\n        super.playTheGame()\n    }\n}\n```\n\nWe define different types of skill boosters with SkillBooster as the base class. In all the boosters, we override the function playTheGame and improve the corresponding skill rating of the player character by 1.\n\n```swift\nclass NoSkillBooster : SkillBooster{\n    override func playTheGame() {\n        print(\"No boosters available here\")\n        //don't call super\n    }\n}\n```\n\nWe also define a dummy skill booster just to make the game more interesting.\n \nLet us now write a main function to see the code in action:\n\n```swift\nfunc main(){\n    \n    let dhoni = Cricketer(\"Dhoni\", 6, 3, 7)\n    print(dhoni)\n}\n \nmain()\n```\nOutput in the Xcode console:\n \nCricketer : Dhoni with battingRating : 6, bowlingRating : 3, fieldingRating : 7\n \nNow change the main method to following:\n\n```swift\nfunc main(){\n    \n    let dhoni = Cricketer(\"Dhoni\", 6, 3, 7)\n    print(dhoni)\n    \n    let skillBooster = SkillBooster(dhoni)\n    \n    print(\"Adding Batting Booster to Dhoni\")\n    skillBooster.addBooster(BattingSkillBooster(dhoni))\n    skillBooster.playTheGame()\n    print(dhoni.description)\n    \n}\n \nmain()\n```\n\nOutput in the Xcode console:\n \nCricketer : Dhoni with battingRating : 6, bowlingRating : 3, fieldingRating : 7\nAdding Batting Booster to Dhoni\nAdding Hook Shot to Dhoni 's Batting\nCricketer : Dhoni with battingRating : 7, bowlingRating : 3, fieldingRating : 7\n \nWe add BattingSkillBooster to object dhoni of type Cricketer. We can check the output in the console for an improved rating on dhoni’s batting skill.\n \nChange the main method to following and observe the console:\n\n```swift\nfunc main(){\n    \n    let dhoni = Cricketer(\"Dhoni\", 6, 3, 7)\n    \n    let skillBooster = SkillBooster(dhoni)\n    \n    print(\"Adding Batting Booster to Dhoni\")\n    skillBooster.addBooster(BattingSkillBooster(dhoni))\n    \n    print(\"Adding Bowling Booster to Dhoni\")\n    skillBooster.addBooster(BowlingSkillBooster(dhoni))\n    skillBooster.playTheGame()\n    print(dhoni.description)\n}\n \nmain()\n \n```\nOutput in the Xcode console:\n \nAdding Batting Booster to Dhoni\nAdding Bowling Booster to Dhoni\nAdding Hook Shot to Dhoni 's Batting\nAdding Reverse Swing to Dhoni 's Bowling\nCricketer : Dhoni with battingRating : 7, bowlingRating : 4, fieldingRating : 7\n \nSummary:\n \nUse the Chain of Responsibility pattern when you can conceptualize your program as a chain made up of links, where each link can either handle a request or pass it up the chain. It can modify an existing behaviour by overriding an existing method using inheritance.\n\n**18) Behavioral - Strategy Design Pattern:**\n\nDefinition:\n\nStrategy is a behavioural design pattern that lets you define a set of encapsulated algorithms and enables selecting one of them at runtime. Important point to observe is that these algorithm implementations are interchangeable, i.e, strategy lets the algorithm vary independently from the clients that use it.\n\nUsage:\n\nConsider an example of a Bowling Machine which releases balls of different colours based on the input of speed specified by the user. Assume, we have three different speeds namely slow, medium, fast which corresponds to yellow, green, red coloured balls respectively.\n\n```swift\nimport UIKit\n \nenum CricketBall : String{\n    case slow = \"Yellow\"\n    case medium = \"Green\"\n    case fast = \"Red\"\n}\n```\n\nWe now define a protocol ReleaseCricketBallStrategy which has properties of speed and the type of cricket ball and also defines a method to release ball.\n\n```swift\nprotocol ReleaseCricketBallStrategy{\n    var speed : String {get set}\n    var cricketBall : CricketBall {get set}\n    func releaseBall() -\u003e String\n}\n```\n\nWe now define three new classes , one each for fast, medium and slow ball strategies.\n\nEach of the classes conforms to ReleaseCricketBallStrategy protocol.\nFor the sake of simplicity, we define speed as a string which can be Fast, Medium , Slow. Each of the classes has an initialiser which does not take any extra arguments.\n\nreleaseBall method returns a string implying that its implementation releases a ball with specified properties.\n\n```swift\nclass FastBallStrategy : ReleaseCricketBallStrategy{\n \n    var speed = \"Fast\"\n    var cricketBall = CricketBall.fast\n    init(){}\n \n    func releaseBall() -\u003e String {\n        return \"Released \\(speed) ball with color \\(cricketBall.rawValue)\"\n    }\n}\n \nclass MediumBallStrategy : ReleaseCricketBallStrategy{\n    var speed = \"Medium\"\n    var cricketBall = CricketBall.medium\n    init(){}\n \n    func releaseBall() -\u003e String {\n        return \"Released \\(speed) ball with color \\(cricketBall.rawValue)\"\n    }\n}\n \nclass SlowBallStrategy : ReleaseCricketBallStrategy{\n    var speed = \"Slow\"\n    var cricketBall = CricketBall.slow\n    init(){}\n \n    func releaseBall() -\u003e String {\n        return \"Released \\(speed) ball with color \\(cricketBall.rawValue)\"\n    }\n}\n\n\n```\n\nNow, we define a BowlingMachine class which can be initialised at runtime by passing an argument of the type of strategy. We make it conform to CustomStringConvertible.\n\n```swift\nclass BowlingMachine : CustomStringConvertible {\n    private var releaseCricketBallStrategy : ReleaseCricketBallStrategy\n    private var returnString = \"\"\n    init(whatStrategy : ReleaseCricketBallStrategy){\n        self.releaseCricketBallStrategy = whatStrategy\n        returnString = releaseCricketBallStrategy.releaseBall()\n    }\n    var description: String{\n        return returnString\n    }\n}\n```\n\nIt’s now time to play with our bowling machine. We define a method named main where we initialise BowlingMachine class with different type of strategies. \n\n```swift\nfunc main(){\n    var bowlingMachine = BowlingMachine(whatStrategy: FastBallStrategy())\n    print(bowlingMachine.description)\n \n    bowlingMachine = BowlingMachine(whatStrategy: SlowBallStrategy())\n    print(bowlingMachine.description)\n \n    bowlingMachine = BowlingMachine(whatStrategy: MediumBallStrategy())\n    print(bowlingMachine.description)\n \n}\n\n```\n\nNow, run the main() method.\n```swift\nmain()\n```\n\nOutput in the Xcode console:\n\nReleased Fast ball with color Red\nReleased Slow ball with color Yellow\nReleased Medium ball with color Green\n\n\nSummary:\n\nStrategy pattern allows us to define a set of related algorithms and allows client to choose any of the algorithms at runtime. It allows us to add new algorithm without modifying existing algorithms.\n\n**19) Behavioral - Command Design Pattern:**\n\nDefinition:\n\nThe definition of Command provided in the original Gang of Four book on DesignPatterns states: \n\nEncapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.\n\nCommand is a behavioral design pattern that decouples the object that invokes the operation from the object that knows how to perform it. It lets us turn requests into stand-alone objects by providing request objects with all the necessary information for the action to be taken.\nUsage:\nLet us consider a decision review system in a cricket match where the on-field umpire is not sure if a batsman is out or not. This umpire then asks the TV Umpire to check TV replays and make a decision. The TV umpire then commands the TV operator to show OUT/ NOT OUT on the screen present in the ground depending upon the decision made. \n\nLet’s see how we can design such system with the help of Command design pattern.\n\n```swift\nimport UIKit\nimport Foundation\n \nprotocol Command{\n    func execute()\n}\n \nWe define a protocol named Command with a function named execute.\nclass ScreenDisplay{\n    private var showOutOnDisplay = false\n    \n    func isBatsmanOut(){\n        showOutOnDisplay = true\n        print(\"Batsman is OUT\")\n    }\n    \n    func isBatsmanNotOut(){\n        showOutOnDisplay = false\n        print(\"Batsman is NOTOUT\")\n    }\n \n}\n \n```\n\nWe then define a class called ScreenDisplay which is used to display the decision made by the TV umpire to public. It has a private variable named showOutOnDisplay which is initialised to false. \nIt has two methods defined. Based on the bool property, these methods show batsman OUT/ NOT OUT on the screen.\n\n```swift\nclass BatsmanOutCommand : Command{\n    var screenDisplay : ScreenDisplay\n    \n    init(_ screenDisplay : ScreenDisplay){\n        self.screenDisplay = screenDisplay\n    }\n    \n    func execute() {\n        screenDisplay.isBatsmanOut()\n    }\n}\n \nclass BatsmanNotOutCommand : Command{\n    var screenDisplay : ScreenDisplay\n    \n    init(_ screenDisplay : ScreenDisplay){\n        self.screenDisplay = screenDisplay\n    }\n    \n    func execute() {\n        screenDisplay.isBatsmanNotOut()\n    }\n}\n \n```\n\nWe then write two classes BatsmanOutCommand and BatsmanNotOutCommand conforming to Command protocol. Both these classes take a parameter of type ScreenDisplay during their initialisation. Then we write the definition of execute method by calling isBatsmanOut/ isBatsmanNotOut on ScreenDisplay object.\n\n```swift\nclass DisplaySwitch {\n    var command : Command\n    \n    init(_ command : Command) {\n        self.command = command\n    }\n    \n    func pressSwitch(){\n        command.execute()\n    }\n}\n```\n\nFinally, we write a class called DisplaySwitch which takes an object of type Command for its initialisation. We define a method called pressSwitch which implements the execute method on Command object.\nLet us write our main method and see our code in action.\n\n```swift\nfunc main(){\n    let screenDisplay = ScreenDisplay()\n    \n    let outCommand = BatsmanOutCommand(screenDisplay)\n    let notOutCommand = BatsmanNotOutCommand(screenDisplay)\n    \n    let displaySwitchForOut = DisplaySwitch(outCommand)\n    displaySwitchForOut.pressSwitch()\n    \n    let displaySwitchForNotOut = DisplaySwitch(notOutCommand)\n    displaySwitchForNotOut.pressSwitch()\n    \n}\n \nmain()\n```\n\nWe take an instance of ScreenDisplay and pass it to BatsmanOutCommand and BatsmanNotOutCommand for their initialisations. \n \nThen based on the decision made by the TV umpire, we initialise DisplaySwitch using outCommand / notOutCommand as the parameters. \n \nOutput in the Xcode console:\n \nBatsman is OUT\nBatsman is NOTOUT\n \nSummary:\n \nWhen you want to encapsulate the logical details of an operation in a separate entity and define specific instructions for applying the command, Command design pattern serves you the best. It also helps in creating composite commands.\n\n**20) Behavioral - Iterator Design Pattern:**\n\nDefinition:\n\nIteration in coding is a core functionality of various data structures. An iterator facilitates the the traversal of a data structure. Iterator is a behavioral design pattern that is used to sequentially access the elements of an aggregate object without exposing its underlying implementation.\n\nUsage:\n\nAssume we are making a list of top cricketers in current lot which includes their name and team name. We will now see how to use an Iterator to traverse through the list and print the profile of each cricketer.\n\nLet us write some code now:\n\n```swift\nimport Foundation\nstruct Cricketer{\n    let name : String\n    let team : String\n}\n```\n\nWe define a struct named Cricketer which stores name and team as String properties.\n\n```swift\nstruct Cricketers{\n    let cricketers : [Cricketer]\n}\n```\n\nWe define another struct named Cricketers which stores cricketers Array of custom type Cricketer.\n\n```swift\nstruct CricketersIterator : IteratorProtocol{\n    \n    private var current = 0\n    private let cricketers : [Cricketer]\n    \n    init(_ cricketers : [Cricketer]) {\n        self.cricketers = cricketers\n    }\n    \n    mutating func next() -\u003e Cricketer? {\n        defer {\n            current += 1\n        }\n        if cricketers.count \u003e current{\n            return cricketers[current]\n        } else{\n            return nil\n        }\n    }\n    \n}\n\nextension Cricketers : Sequence{\n    func makeIterator() -\u003e CricketersIterator {\n        return CricketersIterator(cricketers)\n    }\n}\n\n```\n\nThis is where the magic happens. We define a struct named CricketersIterator conforming to IteratorProtocol. Then we write an extension for Cricketers which conforms to Sequence protocol.\n\nApple says ,\n\nThe IteratorProtocol protocol is tightly linked with the Sequence protocol. Sequences provide access to their elements by creating an iterator, which keeps track of its iteration process and returns one element at a time as it advances through the sequence.\nWhenever you use a for-in loop with an array, set, or any other collection or sequence, you’re using that type’s iterator. Swift uses a sequence’s or collection’s iterator internally to enable the for-in loop language construct.\nUsing a sequence’s iterator directly gives you access to the same elements in the same order as iterating over that sequence using a for-in loop.\n\nBack to our code, we defined two private properties current of type Int (with default value of 0) and an array cricketers of type Cricketer. \n\nWe define a method next which returns an object of type Cricketer (notice the optional - we may not have any element left in the array after we reach the last element).\n\nLet us now write our main method:\n\n```swift\nfunc main(){\n    let cricketers = Cricketers(cricketers: [Cricketer(name: \"Kohli\", team: \"India\"), Cricketer(name: \"Steve\", team: \"Australia\"), Cricketer(name: \"Kane\", team: \"Kiwis\"), Cricketer(name: \"Root\", team: \"England\")])\n    for crick in cricketers{\n        print(crick)\n    }\n}\n \nmain()\n```\n\nOutput in the Xcode console:\n \nCricketer(name: \"Kohli\", team: \"India\")\nCricketer(name: \"Steve\", team: \"Australia\")\nCricketer(name: \"Kane\", team: \"Kiwis\")\nCricketer(name: \"Root\", team: \"England\")\n \nAdding the code snippet for another self explanatory example here which would enhance your understanding:\n\n```swift\nimport Foundation\n \nclass Cricketer : Sequence\n{\n    var totalRunsScored = [Int](repeating: 0, count: 3)\n    \n    private let _testRuns = 0\n    private let _ODIRuns = 1\n    private let _t20Runs = 2\n    \n    var testRuns: Int\n    {\n        get { return totalRunsScored[_testRuns] }\n        set(value) { totalRunsScored[_testRuns] = value }\n    }\n    \n    var ODIRuns: Int\n    {\n        get { return totalRunsScored[_ODIRuns] }\n        set(value) { totalRunsScored[_ODIRuns] = value }\n    }\n    \n    var t20Runs: Int\n    {\n        get { return totalRunsScored[_t20Runs] }\n        set(value) { totalRunsScored[_t20Runs] = value }\n    }\n    \n    var totalRuns: Int\n    {\n        return totalRunsScored.reduce(0, +)\n    }\n    \n    subscript(index: Int) -\u003e Int\n    {\n        get { return totalRunsScored[index] }\n        set(value) { totalRunsScored[index] = value }\n    }\n    \n    func makeIterator() -\u003e IndexingIterator\u003cArray\u003cInt\u003e\u003e\n    {\n        return IndexingIterator(_elements: totalRunsScored)\n    }\n}\n \nfunc main()\n{\n    let cricketer = Cricketer()\n    cricketer.testRuns = 1200\n    cricketer.ODIRuns = 1800\n    cricketer.t20Runs = 600\n \n    print(\"Total R","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvamshiiitbhu14%2Fdesignpatternsinswift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvamshiiitbhu14%2Fdesignpatternsinswift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvamshiiitbhu14%2Fdesignpatternsinswift/lists"}