Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Swift 2 Design Patterns
Swift 2 Design Patterns

Swift 2 Design Patterns: Build robust and scalable iOS and Mac OS X game applications

eBook
£7.99 £16.99
Paperback
£20.99
Subscription
Free Trial
Renews at £16.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Billing Address

Table of content icon View table of contents Preview book icon Preview Book

Swift 2 Design Patterns

Chapter 1. Creational Patterns

The creational patterns are designed to deal with the object creation mechanism in software designing. A system using these patterns becomes independent of how objects are created, which means it is independent of how concrete classes are instantiated.

These patterns encapsulate the use of concrete classes and favor the use of interfaces in the relationship between objects, allowing to have better abstraction of the global system conception.

Thus, if we analyze the singleton pattern, a pattern designed to instantiate only one instance of a class, we find that the mechanism that controls the unique access to this instance is fully encapsulated in the class, which means that this is completely transparent to the client consuming the instance of the class.

In this chapter, we will introduce you to the five creational patterns and discuss how we can use them with Swift:

  • The prototype pattern
  • The factory method pattern
  • The singleton pattern
  • The abstract factory pattern
  • The builder pattern

The objectives of these patterns are described in the following table:

Pattern

Objective

The prototype pattern

This pattern allows you to create new objects by duplicating existing objects called prototypes. This pattern has the cloning capability.

The factory method pattern

This pattern introduces you to an abstract method that allows you to create an object by telling its subclasses about the effective creation of the object.

The singleton pattern

This pattern ensures that a class has only one instance. This class provides a unique point of access that returns this instance.

The abstract factory pattern

This pattern allows you to create an object that is grouped in families by hiding the concrete classes that are needed to create these objects.

The builder pattern

This pattern allows you to separate the creation of complex objects from their implementation. This permits a client to create complex objects having different representations.

The prototype pattern

Our first pattern will be the prototype pattern; we will see how we can use it to accelerate the creation of an instance. We will see how we can use it to copy an existing instance, and eventually, we will see how to modify the new one to our needs.

Roles

The prototype pattern is used to create a new object by duplicating existing objects called prototypes, and they have a cloning capability.

This pattern is used in the following use cases:

  • When you need to create an instance without knowing the hierarchy of a class
  • When you need to create class instances that are dynamically loaded
  • When you need to have a simple object system and not include a parallel hierarchy of a factory class

Design

The following diagram shows the generic class of the prototype pattern:

Design

Participants

Participant to this pattern are as follows:

  • Client: This class contains a list of objects called prototypes that are instances of the AbstractPrototype abstract class. The Client class needs to clone these prototypes without having to know their internal structure and subclass hierarchy.
  • AbstractPrototype: This is an abstract class that can duplicate itself. This class contains a cloning method called clone().
  • ConcretePrototype1 and ConcretePrototype2: These are concrete classes that inherit from the AbstractPrototype class. They define a prototype and have both a cloning method called clone().

Collaborations

The client asks to one or more prototypes to clone themselves.

Illustration

A simple and real example of where this pattern can be applied is the famous game HeartStone from Blizzard (the creator of World of Warcraft). In this strategy card game, when you spend "mana" to use spells, weapons, or put a minion on the board, there is a special minion that has the ability to clone a particular card. When a player uses this card, it selects the minion that he or she wants to clone and the card becomes an exact copy of the selected card. The following card represent the "HeartStone" card that have this behavior:

Illustration

Implementation

The following code represent the implementation of the pattern using Swift:

import UIKit

class AbstractCard {
  var name: String?
  var mana: Int?
  var attack: Int?
  var defense: Int?
  
  init(name:String?, mana:Int?, attack:Int?, defense:Int?) {
    self.name = name
    self.attack = attack
    self.defense = defense
    self.mana = mana
  }
  
  func clone() -> AbstractCard {
    return AbstractCard(name: self.name, mana: self.mana, attack: self.attack, defense: self.defense)
  }
}

class Card: AbstractCard {
  
  override init(name:String?, mana:Int?, attack:Int?, defense:Int? ) {
    super.init(name: name,mana: mana,attack: attack,defense: defense)

  }
}

Note

The AbstractPrototype class is our AbstractCard class, where we implement a way to return a copy of itself using the clone() method.

Usage

The following code simulate how the client will interact with the Card object which implement the prototype pattern:

// Simulate our client

// This is the card that we will copy
let raidLeader = Card(name: "Raid Leader", mana: 3, attack: 2, defense: 2)

// Now we use our faceless Manipulator card to clone the raidleader
let facelessManipulator = raidLeader.clone()

print("\(facelessManipulator.name, facelessManipulator.mana, facelessManipulator.attack, facelessManipulator.defense)")

Since the code is written in a Playground file, you should consider it as the code that you'll put in the Client class.

First, we instantiate a new card named Raid Leader. This is a concrete prototype class. Let say that you have the "Faceless Manipulator" card and you want to use it to clone the "Raid Leader" card, then you simply need to use the raidLeader.clone() method that will return a new instance with the exact same properties as "Raid Leader".

By checking the details on the right-hand side of the Playground file, you'll see that the facelessManipulator constant has exactly the same properties as raidLeader (line 39), as shown in the following screenshot:

Usage

The factory method pattern

Our second pattern is a very well-known pattern. It introduces you to the famous concept: "Program to an interface, not an implementation." The instantiation is done in the factory class that depends on the type that we need and the type that needs to be returned to the client.

Roles

The factory method pattern is one of the most used patterns in software designs. The purpose of this pattern is to abstract the creation of an object. The factory method lets a class defer instantiation to subclasses.

You'll see from that time to time that we have mentioned "program to an interface." This is exactly what this pattern does. With Swift, instead of an interface, you'll code with the "protocol" instead of the class itself.

This pattern is used in the following use cases:

  • A class only knows about abstract classes or interfaces of objects with whom it has some relationships
  • A class wants its subclasses to instantiate the object in order to benefit of polymorphism mechanism

Design

The following diagram shows the generic class of the factory method pattern:

Design

Participants

Participant to this pattern are as follows:

  • Product interface: This class contains the definition of our product. We will define what a card is here.
  • Abstract product: This abstract class implements the signature of our cards and some methods. You'll see that we keep the prototype pattern that allows us to eventually clone a card. These classes define the properties of our products.
  • Concrete product: This class defines our product; in our example, the Raid Leader card is a concrete product, such as the Faceless Manipulator card.
  • Concrete creator: This class implements our factory method.

Illustration

In our previous pattern, you would have seen the following line:

let raidLeader = Card(name: "Raid Leader", mana: 3, attack: 2, defense: 2)

Here, we directly program an implementation. We need a way to create some cards, but without having the knowledge to know exactly how to construct the card; we can only tell to create the raidLeader and Faceless Manipulator cards. At this point of time, the client doesn't want to know that the Raid Leader card needs three manas, so it provides two points of attack and two points of defense.

Implementation

The implementation of the factory method pattern is as follows:

import UIKit
import Foundation

//Define what a card is
protocol Card {
  var name: String? {get set}
  var attack: Int? {get set}
  var defense: Int? {get set}
  var mana: Int? {get set}
  func clone() -> Card
  func toString() -> String
}

// AbstractCard
// implements the signature and some properties
class AbstractCard: NSObject, Card {
  private var _name: String?
  private var _mana: Int?
  private var _attack: Int?
  private var _defense: Int?
  
  init(name: String?, mana: Int?, attack: Int?, defense: Int?) {
    self._name = name
    self._attack = attack
    self._defense = defense
    self._mana = mana
    super.init()
  }
 
  override init(){
    super.init()
  }
  
  //property name
  var name: String?{
    get{ return _name }
    set{ _name = newValue }
  }
  
  //property mana
  var mana: Int? {
    get{ return _mana }
    set{ _mana = newValue }
  }
  
  //property attack
  var attack: Int? {
    get{ return _attack }
    set{ _attack = newValue }
  }
  
  //property attack
  var defense: Int? {
    get{ return _defense }
    set{ _defense = newValue }
  }
  
  func clone() -> Card {
    return AbstractCard(name: self.name, mana: self.mana, attack: self.attack, defense: self.defense)
  }
  
  func toString() -> String{
    return ("\(self.name, self.mana, self.attack,self.defense)")
  }
}

enum CardType {
  case FacelessManipulator, RaidLeader
}

// our Factory Class
// Depending what we need, this class return an instance of the 
// appropriate object.
class CardFactory{
  class func createCard(cardtype: CardType) -> Card?{
    
    switch cardtype {
    case .FacelessManipulator:
      return FacelessManipulatorCard()
    case .RaidLeader:
      return RaidLeaderCard()
    default:
      return nil
    }
  }
}

//Concrete Card "Raid Leader"
//This is the full definition of the Raid Leader Card
class RaidLeaderCard: AbstractCard {
  override init()
  {
    super.init()
    self._mana = 3
    self._attack = 2
    self._defense = 2
    self._name = "Raid Leader"
  }
}

//Concrete Card "Faceless Manipulator"
//this is the full definition of the FacelessManipulator Card.
class FacelessManipulatorCard: AbstractCard {
  override init()
  {
    super.init()
    self._mana = 5
    self._attack = 3
    self._defense = 3
    self._name = "Faceless Manipulator"
    
  }
}

Usage

To simulate the use of the factory method pattern by a client, we can write the card creation as follows:

//simulate our client

var c = CardFactory.createCard(.FacelessManipulator)
c?.toString()

Note

To simulate our client, we simply tell the CardFactory method that we want a FacelessManipulator card.

To do this, we use the createCard method (our factory method), and this method will delegate the instantiation of the card that was asked.

The variable c has the type Card and not FacelessManipulator.

The singleton pattern

This pattern is certainly the pattern that every developer learns first. It is often used with a factory or abstract factory class to ensure that there is only one instance of the class.

Roles

The singleton pattern ensures that a class has only one instance and provides a global point of access to it, and at this point, it returns an instance of this class.

In some cases, it can be useful to have some classes that have only one instance; for example, in the case of the abstract factory, where it is not useful to have several instances.

Design

The following figure shows the generic UML class diagram of the singleton pattern. There are many way to write the singleton pattern using Swift.

Here, we use the easiest way to do this. With Swift, you'll see that we can change the way in which we apply it, thanks to the class constant:

Design

Participants

There is only one participant in this pattern: the Singleton class.

This class provides a method that returns only one instance of the class. The mechanism locks the creation of other instances. It was introduced with Swift 1.2. We can now use class constants.

With Swift 1.2, we will use the class constants to provide us with a way to ensure the unique creation of the instance.

A class constant is defined as follows:

static let myVariable = myObject()

Collaborations

Every client will have access to the unique instance of the Singleton class by calling the Instance method.

With Swift, the approach we'll consider is the one that accesses our unique instance of the Singleton class using the class constant that we will call sharedInstance.

Illustration

You are developing your card game and you need to manage all the data of the current game. In our game, we have two players; each player has a deck, mana reserve, name, and so on. We have a board (the table where we put our cards) and a game state (who is currently playing). To manage all of this information, you'll need a BoardManager class. This class will be a singleton class because we will not have several boards at the same time (we only allow one game at a time). The singleton pattern can be something interesting that can be used here in order to make sure that we access the good data.

Implementation

The following approach supports lazy initialization, and it is thread safe by the definition of let:

import UIKit

class BoardGameManager {
  
  static let sharedInstance = BoardGameManager()
  init() {
    println("Singleton initialized");
  }
  
}

Usage

To use our singleton object, each client will access it using the following code :

let boardManager = BoardGameManager.sharedInstance

The boardManager variable contains all the members available in our singleton object and will be initialized only once.

This pattern is used in the following cases:

  • We must have only one instance of a class
  • This instance must be accessible to clients from a well-known access point

The abstract factory pattern

We already introduced you to a very popular concept in design patterns: factories. Factories are the classes that handle the instantiation of related objects without subclassing. The factory method pattern that we have already seen hides the class name from where an object is instantiated. The abstract factory pattern is more complete as it creates families of related or dependent objects.

Roles

The abstract factory pattern is designed to build objects grouped in families without having to know the concrete class needed to create the object.

This pattern is generally used in the following domains:

  • A system that uses products needs to stay independent of how these products are grouped and instantiated
  • A system can have several product families that can evolve

Design

The following diagram represents the generic structure of the abstract factory pattern. You will see how products and families are decoupled:

Design

Participants

The abstract factory pattern has a lot of participants:

  • Abstract Factory: This abstract class defines the signature of the different methods that create our products.
  • ConcreteFactory1 and ConcreteFactory2: These are our concrete classes that implement our methods for each products' families. By knowing the family and product, the factory is able to create an instance of the product for that family.
  • IProductA and IProductB: These are our interfaces that define our products that are independent of their family. A family is introduced in their concrete subclasses.
  • ProductA and ProductB: These are the concrete classes that implement IProductA and IProductB, respectively.

Collaborations

The Client class uses one instance of one of the concrete factories to create products throughout the interface of the abstract factory.

Illustration

Our company specializes in manufacturing watches. Our watches are built in two parts: a band and dial. Our watches come in two sizes, so we must adapt the manufacturing of the band and dial according to the size of our watch.

In order to simplify how to manage the manufacturing of our watches, the direction team decided to use one manufacturer who specializes in products that are adapted to the 38 mm model of our watch, and another manufacturer whose products are adapted to the 42 mm model of our watch.

Each of these manufacturers will build a dial and band that are adapted to the dimension of the watch.

Implementation

To implement our pattern, we first need to identify our actors. The two manufacturers represent the ConcreteFactory1 and ConcreteFactory2 classes. These two factories implement the AbstractFactory method, which tell us that we can create a band or dial. Of course, the concrete factories will create the dial adapted to the size of the watch produced in that manufacture.

Our ConcreteProductA and ConcreteProductB classes are the band and the dial; each of these products implements their respective IProductA and IProductB interfaces, as shown in the following code:

import UIKit

//Our interfaces
protocol IWatchBand {
  var color: UIColor{get set}
  var size: BandSize{get set}
  var type: BandType{get set}
  init(size: BandSize)
}

protocol IWatchDial {
  var material: MaterialType{get set}
  var size: WatchSize{get set}
  init(size: WatchSize)
}

//Enums
enum MaterialType: String {
  case Aluminium = "Aluminium",
  StainlessSteel = "Stainless Steel",
  Gold = "Gold"
}

enum BandType: String {
  case Milanese = "Milanese",
  Classic = "Classic",
  Leather = "Leather",
  Modern = "Modern",
  LinkBracelet = "LinkBracelet",
  SportBand = "SportBand"
}

enum WatchSize: String {
  case _38mm = "38mm", _42mm = "42mm"
}

enum BandSize: String {
  case SM = "SM", ML = "ML"
}

//prepare our Bands components
class MilaneseBand: IWatchBand {
  var color = UIColor.yellowColor()
  var size: BandSize
  var type = BandType.Milanese
  required init(size _size: BandSize) {
    size = _size
  }
 }

class Classic: IWatchBand {
  var color = UIColor.yellowColor()
  var size: BandSize
  var type = BandType.Classic
  required init(size _size: BandSize) {
    size = _size
  }
}
class Leather:IWatchBand{
  var color = UIColor.yellowColor()
  var size:BandSize
  var type = BandType.Leather
  required init(size _size: BandSize) {
    size = _size
  }
}
class Modern: IWatchBand {
  var color = UIColor.yellowColor()
  var size: BandSize
  var type = BandType.Modern
  required init(size _size: BandSize) {
    size = _size
  }
}

class LinkBracelet: IWatchBand {
  var color = UIColor.yellowColor()
  var size: BandSize
  var type = BandType.LinkBracelet
  required init(size _size: BandSize) {
    size = _size
  }
}
class SportBand: IWatchBand {
  var color = UIColor.yellowColor()
  var size: BandSize
  var type = BandType.SportBand
  required init(size _size: BandSize) {
    size = _size
  }
}


//Dials
class AluminiumDial: IWatchDial {
  var material: MaterialType = MaterialType.Aluminium
  var size: WatchSize
  required init(size _size:WatchSize){
    size = _size
  }
}

class StainlessSteelDial: IWatchDial {
  var material: MaterialType = MaterialType.StainlessSteel
  var size: WatchSize
  required init(size _size:WatchSize){
    size = _size
  }
}

class GoldDial: IWatchDial {
  var material: MaterialType = MaterialType.Gold
  var size: WatchSize
  required init(size _size:WatchSize){
    size = _size
  }
}


//Our AbstractFactory
class WatchFactory {
  
  func createBand(bandType: BandType) -> IWatchBand {
    fatalError("not implemented")
  }
  func createDial(materialtype: MaterialType) -> IWatchDial{
    fatalError("not implemented")
  }
  
  //our static method that return the appropriated factory.
  final class func getFactory(size: WatchSize) -> WatchFactory{
    var factory: WatchFactory?
    switch(size){
    case ._38mm:
      factory = Watch38mmFactory()
    case ._42mm:
      factory = Watch42mmFactory()
    }
    return factory!
  }

}


// Concrete Factory 1 for 42 mm
class Watch42mmFactory: WatchFactory {
  override func createBand(bandType: BandType) -> IWatchBand {
    switch bandType {
    case .Milanese:
      return MilaneseBand(size: .ML)
    case .Classic:
      return Classic(size: .ML)
    case .Leather:
      return Leather(size: .ML)
    case .LinkBracelet:
      return LinkBracelet(size: .ML)
    case .Modern:
      return Modern(size: .ML)
    case .SportBand:
      return SportBand(size: .ML)
    default:
      return SportBand(size: .ML)
    }
  }
  
  override func createDial(materialtype: MaterialType) -> IWatchDial {
    switch materialtype{
    case MaterialType.Gold:
      return GoldDial(size: ._42mm)
    case MaterialType.StainlessSteel:
      return StainlessSteelDial(size: ._42mm)
    case MaterialType.Aluminium:
      return AluminiumDial(size: ._42mm)
    }
  }
}

//Concrete Factory 2 for 38mm
class Watch38mmFactory: WatchFactory{
  override func createBand(bandType:BandType) -> IWatchBand {
    switch bandType {
    case .Milanese:
      return MilaneseBand(size: .SM)
    case .Classic:
      return Classic(size: .SM)
    case .Leather:
      return Leather(size: .SM)
    case .LinkBracelet:
      return LinkBracelet(size: .SM)
    case .Modern:
      return Modern(size: .SM)
    case .SportBand:
      return SportBand(size: .SM)
    default:
      return SportBand(size: .SM)
    }
  }
  
  override func createDial(materialtype: MaterialType) -> IWatchDial {
    switch materialtype{
    case MaterialType.Gold:
      return GoldDial(size: ._38mm)
    case MaterialType.Gold:
      return StainlessSteelDial(size: ._38mm)
    case MaterialType.Gold:
      return AluminiumDial(size: ._38mm)
    default:
      return AluminiumDial(size: ._38mm)
      
    }
  }
}

Usage

To simulate our client, we will use the following code:

//Here we deliver products from the Manufacture 1 specialized in
//products for the 38 mm Watch
let manufacture1 = WatchFactory.getFactory(WatchSize._38mm)
let productA = manufacture1.createBand(BandType.Milanese)
productA.color
productA.size.rawValue
productA.type.rawValue

let productB = manufacture1.createDial(MaterialType.Gold)
productB.material.rawValue
productB.size.rawValue


//Here we delivers products from the Manufacture 2 specialized in
//products for the 42 mm Watch
let manufacture2 = WatchFactory.getFactory(WatchSize._42mm)
let productC = manufacture2.createBand(BandType.LinkBracelet)
productC.color
productC.size.rawValue
productC.type.rawValue

let productD = manufacture2.createDial(MaterialType.Gold)
productD.material.rawValue
productD.size.rawValue

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

The Playground file will display our product's properties, depending on the factory used. The details of product A (the band) and product B (the dial) from the manufacture1 object are shown in the following screenshot:

Usage

The details of product C (the band) and product D (the dial) from the manufacture2 object are shown in the following screenshot:

Usage

The sizes of the band and the dial adapt to the manufacturer who delivers the product.

Note

We should use the singleton pattern to ensure that we have only one instance of our abstract factory. This instance can be shared between several clients.

The builder pattern

Unlike the abstract factory pattern, which will produce parts of products of the same family, the builder pattern will help us build the finalized product that consists of several parts.

Roles

The main purpose of the builder pattern is to abstract the building of complex objects from its actual construction. Having the same construction process can create different representations of the product.

This pattern can be used when:

  • A client needs to construct complex objects without having to know its implementation
  • A client needs to construct complex objects that need to have several implementations or representations

Design

The following figure shows the generic UML class diagram of the builder pattern:

Design

Participants

This pattern is quite simple as it has only a few participants:

  • Director: This class constructs the product using the interface of the AbstractBuilder class.
  • AbstractBuilder: This class defines the method signature that allows the construction of all the parts of the product, and it contains a signature of a method that returns the product once this is built.
  • ConcreteBuilder: This is the Concrete class that implements the method of the AbstractBuilder class.
  • Product: This is the finalized product. The product contains all the parts of the watch.

Collaborations

The client creates the ConcreteBuilder and Director classes. The Director class will then build an object if the client asks him to do so by invoking the constructor and returns the finalized product to the client.

Illustration

Using the AbstractFactory method, we can use the builder pattern to build a watch. As we've seen that a watch has several parts: a dial and band. A watch can have two sizes too, and as we have already seen, the representation of the dial or band depends on the size of the watch too.

Implementation

If we want to build some watches that are represented with a dial and band, we will define a Director class that will define the construction order of all the parts of our watches and return the finalized watch to the client.

The Director class will call all the constructors who are in charge to construct one part of the watch. To implement this, we will reuse the existing code of the abstract factory pattern and add the following code.

Open the Builder.playground file in Xcode to see the added code at the bottom of the file:

//Our builder1
class BuilderGoldMilanese38mmWatch: AbstractWatchBuilder {
  override func buildDial() {
    watch.band = MilaneseBand(size: BandSize.SM)
  }
  override func buildBand() {
    watch.dial = GoldDial(size: WatchSize._38mm)
  }
}

//Our builder2
class BuilderAluminiumSportand42mmWatch:AbstractWatchBuilder {
  override func buildDial() {
    watch.band = SportBand(size: BandSize.ML)
  }
  override func buildBand() {
    watch.dial = AluminiumDial(size: WatchSize._42mm)
  }
}

//our Director class
class Director {
  var builder: AbstractWatchBuilder?
  init(){
    
  }
  
  func buildWatch(builder: AbstractWatchBuilder){
    builder.buildBand()
    builder.buildDial()
  }
}

Usage

To simulate our client, we will tell our director to create two watches:

  • A 42 mm aluminium dial with a sports band
  • A 38 mm gold dial with a milanese band

The code for the example is as follows:

//We will build 2 Watches :
//First is the Aluminium Dial of 42mm with Sport Band
let director = Director()
var b1 = BuilderAluminiumSportand42mmWatch()
director.buildWatch(b1)

// our watch 1
var w1 = b1.getResult()
w1.band?.color
w1.band?.type.rawValue
w1.band?.size.rawValue
w1.dial?.size.rawValue
w1.dial?.material.rawValue

//Our 2nd watch is a Gold 38mm Dial with Milanese Band
var b2 = BuilderGoldMilanese38mmWatch ()
director.buildWatch(b2)

// Our watch 1
var w2 = b2.getResult()
w2.band?.color
w2.band?.type.rawValue
w2.band?.size.rawValue
w2.dial?.size.rawValue
w2.dial?.material.rawValue

The result is shown in Playground like this:

Usage

Note

Swift allows the use of closure that simplifies the creation of our complex objects. Regarding the example that we provided earlier, we can write the following code to build our two watches.

Implementation using closures

Here, we don't need to use the Director and ConcreteBuilder classes. Instead, we will tell our Watch class that the builder will be in the closure.

In the previous example, remove the Director, AbstractBuilder, and ConcreteBuilder classes.

We just need to write the Watch class, as shown in the following code (you can find the following code in the BuilderClosures.playground file accompanying this chapter):

//our Product Class : a Watch
//The builder will be in the closure
class Watch{
  var dial:IWatchDial?
  var band:IWatchBand?
  typealias buildWatchClosure = (Watch) -> Void
  
  init(build:buildWatchClosure){
    build(self)
  }
}

Then, to simulate our client, we can write the following code which will call the appropriate constructor assigned to the band or dial property of the Watch object:

//Simulate our clients

let Gold42mmMilaneseWatch = Watch(build: {
  $0.band = MilaneseBand(size: BandSize.ML)
  $0.dial = GoldDial(size: WatchSize._42mm)
})

The result is as follows:

Implementation using closures

Summary

Well, I hope that this chapter was a good introduction to the use of patterns using Swift. We learned the five creational patterns: the prototype pattern, the factory method pattern, the singleton pattern, the abstract factory pattern, and the builder pattern. We also learned when to use them and how to implement them.

In the next chapter, we will introduce you to three structural patterns that are designed to ease the relationship between entities.

Left arrow icon Right arrow icon

Description

Swift is a multi-paradigm language. It has expressive features familiar to those used to work with modern functional languages, while also keeping the object-oriented features of Objective-C. It remains compatible with Apple’s legacy codes and frameworks. A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples. Knowledge about design patterns is also one of the best ways to make you different compared to other low-level developers. This book shows you how to use Swift 2 to learn about 23 Gang of Four (GoF) design patterns, and is organized into three categories. The book will present you the five creational patterns, followed by the seven structural patterns, and finishing with the 11 behavioral patterns as defined by the GoF. Each chapter will introduce the pattern by defining its role, which common problems the pattern should be used for, its generic UML representation, how each objects presented in the class diagram participate in the pattern, and what the role of each of these objects is. The book then presents you with a concrete case as an illustration that will be used to implement the pattern using Swift.

Who is this book for?

This book is intended for competent Swift developers who want to apply enduring design patterns with Swift to structure and scale their application code.

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Oct 28, 2015
Length: 224 pages
Edition : 1st
Language : English
ISBN-13 : 9781785886119
Vendor :
Apple
Category :
Languages :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Billing Address

Product Details

Publication date : Oct 28, 2015
Length: 224 pages
Edition : 1st
Language : English
ISBN-13 : 9781785886119
Vendor :
Apple
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
£16.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
£169.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just £5 each
Feature tick icon Exclusive print discounts
£234.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just £5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total £ 85.97
Swift 2 Design Patterns
£20.99
Swift High Performance
£27.99
Swift 2 Blueprints
£36.99
Total £ 85.97 Stars icon
Banner background image

Table of Contents

9 Chapters
1. Creational Patterns Chevron down icon Chevron up icon
2. Structural Patterns – Decorator, Proxy, and Bridge Chevron down icon Chevron up icon
3. Structural Patterns – Composite and Flyweight Chevron down icon Chevron up icon
4. Structural Patterns – Adapter and Facade Chevron down icon Chevron up icon
5. Behavioral Patterns – Strategy, State, and Template Method Chevron down icon Chevron up icon
6. Behavioral Patterns – Chain of Responsibility and Command Chevron down icon Chevron up icon
7. Behavioral Patterns – Iterator, Mediator, and Observer Chevron down icon Chevron up icon
8. Behavioral Patterns – Visitor, Interpreter, and Memento Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
(2 Ratings)
5 star 50%
4 star 0%
3 star 0%
2 star 0%
1 star 50%
Nasser Nov 17, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book helped me to my current project . It is very clear . I recommend it .
Amazon Verified review Amazon
commiepinkofag Dec 18, 2015
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
This book verges on the surreal in its awfulness. It reads like a 1982 VCR manual translated from Japanese into English by a native speaker of Italian. Truly - nearly every paragraph has some terrible linguistic convolution stunning in its cluelessness. Imagine 2001's HAL, had he been an autistic child. The author thinks nothing of beginning any number of successive sentences with the same words and seems to regard all articles and conjunctions as interchangeable. Misspellings, typos, syntax & tense errors, and word misusage all abound. The result is a droning, bizarrely robotic glossolalia overflowing with numbing repetition punctuated by strange quirks and distractions, all of which achieves the goal of rendering an already esoteric subject opaque.Nor does the ugliness stop there. The ebook includes delights such as entire pages with a single sentence and other layout disasters that suggest a computer generated text untouched by any human being. Vast expanses of white space interrupt the text; perhaps half the pages are more than half blank. It appears to be a draft website or classroom presentation dumped to text. Printed, there'd be enough room to write an entirely new (and one hopes, better) text in the white space provided.Perhaps the author is a non-native speaker of English, but that in no way excuses the publisher for releasing this half-baked abortion. One can only assume Packt employs no editors and vetted this shameful mess not at all.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.