Creational patterns

Creational patterns are design patterns that deal with how an object is created. These patterns create objects in a manner suitable for particular situations.

There are two basic ideas behind creational patterns. The first is encapsulating the knowledge of which concrete types should be created and the second is hiding how the instances of these types are created.

There are five well-known patterns that are a part of the creational pattern category. They are as follows:

In this chapter, we are going to show examples on how to implement the builder, factory method, and singleton patterns in Swift. Let's start off by looking at one of the most controversial and possibly overused design patterns, the singleton pattern.

The use of the singleton pattern is a fairly controversial subject among certain corners of the development community. One of the main reasons for this is that the singleton pattern is probably the most overused and misused pattern. Another reason this pattern is controversial is that the singleton pattern introduces a global state into an application, which provides the ability to change the object at any point within the application. The singleton pattern can also introduce hidden dependencies and tight compiling. My personal opinion is that, if the singleton pattern is used correctly, there is nothing wrong with using it. However, we do need to be careful not to misuse it.

The singleton pattern restricts the instantiation of a class to a single instance for the lifetime of an application. This pattern is very effective when we need exactly one instance to coordinate actions within our application. An example of a good use of a singleton is if our application communicates with a remote device over Bluetooth and we also want to maintain that connection throughout our application. Some would say that we could pass the instance of the connection class from one page to the next, which is essentially what a singleton is. In my opinion, the singleton pattern, in this instance, is a much cleaner solution, because with the singleton pattern any page that needs the connection can get it without forcing every page to maintain the instance. This also allows us to maintain the connection without having to reconnect each time we go to another page.

Let's look at how we implement the singleton pattern with Swift. The following code example shows how to create a singleton class:

We can see that, within the MySingleton class, we created a static constant named sharedInstance that contains an instance of the MySingleton class. A static constant can be called without having to instantiate the class. Since we declared the sharedInstance constant static, only one instance will exist throughout the lifecycle of the application, thereby creating the singleton pattern.

We also created the private initiator that will restrict other code from creating another instance of the MySingleton class.

Now, let's see how this pattern works. The MySingleton pattern has another property named number, which is of the Int type. We will monitor how this property changes as we use the sharedInstance property to create multiple variables of the MySingleton type, as shown in the following code:

In this example, we used the sharedInstance property to create three variables of the MySingleton type. We initially set the number property of the second MySingleton variable (singleB) to the number 2. When we printed out the value of the number property for singleA, singleB, and singleC, we saw that the number property for all three equals 2. We then changed the value of the number property of the third MySingleton variable (singleC) to the number 3. When we printed out the value of the number property again, we saw that all three now have the value of 3. Therefore, when we change the value of the number property in any of the instances, the values of all three change because each variable is pointed to the same instance.

In this example, we implemented the singleton pattern using a reference (class) type because we wanted to ensure that only one instance of the type existed throughout our application. If we implemented this pattern with a value type, such as a structure or an enumeration, we would run the risk of there being multiple instances of our type. If you recall, each time we pass an instance of a value type, we are actually passing a copy of that instance, which means that, if we implemented the singleton pattern with a value type, each time we called the sharedInstance property, we would receive a new copy, which would effectively break the singleton pattern.

The singleton pattern can be very useful when we need to maintain the state of an object throughout our application; however, be careful not to overuse it. The singleton pattern should not be used unless there is a specific requirement (requirement is the keyword here) for having one, and only one, instance of our class throughout the lifecycle of our application. If we are using the singleton pattern simply for convenience, then we are probably misusing it.

Keep in mind that, while Apple recommends that we prefer value types to reference types, there are still plenty of examples, such as the singleton pattern, where we need to use reference types. When we continuously tell ourselves to prefer value types to reference types, it can be very easy to forget that there are times where a reference type is needed. Don't forget to use reference types with this pattern.

Now, let's look at the builder design pattern.

The builder pattern helps us with the creation of complex objects and enforces the process of how these objects are created. With this pattern, we generally separate the creation logic from the complex type and put it in another type. This allows us to use the same construction process to create different representations of the type.

Before we show how we would use the builder pattern, let's look at how to create a complex structure without the builder pattern and the problem we run into.

The following code creates a structure named BurgerOld and does not use the builder pattern:

In the BurgerOld structure, we have several properties that define which condiments are on the burger and also the name of the burger. Since we need to know which items are on the burgers, and which items aren't, when we create an instance of the BurgerOld structure, the initializer requires us to define each item. This can lead to some complex initializations throughout our application, not to mention that, if we had more than one standard burger (bacon cheeseburger, cheeseburger, hamburger, and so on), we would need to make sure that each is defined correctly. Let's see how to create instances of the BurgerOld class:

As we can see, creating instances of the BurgerOld type requires a lot of code. Now, let's look at a better way to do this. In this example, we will show how to use multiple builder types where each type will define the condiments that are on a particular burger. We will begin by creating a BurgerBuilder protocol that will have the following code in it:

This protocol simply defines the nine properties that will be required for any type that implements this protocol. Now, let's create two structures that implement this protocol, the HamBurgerBuilder and the CheeseBurgerBuilder structures:

In both the HamBurgerBuilder and the CheeseBurgerBuilder structures, all we are doing is defining the values for each of the required properties. In more complex types, we might need to initialize additional resources.

Now, let's look at our Burger structure, which will use instances of the BugerBuilder protocol to create instances of itself. The following code shows this new Burger type:

The difference between this Burger structure and the BurgerOld structure shown earlier is the initializer. In the previous BurgerOld structure, the initializer took nine arguments—one for each constant defined in the structure. In the new Burger structure, the initializer takes one argument, which is an instance of a type that conforms to the BurgerBuilder protocol. This new initializer allows us to create instances of the Burger class like this:

If we compare how we create instances of the new Burger structure to the earlier BurgerOld structure, we can see that it is much easier to create instances of the Burger structure. We also know that we are correctly setting the property values for each type of burger because the values are set directly in the builder classes.

As we mentioned earlier, there is a second method that we can use to implement the builder pattern. Rather than having multiple builder types, we can have a single builder type that sets all of the configurable options to a default value; then we would change the values as needed. I use this implementation method a lot when I am updating older code because it is easy to integrate it with preexisting code.

For this implementation, we will create a single BurgerBuilder structure. This BurgerBuilder structure will be used to create instances of the BurgerOld structure and will, by default, set all of the ingredients to their default values. The BurgerBuilder structure also give us the ability to change what ingredients will go on the burger prior to creating instances of the BurgerOld structure. We create the BurgerBuilder structure like this:

In the BurgerBuilder structure, we define our nine properties (ingredients) for our burger and then create a setter method for each of the properties except for the name property. We also create one method named buildBurgerOld() that will create an instance of the BurgerOld structure based on the values of the properties in the BurgerBuilder instance. We use the BurgerBuilder structure like this:

In this example, we create an instance of the BurgerBuilder structure. We then use the setCheese() and setBacon() methods to add cheese and bacon to our burger. Finally we call the buildBurgerOld() method to create the instance of the Burger Old structure.

As we can see, both methods that were used to implement the builder pattern greatly simplify the creation of our complex type. Both methods also ensured that our instances were properly configured with default values. If you find yourself creating instances of types with very long and complex initialization commands, I would recommend that you look at the builder pattern to see if you can use it to simplify the initialization.

For our last example of a creational pattern, we will look at the factory method pattern.

The factory method pattern uses methods to create instances of objects without specifying the exact type that will be created. These methods are called factory methods. This allows us to pick the type to create at runtime.

I find that the factory pattern is one of the patterns that I use a lot. It is also one of the patterns that developers tend to recognize when they first start reading about design patterns because they have used it in previous projects.

To demonstrate how we would use the factory method pattern, we will use the text validation types that we created at the end of Chapter 5, Let's Extend Some Types. In this example, we will create a function that will determine which text validation type to use based on the parameters passed into the factory method by the code that called it. As a refresher, the code for the TextValidationProtocol protocol and the TextValidationProtocol protocol extension are shown here:

protocol TextValidationProtocol {
 var regExFindMatchString: String {get}
    var validationMessage: String {get}
}


extension TextValidationProtocol {
    
    var regExMatchingString: String { get {
        return regExFindMatchString + "$"
        }
    }
    
    func validateString(str: String) -> Bool {
        if let _ = str.rangeOfString(regExMatchingString, options: .RegularExpressionSearch) {
            return true
        } else {
            return false
        }
    }
    func getMatchingString(str: String) -> String? {
        if let newMatch = str.rangeOfString(regExFindMatchString, options: .RegularExpressionSearch) {
            return str.substringWithRange(newMatch)
        } else {
            return nil
        }
    }
}

Within the TextValidationProtocol protocol, we define two properties named regExFindMatchString and validationMessage. Within the protocol extension, we implement one computed property named regExMatchingString and two methods named validateString() and getMatchingString().

Now let's create three types that conform to the TextValidationProtocol protocol. These three types will be named AlphaValidation, NumericValidation, and AlphaNumericValidation:

The AlphaValidation class can be used to validate strings to ensure they contain a maximum of 10 alpha characters. The NumericValidation class can be used to validate strings to ensure they contain a maximum of 10 numeric characters. Finally, the AlphaNumericValidation class can be used to validate strings to ensure they contain a maximum of 10 alpha or numeric characters.

To use these validation classes, we need a way to determine which class to use based on the string that we are validating. The factory method pattern can help us with this determination. We could implement this pattern as shown in the following code:

The getValidator() method accepts two parameters both of the Boolean type named alphaCharacters and numericCharacters. These parameters define the type of validation we wish to do and we then return a type that conforms to the TextValidationProtocol protocol based on the values in the parameters.

One of the biggest advantages that we get with this pattern is that all of the logic on how the text validation types are selected is encapsulated in this one function. This means that, if we need to change the logic or change which type to use, the only code we need to change is the code within this function rather than having to refactor our entire code base. As an example, if we wish to replace the AlphaValidation class with a new AlphaSpacesValidation class, the only code that needs to change is within this function.

We can now use the getValidator() method, as shown in the following code:

In this code, the validator1 variable contains an instance of the AlphaValidation type. When we call the validateString() method of this instance, it returns a false value because the str variable contains numeric values. The validator2 variable contains an instance of the AlphaNumericValidation type. When we call the validateString() method of this instance, it returns true because the validation class looks for both alpha and numeric characters.

One of the key ideas behind creational patterns is that we take the logic about how and what to create out of our general code base and put it into specific classes or functions. Then, when we need to make changes to our code in the future, the logic is encapsulated in a single spot and can be easily changed, rather than having the logic spread throughout our code.

Now, let's look at structural design patterns.