Hands-On Design Patterns with Swift
eBook - ePub

Hands-On Design Patterns with Swift

Master Swift best practices to build modular applications for mobile, desktop, and server platforms

Florent Vilmart, Giordano Scalzo, Sergio De Simone

Share book
  1. 414 pages
  2. English
  3. ePUB (mobile friendly)
  4. Available on iOS & Android
eBook - ePub

Hands-On Design Patterns with Swift

Master Swift best practices to build modular applications for mobile, desktop, and server platforms

Florent Vilmart, Giordano Scalzo, Sergio De Simone

Book details
Book preview
Table of contents
Citations

About This Book

From learning about the most sought-after design patterns to a comprehensive coverage of architectural patterns and code testing, this book is all you need to write clean, reusable code

Key Features

  • Write clean, reusable and maintainable code, and make the most of the latest Swift version.
  • Analyze case studies of some of the popular open source projects and give your workflow a huge boost
  • Choose patterns such as MVP, MVC, and MVVM depending on the application being built

Book Description

Swift keeps gaining traction not only amongst Apple developers but also as a server-side language. This book demonstrates how to apply design patterns and best practices in real-life situations, whether that's for new or already existing projects.

You'll begin with a quick refresher on Swift, the compiler, the standard library, and the foundation, followed by the Cocoa design patterns – the ones at the core of many cocoa libraries – to follow up with the creational, structural, and behavioral patterns as defined by the GoF. You'll get acquainted with application architecture, as well as the most popular architectural design patterns, such as MVC and MVVM, and learn to use them in the context of Swift. In addition, you'll walk through dependency injection and functional reactive programming. Special emphasis will be given to techniques to handle concurrency, including callbacks, futures and promises, and reactive programming. These techniques will help you adopt a test-driven approach to your workflow in order to use Swift Package Manager and integrate the framework into the original code base, along with Unit and UI testing.

By the end of the book, you'll be able to build applications that are scalable, faster, and easier to maintain.

What you will learn

  • Work efficiently with Foundation and Swift Standard library
  • Understand the most critical GoF patterns and use them efficiently
  • Use Swift 4.2 and its unique capabilities (and limitations) to implement and improve GoF patterns
  • Improve your application architecture and optimize for maintainability and performance
  • Write efficient and clean concurrent programs using futures and promises, or reactive programming techniques
  • Use Swift Package Manager to refactor your program into reusable components
  • Leverage testing and other techniques for writing robust code

Who this book is for

This book is for intermediate developers who want to apply design patterns with Swift to structure and scale their applications. You are expected to have basic knowledge of iOS and Swift.

Frequently asked questions

How do I cancel my subscription?
Simply head over to the account section in settings and click on “Cancel Subscription” - it’s as simple as that. After you cancel, your membership will stay active for the remainder of the time you’ve paid for. Learn more here.
Can/how do I download books?
At the moment all of our mobile-responsive ePub books are available to download via the app. Most of our PDFs are also available to download and we're working on making the final remaining ones downloadable now. Learn more here.
What is the difference between the pricing plans?
Both plans give you full access to the library and all of Perlego’s features. The only differences are the price and subscription period: With the annual plan you’ll save around 30% compared to 12 months on the monthly plan.
What is Perlego?
We are an online textbook subscription service, where you can get access to an entire online library for less than the price of a single book per month. With over 1 million books across 1000+ topics, we’ve got you covered! Learn more here.
Do you support text-to-speech?
Look out for the read-aloud symbol on your next book to see if you can listen to it. The read-aloud tool reads text aloud for you, highlighting the text as it is being read. You can pause it, speed it up and slow it down. Learn more here.
Is Hands-On Design Patterns with Swift an online PDF/ePUB?
Yes, you can access Hands-On Design Patterns with Swift by Florent Vilmart, Giordano Scalzo, Sergio De Simone in PDF and/or ePUB format, as well as other popular books in Informatik & Programmierung. We have over one million books available in our catalogue for you to explore.

Information

Year
2018
ISBN
9781789138511
Edition
1

Behavioral Patterns

Behavioral patterns are those patterns that identify common communication strategies between different entities. By realizing these patterns, you'll increase flexibility when communicating between different parts of your programs.
We'll start by looking at the state pattern, which helps decouple the behavior of a program from its internal state. We'll follow up with the observer pattern, which encompasses the implementation of event-based data flows.
Next, we'll discuss the memento pattern, a very useful pattern that manages to elegantly abstract the ability to roll back between states. Finally, we'll cover the visitor and strategy patterns, which both help to abstract complexity when implementing algorithms that evolve at runtime.
In this chapter, we will cover the following topics:
  • The state pattern
  • The observer pattern
  • The memento pattern
  • The visitor pattern
  • The strategy pattern

The state pattern

The state design pattern helps you decouple the behavior of an object, often called the context, from its internal state. For each state, the state object will implement the specific behaviors, keeping the context clean and concise.
This design pattern can help transform large switch statements into smaller objects that can perform the underlying specific task.
Let's get started with a simple example of a state machine—a card reader that you can find at a metro station, bus stop, or other public transportation system. From a high-level perspective, these card readers are simple state machines. They follow a simple run loop—wait, detect, read, success or failure—and each state transition is linear. This makes them particularly suitable for demonstrating this pattern.

The card reader

When we think about a finite amount of states, we usually consider using an enum. While this is not wrong, it forces you to pack all the logic either in your context or your enum itself. Let's explore this with an example.

Using enums

First, let's see how this reader could look if we implement its state with an enum:
class CardReader {
Implement the state with the enum, with all the possible state values, as follows:
enum State {
case unknown
case waiting
case reading
case read(CardInfo)
case failed(Error)
}
Use the private var state property so that no one can mutate the state from outside:
private var state: State = .unknown
The main routine is implemented as follows. For each loop, it will print the current state:
 func start() {
while true {
print("\(state)")
switch state {
case .unknown:
state = .waiting
case .waiting:
When we're waiting, we wait for a card to be detected by the radio. When the card is detected, we change the state to reading:
 if seenCard() {
state = .reading
}
case .reading:
When reading, we'll wait for this to complete. If it succeeds, we will change the state to read, or otherwise indicate the failure as follows:
 if readCard() {
state = .read(CardInfo())
} else {
state = .failed(ReadError())
}
case .read(_):
Now that the card is read, we can apply the logic. For example, that may involve using an external object to open doors, display a success message on a screen, decrement the number of journeys left on the card, or something more complex.
In any case, whether this logic is implemented in the enum or the context, you can clearly see that the state transitions are polluted by each state's logic. The same is true for the failure scenario, as follows:
 // Card is read
// Now we can open the gate
state = .waiting
case .failed(_):
// Display an error message on the screen
// Prompt to restart after a few seconds
state = .waiting
}
sleep(1)
}
}
}
We'll start the reader as follows:
let reader = CardReader()
reader.start()
This program should print, depending on the output of readCard() and seenCard(), something along the following lines:
unknown
waiting
reading
failed(ReadError())
waiting
reading
failed(ReadError())
waiting
reading
read(CardInfo(id: 415))
waiting
waiting
reading
failed(ReadError())
...
As we've seen, all the logic is packed into the context, making it very inefficient and hard to maintain. The state design pattern provides a solution for this problem. Let's refactor the code to improve maintainability.

Refactoring for maintainability

A few steps are needed in order to refactor CardReader:
  1. Define a single protocol for all the states
  2. Extract all states as structs or classes
  3. Implement the logic and transition inside each state object, instead of the context
  4. Refactor the context, in our case CardReader, to leverage those states
First, we need to define a single protocol. This protocol abstracts all the different states, and exposes at least one method that lets an external object perform the work in the said state. This method takes the context (CardReader) as a parameter, in order to perform the transitions.

Extracting a single protocol

Let's take a look at how to extract a single protocol:
protocol CardReaderState {
func perform(context: CardReader)
}
Next, we need to implement all our states as structs ...

Table of contents