Swift builder design sample – The.Swift.Dev.


How does the builder sample work?

The builder sample could be carried out in a number of methods, however that actually does not issues if you happen to perceive the principle objective of the sample:

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

So when you’ve got an object with plenty of properties, you wish to disguise the complexity of the initialization course of, you would write a builder and assemble the thing by means of that. It may be so simple as a construct methodology or an exterior class that controls the whole building course of. All of it is determined by the given setting. 🏗

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

Easy emitter builder

I consider that SKEmitterNode is sort 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 could possibly be an affordable 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 = .pink
        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 in your UIKit utility which has many customized fonts, colours, and so forth. a builder could possibly be helpful to assemble standalone themes. 🔨

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

class ThemeBuilder {

    enum Model {
        case gentle
        case darkish
    }

    func construct(_ type: Model) -> Theme {
        swap type {
        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 strategy you'll be able to configure your object by means of numerous strategies and each single one in all them will return the identical builder object. This approach you'll be able to chain the configuration and as a final step construct the remaining product. ⛓

class URLBuilder {

    personal var elements: URLComponents

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

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

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

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

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

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

    func construct() -> URL? {
        return self.elements.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 can also make a recreation with circles, however in a while if you happen to change your thoughts and you would like to make use of squares, that is comparatively straightforward. You simply need to create a brand new builder, and every little thing else could be the identical. 🎬

protocol NodeBuilder {
    var title: String { get set }
    var shade: SKColor { get set }
    var dimension: CGFloat { get set }

    func construct() -> SKShapeNode
}

protocol NodeDirector {
    var builder: NodeBuilder { get set }

    func construct() -> SKShapeNode
}

class CircleNodeBuilder: NodeBuilder {
    var title: String = ""
    var shade: SKColor = .clear
    var dimension: CGFloat = 0

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

class PlayerNodeDirector: NodeDirector {

    var builder: NodeBuilder

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

    func construct() -> SKShapeNode {
        self.builder.title = "Hiya"
        self.builder.dimension = 32
        self.builder.shade = .pink
        return self.builder.construct()
    }
}

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

Block primarily based builders

A extra swifty strategy could be the usage of blocks as an alternative 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 = "Hiya wold!"
    label.font = UIFont.systemFont(ofSize: 12)
}

Please observe that the builder implementation can fluctuate on the precise use case. Typically a builder is mixed with factories. So far as I can see nearly everybody interpreted it another way, however I do not assume that is an issue. Design patterns are well-made tips, however generally you need to cross the road.

Recent Articles

Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here

Stay on op - Ge the daily news in your inbox