HomeiOS DevelopmentSwift builder design sample - The.Swift.Dev.

Swift builder design sample – The.Swift.Dev.


Discover ways to implement the builder sample in Swift to cover the complexity of making objects with a number of particular person properties.

Design patterns

How does the builder sample work?

The builder sample could be applied in a number of methods, however that basically does not issues in case you perceive the principle purpose of the sample:

The intent of the Builder design sample is to separate the development of a fancy object from its illustration.

So when you have an object with a number of properties, you need to conceal the complexity of the initialization course of, you can write a builder and assemble the thing via that. It may be so simple as a construct technique or an exterior class that controls the whole building course of. All of it will depend on the given surroundings. 🏗

That is sufficient concept for now, let’s examine the builder sample in motion utilizing dummy, however real-world examples and the highly effective Swift programming language! 💪


Easy emitter builder

I imagine that SKEmitterNode is kind of a pleasant instance. If you wish to create customized emitters and set properties programmatically – normally for a SpriteKit recreation – an emitter builder class like this may very well be an inexpensive resolution. 👾

class EmitterBuilder {

    func construct() -> SKEmitterNode {
        let emitter = SKEmitterNode()
        emitter.particleTexture = SKTexture(imageNamed: "MyTexture")
        emitter.particleBirthRate = 100
        emitter.particleLifetime = 60
        emitter.particlePositionRange = CGVector(dx: 100, dy: 100)
        emitter.particleSpeed = 10
        emitter.particleColor = .purple
        emitter.particleColorBlendFactor = 1
        return emitter
    }
}

EmitterBuilder().construct()

Easy theme builder

Let’s transfer away from gaming and picture that you’re making a theme engine on your UIKit software which has many customized fonts, colours, and so on. a builder may very well be helpful to assemble standalone themes. 🔨

struct Theme {
    let textColor: UIColor?
    let backgroundColor: UIColor?
}

class ThemeBuilder {

    enum Fashion {
        case gentle
        case darkish
    }

    func construct(_ model: Fashion) -> Theme {
        change model {
        case .gentle:
            return Theme(textColor: .black, backgroundColor: .white)
        case .darkish:
            return Theme(textColor: .white, backgroundColor: .black)
        }
    }
}

let builder = ThemeBuilder()
let gentle = builder.construct(.gentle)
let darkish = builder.construct(.darkish)

“Chained” URL builder

With this method you’ll be able to configure your object via numerous strategies and each single considered one of them will return the identical builder object. This manner you’ll be able to chain the configuration and as a final step construct the ultimate product. ⛓

class URLBuilder {

    personal var parts: URLComponents

    init() {
        self.parts = URLComponents()
    }

    func set(scheme: String) -> URLBuilder {
        self.parts.scheme = scheme
        return self
    }

    func set(host: String) -> URLBuilder {
        self.parts.host = host
        return self
    }

    func set(port: Int) -> URLBuilder {
        self.parts.port = port
        return self
    }

    func set(path: String) -> URLBuilder {
        var path = path
        if !path.hasPrefix("https://theswiftdev.com/") {
            path = "https://theswiftdev.com/" + path
        }
        self.parts.path = path
        return self
    }

    func addQueryItem(title: String, worth: String) -> URLBuilder  {
        if self.parts.queryItems == nil {
            self.parts.queryItems = []
        }
        self.parts.queryItems?.append(URLQueryItem(title: title, worth: worth))
        return self
    }

    func construct() -> URL? {
        return self.parts.url
    }
}

let url = URLBuilder()
    .set(scheme: "https")
    .set(host: "localhost")
    .set(path: "api/v1")
    .addQueryItem(title: "kind", worth: "title")
    .addQueryItem(title: "order", worth: "asc")
    .construct()

The builder sample with a director

Let’s meet the director object. Because it looks like this little factor decouples the builder from the precise configuration half. So for example you may make a recreation with circles, however afterward in case you change your thoughts and you want to make use of squares, that is comparatively simple. You simply should create a brand new builder, and the whole lot else could be the identical. 🎬

protocol NodeBuilder {
    var title: String { get set }
    var colour: SKColor { get set }
    var measurement: CGFloat { get set }

    func construct() -> SKShapeNode
}

protocol NodeDirector {
    var builder: NodeBuilder { get set }

    func construct() -> SKShapeNode
}

class CircleNodeBuilder: NodeBuilder {
    var title: String = ""
    var colour: SKColor = .clear
    var measurement: CGFloat = 0

    func construct() -> SKShapeNode {
        let node = SKShapeNode(circleOfRadius: self.measurement)
        node.title = self.title
        node.fillColor = self.colour
        return node
    }
}

class PlayerNodeDirector: NodeDirector {

    var builder: NodeBuilder

    init(builder: NodeBuilder) {
        self.builder = builder
    }

    func construct() -> SKShapeNode {
        self.builder.title = "Howdy"
        self.builder.measurement = 32
        self.builder.colour = .purple
        return self.builder.construct()
    }
}

let builder = CircleNodeBuilder()
let director = PlayerNodeDirector(builder: builder)
let participant = director.construct()

Block based mostly builders

A extra swifty method could be using blocks as a substitute of builder courses to configure objects. In fact we may argue on if that is nonetheless a builder sample or not… 😛

extension UILabel {

    static func construct(block: ((UILabel) -> Void)) -> UILabel {
        let label = UILabel(body: .zero)
        block(label)
        return label
    }
}

let label = UILabel.construct { label in
    label.translatesAutoresizingMaskIntoConstraints = false
    label.textual content = "Howdy wold!"
    label.font = UIFont.systemFont(ofSize: 12)
}

Please be aware that the builder implementation can range on the precise use case. Generally a builder is mixed with factories. So far as I can see virtually everybody interpreted it differently, however I do not assume that is an issue. Design patterns are well-made tips, however typically you need to cross the road.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments