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

  1. 414 pages
  2. English
  3. ePUB (adapté aux mobiles)
  4. Disponible sur iOS et 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

DĂ©tails du livre
Aperçu du livre
Table des matiĂšres
Citations

À propos de ce livre

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.

Foire aux questions

Comment puis-je résilier mon abonnement ?
Il vous suffit de vous rendre dans la section compte dans paramĂštres et de cliquer sur « RĂ©silier l’abonnement ». C’est aussi simple que cela ! Une fois que vous aurez rĂ©siliĂ© votre abonnement, il restera actif pour le reste de la pĂ©riode pour laquelle vous avez payĂ©. DĂ©couvrez-en plus ici.
Puis-je / comment puis-je télécharger des livres ?
Pour le moment, tous nos livres en format ePub adaptĂ©s aux mobiles peuvent ĂȘtre tĂ©lĂ©chargĂ©s via l’application. La plupart de nos PDF sont Ă©galement disponibles en tĂ©lĂ©chargement et les autres seront tĂ©lĂ©chargeables trĂšs prochainement. DĂ©couvrez-en plus ici.
Quelle est la différence entre les formules tarifaires ?
Les deux abonnements vous donnent un accĂšs complet Ă  la bibliothĂšque et Ă  toutes les fonctionnalitĂ©s de Perlego. Les seules diffĂ©rences sont les tarifs ainsi que la pĂ©riode d’abonnement : avec l’abonnement annuel, vous Ă©conomiserez environ 30 % par rapport Ă  12 mois d’abonnement mensuel.
Qu’est-ce que Perlego ?
Nous sommes un service d’abonnement Ă  des ouvrages universitaires en ligne, oĂč vous pouvez accĂ©der Ă  toute une bibliothĂšque pour un prix infĂ©rieur Ă  celui d’un seul livre par mois. Avec plus d’un million de livres sur plus de 1 000 sujets, nous avons ce qu’il vous faut ! DĂ©couvrez-en plus ici.
Prenez-vous en charge la synthÚse vocale ?
Recherchez le symbole Écouter sur votre prochain livre pour voir si vous pouvez l’écouter. L’outil Écouter lit le texte Ă  haute voix pour vous, en surlignant le passage qui est en cours de lecture. Vous pouvez le mettre sur pause, l’accĂ©lĂ©rer ou le ralentir. DĂ©couvrez-en plus ici.
Est-ce que Hands-On Design Patterns with Swift est un PDF/ePUB en ligne ?
Oui, vous pouvez accĂ©der Ă  Hands-On Design Patterns with Swift par Florent Vilmart, Giordano Scalzo, Sergio De Simone en format PDF et/ou ePUB ainsi qu’à d’autres livres populaires dans Informatik et Programmierung. Nous disposons de plus d’un million d’ouvrages Ă  dĂ©couvrir dans notre catalogue.

Informations

Année
2018
ISBN
9781789138511
Édition
1
Sous-sujet
Programmierung

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 des matiĂšres