Creating a data repository with generics and protocols

Now, we want to create a repository that provides us with entities so that we can apply the functional programming features included in Swift to retrieve and process data from these entities. First, we will create an Identifiable protocol that defines the requirements for an identifiable entity. We want any class that conforms to this protocol to have a read-only id property of the Int type to provide a unique identifier for the entity. The code file for the sample is included in the swift_3_oop_chapter_07_11 folder:

    import Foundation  
    public protocol Identifiable { 
      var id: Int { get } 
    } 

The next lines create a Repository<Element> generic class, which specifies that Element must conform to the recently created Identifiable protocol in the generic type constraint. The class declares a getAll method that we will override in the subclasses. The code file for the sample is included in the swift_3_oop_chapter_07_11 folder:

    open class Repository<Element: Identifiable> { 
      open func getAll() -> [Element] { 
        return [Element]() 
      } 
    }  

The next lines create the Entity class, which is the base class for all the entities. The class conforms to the Identifiable protocol and defines a read-only id property of the Int type. The code file for the sample is included in the swift_3_oop_chapter_07_11 folder:

    open class Entity: Identifiable { 
      open let id: Int 
 
      init(id: Int) { 
        self.id = id 
      } 
    }

The next lines create the Game class, which is a subclass of Entity, which conforms to the CustomStringConvertible protocol. The class adds the following stored properties: name, highestScore, and playedCount. The CustomStringConvertible protocol requires the class to implement a description calculated property that Swift uses whenever we write values to the output string. This way, whenever we use print and specify an instance of the Game class, Swift will print the value for the description calculated property. The code file for the sample is included in the swift_3_oop_chapter_07_11 folder:

    open class Game: Entity, CustomStringConvertible {
      open var name: String
      open var highestScore: Int
      open var playedCount: Int
 
      open var description: String {
        get {
          return "id: (id), name: "(name)", highestScore: 
          (highestScore), playedCount: (playedCount)"
        }
      }
 
      init(id: Int, name: String, highestScore: Int, 
      playedCount: Int) {
        self.name = name
        self.highestScore = highestScore
        self.playedCount = playedCount
        super.init(id: id)
      }
    }

The following lines create the GameRepository class, a subclass of Repository<Game>. The class overrides the getAll method declared in the generic superclass, that is, in the Repository<T> class. In this case, the method returns an array of Game, Array<Game>, specified with the [Game] shortcut. The overridden method creates ten Game instances and appends them to an array of Game that the method returns as a result. Note that we use underscores as separators to make it easier to read integer numbers. For example, instead of writing 3050, we write 3_050, and it is equivalent to 3050. This way, we can easily realize that it is three thousand and fifty. The code file for the sample is included in the swift_3_oop_chapter_07_11 folder:

    open class GameRepository: Repository<Game> { 
      open override func getAll() -> [Game] { 
        var gamesList = [Game]() 
 
        gamesList.append(Game(id: 1, name: "Invaders 2017", 
        highestScore: 1050, playedCount: 3_050)) 
 
        gamesList.append(Game(id: 2, name: "Minecraft", 
        highestScore: 3741050, playedCount: 780_009_992)) 
 
        gamesList.append(Game(id: 3, name: "Minecraft Story Mode", 
        highestScore: 67881050, playedCount: 304_506_506)) 
 
        gamesList.append(Game(id: 4, name: "Soccer Warriors", 
        highestScore: 10_025, playedCount: 320_450)) 
 
        gamesList.append(Game(id: 5, name: "The Walking Dead Stories", 
        highestScore: 1_450_708, playedCount: 75_405_350)) 
 
        gamesList.append(Game(id: 6, 
        name: "Once Upon a Time in Wonderland", 
        highestScore: 1_050_320, playedCount: 7_052)) 
 
        gamesList.append(Game(id: 7, name: "Cars Forever", 
        highestScore: 6_705_203, playedCount: 850_021)) 
 
        gamesList.append(Game(id: 8, name: "Jake & Peter Pan", 
        highestScore: 4_023_134, playedCount: 350_230)) 
 
        gamesList.append(Game(id: 9, name: "Kong Strikes Back", 
        highestScore: 1_050_230, playedCount: 450_050)) 
 
        gamesList.append(Game(id: 10, name: "Mario Kart 2017", 
        highestScore: 10_572_340, playedCount: 3_760_879)) 
 
        return gamesList 
      } 
    } 

The following lines create an instance of GameRepository and call the forEach method for the array of Game returned by the getAll method. The forEach method calls a body on each element in the array, as is done in a for in loop. The closure specified as an argument for the forEach method calls the print method with the Game instance as an argument. This way, Swift uses the description computed property to generate a String representation for each Game instance. The code file for the sample is included in the swift_3_oop_chapter_07_11 folder:

    var gameRepository = GameRepository() 
    gameRepository.getAll().forEach({ (game) in print(game) })

The following lines show the output generated by the preceding code:

id: 1, name: "Invaders 2017", highestScore: 1050, playedCount: 3050

id: 2, name: "Minecraft", highestScore: 3741050, playedCount: 780009992

id: 3, name: "Minecraft Story Mode", highestScore: 67881050, 
    playedCount: 304506506

id: 4, name: "Soccer Warriors", highestScore: 10025,
    playedCount: 320450

id: 5, name: "The Walking Dead Stories", highestScore: 1450708, 
    playedCount: 75405350

id: 6, name: "Once Upon a Time in Wonderland", highestScore: 1050320, 
    playedCount: 7052

id: 7, name: "Cars Forever", highestScore: 6705203, 
    playedCount: 850021

id: 8, name: "Jake & Peter Pan", highestScore: 4023134, 
    playedCount: 350230

id: 9, name: "Kong Strikes Back", highestScore: 1050230, 
    playedCount: 450050

id: 10, name: "Mario Kart 2017", highestScore: 10572340, 
    playedCount: 3760879

The following screenshot shows the result of executing the previous lines in the Playground:

Creating a data repository with generics and protocols

The following line uses the argument shorthand notation, which is equivalent to the last line, and produces the same result. The code file for the sample is included in the swift_3_oop_chapter_07_12 folder:

    gameRepository.getAll().forEach({ print($0) }) 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.128.168