design pattern factory method iOS singleton swift Technology Tutorial

Design Patterns in Swift #1: Factory Method and Singleton

Design Patterns in Swift #1: Factory Method and Singleton

There are 23 basic software program improvement design patterns in all probability first recognized, collected, and defined all in one place by the “Gang of Four” (“GoF”), Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in their seminal e-book, “Design Patterns: Elements of Reusable Object-Oriented Software.” This tutorial focuses on two of these patterns in phrases of what the GoF calls the “creational” class: manufacturing unit technique and singleton.

Software program improvement is an endeavor into modeling actual world situations in the hopes of making instruments to reinforce the human expertise in such situations. Instruments for managing funds, e.g., banking apps and buying aids like Amazon or eBay’s iOS apps, undoubtedly make life a lot easier than it was for shoppers simply ten years in the past. Consider how far we’ve come. Whereas software program apps have usually gotten extra highly effective and easier to make use of for shoppers, improvement of stated apps has gotten rather more complicated for builders.

So builders have created an arsenal of greatest practices to handle complexity, like object-oriented programming, protocol-oriented programming, worth semantics, native reasoning, breaking giant items of code into smaller ones with well-defined interfaces (like with Swift extensions), syntactic sugar, to call a few of the hottest. One of the essential greatest practices that I didn’t point out, however that deserves a lot consideration, is using design patterns.

Design Patterns

Design patterns are a particularly necessary device with which builders can handle complexity. It’s greatest to conceptualize them as usually templated methods, every tailor-made to fixing a corresponding, recurring, and readily identifiable drawback. Take a look at them as an inventory of greatest practices you’d use for coding situations that you simply see over and over once more, like tips on how to create objects from a associated household of objects with out having to know all of the gory implementation particulars of that household. The entire level of design patterns is that they apply to generally occurring situations. They’re reusable as a result of they’re generalized. A selected instance ought to assist.

Design patterns will not be particular to some use case like iterating over a Swift array of 11 integers (Int). For instance, the GoF outlined the Iterator sample to offer a standard interface for traversing via all gadgets in some assortment with out understanding the intricacies (i.e., sort) of the gathering. A design sample is just not programming language code. It’s a set of tips or rule of thumb for fixing a standard software program state of affairs.

Keep in mind that I mentioned the “Model-View-ViewModel” or “MVVM” design sample right here on AppCoda — and in fact the very well-known “Model-View-Controller” or “MVC” design sample, lengthy favored by Apple and many iOS builders.

These two patterns are usually utilized to complete purposes. MVVM and MVC are architectural design patterns and are supposed to separate the consumer interface (UI) from the app’s knowledge and from code for presentation logic, and to separate the app’s knowledge from core knowledge processing and/or enterprise logic. The GoF design patterns are extra particular in nature, meant to unravel extra particular issues inside an software’s code base. Chances are you’ll use three or seven and even twelve GoF design patterns in one app. Keep in mind my Iterator instance. Delegation is one other nice instance of a design sample, although not particularly on the GoF’s record of 23.

Whereas the GoF e-book has taken on biblical connotations for a lot of builders, it isn’t with out its detractors. We’ll speak about that in the conclusion to this text.

Design sample classes

The GoF organized their 23 design patterns into three classes, “creational,” “structural,” and “behavioral.” This tutorial discusses two patterns in the creational class. This sample’s function is to make the creation of (typically complicated) objects simple (straightforward), comprehensible, and maintainable for builders, hiding particulars like instantiation and class implementation.

Hiding complexity (encapsulation) is one the very best objectives of sensible builders. For instance, object-oriented (OOP) courses can present very complicated, refined, and highly effective performance with out requiring the developer to know something concerning the inner workings of these courses. Within the creational sample, a developer might not even should find out about a category’s key properties and strategies, but when vital, she/he can take a peek on the interface — protocol in Swift — to the category(es) of curiosity and simply plug and play. You’ll see what I imply in our first instance of a “factory method” design sample.

The manufacturing unit technique design sample

Should you’ve delved into the GoF design patterns and/or spent a whole lot of time in the world of OOP, you’ve in all probability at the very least heard of the “abstract factory,” “factory,” or “factory method” sample. Whereas we might quibble over “exact” nomenclature, the instance I’m going to point out you right here best suits the “factory method” sample.

On this paradigm, you possibly can create very helpful objects with out immediately calling class constructors and with out understanding something concerning the class(es) or class hierarchy that your manufacturing unit technique is instantiating. You get a number of bang for reasonable. You get performance and UI (if relevant) with a minimal quantity of code. So my manufacturing unit technique instance undertaking, out there on GitHub, showcases how objects from a nontrivial class hierarchy can be utilized simply by, say, a workforce’s UI developer:

Most profitable apps have a constant look — a theme — that’s pleasing and turns into related to the app and/or app developer. We’ll assume that each one shapes used in our hypothetical app would be the similar shade and similar measurement in order to remain in tune with the app’s theme — it’s branding. These shapes could possibly be helpful by way of an app as customized buttons, or perhaps simply a part of background imagery in the course of the onboarding course of.

Let’s assume that the design group has agreed that my app theming code has been chosen for use as app background imagery. We’ll undergo my code, beginning with the protocol, class hierarchy, and manufacturing unit strategies that our hypothetical UI developer shouldn’t have to fret about.

See file ShapeFactory.swift. Right here’s a protocol for drawing shapes inside preexisting view controllers. Because it could possibly be used for quite a lot of functions, it’s entry degree is public:

Keep in mind that the UIView class has an oblong body by default, so it was easiest for me to make Sq. my base form class:

Discover that I’m profiting from OOP to reuse my code and thus make my form hierarchy easy and maintainable. Courses Circle and Rectangle are simply specializations of Sq. (and keep in mind how straightforward it’s to attract a circle by beginning with an ideal sq.):

I’ve used fileprivate to emphasise one of many functions behind the manufacturing unit technique sample: hiding complexity. You also needs to see how the form class hierarchy could possibly be simply modified or prolonged with out altering the manufacturing unit strategies under. Right here’s the code for the manufacturing unit strategies that makes object creation so summary and easy:

Discover that I’ve developed a category manufacturing unit and two manufacturing unit strategies to provide you some meals for thought. Technically, a manufacturing unit technique ought to return one in every of a lot of associated courses, all with widespread base class and/or a standard protocol. Because the function right here was to attract a form in a view, I personally want the createShape(_:view:) technique. Typically it’s a good suggestion to offer options — or simply to experiment and discover new prospects.

Lastly, I present using two manufacturing unit strategies to attract shapes. The UI developer doesn’t need to know something about how the form courses are encoded. He/she particularly doesn’t have to fret about how form courses are initialized. The code in file ViewController.swift is definitely readable:

The singleton design sample

Most iOS builders are conversant in the singleton sample. Consider the UNUserNotificationCenter.present(), UIApplication.shared, or FileManager.default singletons that you need to use if you wish to ship notifications, or open a URL in Safari, or manipulate iOS information, respectively. Singletons may be good for shielding shared assets, offering entry to some system which incorporates one and just one occasion of an object, supporting one object which performs some sort of app-wide coordination, and, as we’ll see right here, may be good for offering a value-added wrapper of a built-in iOS singleton.

To behave as a singleton, we be sure that a category:

  • declares and initializes a static and fixed property of itself, and calls that property shared to convey the truth that an occasion of the category is a singleton (public by default);
  • declares a personal property of some useful resource we need to management/shield but in addition share by way of shared; and,
  • declares a personal initializer in order that solely our singleton class can initialize itself, and inside this init, we initialize the useful resource we need to management but in addition share.

By making the category’s initializer personal and defining the shared static fixed, we’ve ensured that there can solely be one occasion of the category, the category can solely initialize itself as soon as, and the category’s shared occasion is accessible all through our app code. We’ve created a… singleton!

My singleton instance undertaking, out there on GitHub, showcases how a improvement staff can retailer consumer preferences safely, persistently, and with only a few errors. Right here’s my pattern app remembering whether or not the consumer prefers to see their password as unencrypted plain textual content or as masked, which isn’t the best concept in retrospect, however I wanted an instance to point out you that my code works. This code is solely for instructional functions. I counsel you by no means to go away a password uncovered. Right here’s how the consumer can set her/his password choice — and that choice is saved in UserDefaults:

Show_Pwd

When the consumer closes and ultimately comes again to the app, notice that her/his password choice is remembered:

Let me present you an excerpt of the code in file PreferencesSingleton.swift, with inline commentary, and you’ll see precisely what I imply:

There’s no want to fret about impression on, say, app startup as initializers of static properties and international variables are run lazily, as I perceive Swift.

Chances are you’ll ask, “Why has he created a singleton wrapper of another singleton, UserDefaults?” First, my important function herein was to point out you a greatest apply for creating and utilizing a singleton in Swift, and consumer preferences is the kind of useful resource that ought to have a single level of entry. So UserDefaults served a really apparent didactic instance. However secondly, take into consideration what number of occasions you’ve seen UserDefaults used (abused) virtually flippantly by means of an app’s code base.

I’ve seen apps the place UserDefaults (or NSUserDefaults in the “old” days) have been unfold throughout venture code with none rhyme or purpose. Each single reference to a key in consumer preferences was spelling out by hand. I simply discovered a bug in my very own code the place I had misspelled the phrase “switch” as “swithc,” and as a result of I had copied and pasted, I had ended up with fairly a number of situations of “swithc” earlier than I caught the issue. What if different group member(s) on that app began or continued to used “switch” as a key in saving the corresponding worth? The app might’ve ended up with two or extra states being preserved for what ought to’ve been one state. UserDefaults makes use of strings because the keys to the values we want to keep as a part of app state, which is ok as a result of it’s greatest to explain one thing — values — with significant, simply recognized, and simply remembered phrases. However strings usually are not with out danger.

Lots of you have got in all probability examine what has turn into referred to as “stringly-typed” code, as in my dialogue about “swithc” vs. “switch.” Whereas strings are very descriptive — a very good factor — using uncooked strings as distinctive identifiers throughout a code base is more likely to result in delicate but ultimately catastrophic errors due to misspellings. The Swift compiler doesn’t forestall us from making stringly-typed errors.

The answer to stringly-typed errors is making use of string constants in the type of the Swift enum. Not solely can we standardize our use of strings, however we will manage them by breaking them into classes. Once more, see PreferencesSingleton.swift:

I’m beginning to wander from the definition of the singleton design sample, however I do need to briefly present you and clarify why I personally use a singleton wrapper for UserDefaults in most of my manufacturing apps. There are various value-added options that may make a UserDefaults singleton wrapper very handy and improve the reliability of code. Offering error checking when getting and setting preferences instantly involves thoughts. One other function I like so as to add is offering comfort strategies for generally used consumer preferences, like for easy methods to deal with passwords. You’ll see under as you learn my code. Right here’s every thing in my PreferencesSingleton.swift file:

For those who take a look at my ViewController.swift file, you’ll see how straightforward it’s to entry and make use of a well-constructed singleton:

Conclusion

Some critics have claimed that use of design patterns is proof of deficiencies in programming languages and that seeing recurring patterns in code is a nasty factor. I disagree. Anticipating a language to have a function for all the things is foolish and would most certainly result in monumental languages like C++ into turning into even bigger and extra complicated and thus more durable to study, use, and keep. Recognizing and fixing recurring issues is a constructive human trait worthy of constructive reinforcement. Design patterns are profitable examples of studying from historical past, one thing humankind has did not do too many occasions. Arising with summary and standardized options to widespread issues makes these options moveable and extra more likely to be distributed.

A mixture of a compact language like Swift and an arsenal of greatest practices, like design patterns, is a perfect and glad medium. Constant code is usually readable and maintainable code. Keep in mind too that design patterns are ever-evolving as tens of millions of builders are always discussing and sharing concepts. By advantage of being linked collectively over the World Extensive Net, this developer dialogue has result in always self-regulating collective intelligence.

(perform(d, s, id)
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = ‘https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.10&appId=1159859510706720’;
fjs.parentNode.insertBefore(js, fjs);
(doc, ‘script’, ‘facebook-jssdk’));