Explaining the Factory Design Pattern
The factory method design pattern is a creational design pattern that provides a way to create objects without specifying the exact class of object that will be created. This is useful when the type of object to be created is determined by runtime conditions or user input, for example.
In Swift, the factory method pattern is often implemented using protocols and protocol extensions. Here's an example to illustrate how this works:
// This protocol defines the basic interface for a shape object.
// Any class that conforms to this protocol can be used as a shape.
protocol Shape {
func draw()
}
// This is a simple class that represents a square shape.
class Square: Shape {
func draw() {
print("Drawing a square")
}
}
// This is a simple class that represents a circle shape.
class Circle: Shape {
func draw() {
print("Drawing a circle")
}
}
// This is a factory class that creates shape objects.
// The factory has a method called "makeShape(type:)" that
// takes a shape type as an argument and returns a shape object.
// The specific type of shape object that is returned depends
// on the value of the "type" argument.
class ShapeFactory {
func makeShape(type: String) -> Shape {
switch type {
case "square":
return Square()
case "circle":
return Circle()
default:
fatalError("Unsupported shape type")
}
}
}
// Now we can create a shape factory and use it to create different
// types of shape objects.
let factory = ShapeFactory()
let square = factory.makeShape(type: "square")
let circle = factory.makeShape(type: "circle")
square.draw() // Output: "Drawing a square"
circle.draw() // Output: "Drawing a circle"
In this example, we define a Shape
protocol that represents a shape object. We also define two classes, Square
and Circle
, that conform to the Shape
protocol and provide an implementation of the draw()
method.
Then, we define a ShapeFactory
class that has a makeShape(type:)
method. This method takes a shape type as an argument and returns a shape object of the specified type. The specific type of shape object that is returned depends on the value of the type
argument.
Finally, we create an instance of the ShapeFactory
class and use it to create Square
and Circle
objects. When we call the draw()
method on each of these objects, the appropriate draw()
method is called and the corresponding shape is drawn.
This example shows how the factory method pattern can be used to create objects of different types based on runtime conditions. The ShapeFactory
class acts as a factory that creates objects of the appropriate type, and the Shape
protocol defines the basic interface for these objects. This makes it easy to add new types of shapes to the program without having to change the factory class.