IOS& design pattern builder mode (Builder)

What is the construction model?

The creation and representation of a complex object are separated, depending on the order of creation, and the manner of presentation is different. Such as when buying a mobile phone configuration: iPhote7, 64g, rose gold, you can choose a different configuration, but you do not know if he is achieved, but also because of the choice of different configurations, process and mobile phone production style is not the same. The user does not need to know how to implement, and only the final representation is chosen, which is the real-life builder model.

Standard composition

  • Abstract Builder (Builder): provides interfaces for builders (protocols in iOS)
  • Concrete Builder (ConcreteBuilder): building concrete products (implementing the Builder protocol)
  • Command (Director): call the Builder interface to create the product object (which is not necessarily necessary)
  • Product roles (Product): specific products


IOS& design pattern builder mode (Builder)

The conductor on the map (assembler) is not required, because we can directly iPhoneBuilder to assemble products, without the need to separate the closure of a class to implement, but should not, or need to business scenarios to determine, design pattern is dead, people are living, as for how to use. Or that sentence: according to the actual demand.


Here is the builder of a date:

Bulider = (DateBulider) / / let / / bulider.setYear (2017).SetMonth (5).SetDay (25).SetHour (11).SetMinute (41).ShowDate (class) DateBulider: NSObject private var component: {NSDateComponents? Override (init) {component = NSDateComponents (default) / component?.calendar = Calendar (identifier:.Gregorian) func date} (-> Date) {return (component?.date)!} func {let = formatter (showDate) DateFormatter (formatter.dateFormat) = "yy-MM-dd hh:mm:ss" (print formatter.string (from: (component?.date)!})) func setCalender (identifier: Calendar.Identifier ->); DateBulider {component = Calendar?.calendar (identifier: identifier) return self Func setSecond (second: _} Int -> DateBulider) {component.Second = second? Return self func setMinute (minute: _} Int -> DateBulider) {component.Minute = minute? Return self func setHour (hour: _} Int -> DateBulider) {component.Hour = hour? Return self func setDay day: Int (_} -> DateBulider) {component.Day = day? Return self func setMonth (month: _} Int -> DateBulider) {component.Month = month? Return self func setYear (year: _} Int -> DateBulider) {component.Year = year? Return self}}

Build up above, non strict standards, according to the following standards, to achieve the abstract Builder (DateBuilder Protocole):

Protocol DateBuliderProtocole: class (date) {func -> Date func showDate (func) setCalender (identifier: Calendar.Identifier ->); DateBulider func (setSecond _ second: Int -> DateBulider func (setMinute); minute: Int -> _) DateBulider func setHour (_ hour: Int -> DateBulider func (setDay); day: Int -> DateBulider _) func setMonth (_ month: Int -> DateBulider func (setYear); year: Int -> DateBulider _)}

And implement the Protocole in DateBulider:

Class, DateBulider:, DateBuliderProtocole {...}

Here, this example can be said to be a standard, simple builder model, Director and Product do not appear, but Director is not necessarily required, and the Product part can be said to be:

Let, Bulider = (DateBulider), bulider.setYear (2017),.SetMonth (5),.SetDay (25),.SetHour (11),.SetMinute (41),.ShowDate ()

But there is no encapsulation into a Product class, and if in complex scenarios, the Product class still needs to be available.

Nonstandard builder model

Design pattern is a kind of thought, it is not immutable and frozen, construction mode, use the actual construction in various modes is the standard model in deformation, but the idea is the same, the same.

Here’s a look at the builder pattern used in the next Realm, and a little bit about the introduction of Realm:

The first database specifically designed for mobile platforms aims to replace SQLite.

Database operations in Realm are using builder patterns, such as:

/ / add / update realm.add (model update: true) realm.delete (model) / / / / delete query realm.objects (YHFeedItemModel.self).Filter ("isDel = false").Filter ("isFavorite = true")

Here is an application of the builder pattern to separate the creation and representation of a complex object. If we add the function, we can enter the correct instance to complete the storage, but the bottom layer is how he realized, we do not know, and we do not care. We can download the Realm source code to see the implementation of the next (probably know the process is OK, interested can go under the integrity of the source code to see):

Swift public func add (_ / / object: Object update:, Bool = false) {if update & & object.objectSchema.primaryKeyProperty = = nil {throwRealmException ("/ (object.objectSchema.className) does not have a primary 'key and can not be updated RLMAddObjectToRealm (object)}, rlmRealm, update OC void (RLMAddObjectToRealm)} / / __unsafe_unretained RLMObjectBase *const object, __unsafe_unretained RLMRealm *const realm, bool createOrUpdate) {RLMVerifyInWriteTransaction (REALM); / / verify that object is unmanaged if (object.invalidated) {@throw RLMException (@ Adding a deleted or invalidated object to a Realm is not permitted");} if (object-> _ Realm (object-> _realm) {if = = realm) {/ / Adding an object to the Realm it's already manged by is a no-op return differing realms;} / / for users must explicitly create the object in the second realm @throw RLMException Object is already managed (@ by another Realm. Use create instead to copy it into this Realm. ");} if (object-> _observationInfo & & object-> _observationInfo-> hasObservers (@throw)) {RLMException (" Cannot add an object @ with observers to a Realm ");} auto& info = realm-> _info[object-> _objectSchema.className]; RLMAccessorContext c{realm, info, true}; object-> _info = & info object-> _realm = realm; Object-> _objectSchema = info.rlmObjectSchema; try {realm:: Object:: create (C, realm-> _realm, *info.objectSchema, (ID) object, createOrUpdate, & object-> _row;} catch (std:): exception const& E) {@ throw RLMException (E);} object_setClass (object, info.rlmObjectSchema.accessorClass (RLMInitializeSwiftAccessorGenerics); object);}

There is no detailed reading Realm source code, it can achieve the general understanding, mainly understand the construction patterns of thought on constructing the mode content here, there is a free time, then simply write a complex point to that Demo.

Demo can be downloaded from here, this is the iOS development group (QQ group): 127548419 the first phase of thematic sharing activities articles, the design model of sharing activities after the end of all articles and demo will be released, welcomed the attention, interested students can come to participate in the two week, a special share, one stroke.