Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Learning Design Patterns with Unity

You're reading from   Learning Design Patterns with Unity Learn the secret of popular design patterns while building fun, efficient games in Unity 2023 and C#

Arrow left icon
Product type Paperback
Published in May 2024
Publisher Packt
ISBN-13 9781805120285
Length 676 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Harrison Ferrone Harrison Ferrone
Author Profile Icon Harrison Ferrone
Harrison Ferrone
Arrow right icon
View More author details
Toc

Table of Contents (23) Chapters Close

Preface 1. Priming the System 2. Managing Access with the Singleton Pattern FREE CHAPTER 3. Spawning Enemies with the Prototype Pattern 4. Creating Items with the Factory Method Pattern 5. Building a Crafting System with the Abstract Factory Pattern 6. Assembling Support Characters with the Builder Pattern 7. Managing Performance and Memory with Object Pooling 8. Binding Actions with the Command Pattern 9. Decoupling Systems with the Observer Pattern 10. Controlling Behavior with the State Pattern 11. Adding Features with the Visitor Pattern 12. Swapping Algorithms with the Strategy Pattern 13. Making Monsters with the Type Object Pattern 14. Taking Data Snapshots with the Memento Pattern 15. Dynamic Upgrades with the Decorator Pattern 16. Converting Incompatible Classes with the Adapter Pattern 17. Simplifying Subsystems with the Façade Pattern 18. Generating Terrains with the Flyweight Pattern 19. Global Access with the Service Locator Pattern 20. The Road Ahead 21. Other Books You May Enjoy
22. Index

What are design patterns?

If I haven’t harped on this point enough, I want you to keep thinking to yourself “Design Patterns are systems” over and over. Let’s say that again, design patterns are systems, and systems are designed to solve specific problems. It doesn’t matter if it’s the brake system in your car, the biological systems that run our bodies, or the banking system in Figure 1.2. They’re all systems and they’re all trying to solve a problem or keep their respective system organized and balanced (and sometimes both).

Diagram  Description automatically generated

Figure 1.2: Diagram of how bank accounts work using credit and debit

More than anything, design patterns focus on making code more flexible and reusable, two tenets we’ll hammer away at throughout this book. Just keep repeating our mantra every time we dive into a new pattern: design patterns are systems!

The Gang of Four

Back in 1994, a group of four daring engineers banded together to better tackle OOP practices and recurring problems that kept popping up in their programs; Design Patterns: Elements of Reusable Object-Oriented Software written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides is the product of that team-up. The book covers 23 design patterns split into three categories according to their core functions, with examples written in C++ and Smalltalk. While the book was and continues to be an important resource, these patterns have been adapted and expanded since 1994, leaving some more (and some less) relevant depending on your chosen programming language and environment.

There are also those who have pointed out that a fair few of the patterns are replacements for perceived missing features in the C++ language. However, this argument has never resonated with me when I look at my code in other languages (whether it’s C# or something like Swift) because wearing my systems-thinking glasses has always made me think more critically and write code more intentionally.

You’ve likely heard the phrase “Gang of Four” whispered with quiet reverence (or loud and angry fist-shaking, depending on who you’re talking to), but with topics like this, I’ve found it’s best to learn design patterns as a skill before making judgments. There are impassioned programmers on both sides of the aisle, which means getting your hands dirty is the best thing you can do for yourself. A lot of the debate gets lost in theoretical or pedagogical minutiae (and personalities) but the core skillset behind design patterns has always been a useful tool for programming.

Pattern categories

There are three categories that all original design patterns fall into – Creational, Behavioral, and Structural. As with all things, additional patterns have evolved since 1994, resulting in useful patterns that were not included in the original Gang of Four book that we’ll cover on our journey and a few honorable mentions (because we can’t cover every design pattern in a single book).

Before we get into the category details, I feel it’s important to address a problem that crops up at the beginning of most journeys into design patterns – how do I find the right pattern for the problem I’m facing? Do I need to read and memorize every pattern, or is there a better way to navigate this topic?

The answer might surprise you, but no, this isn’t a memorization game and you don’t get extra points for knowing everything about every design pattern – systems thinking is a learned skill, not a closed-book test. It’s almost a detective game: first, knowing what problems each pattern category addresses is super important because it narrows the field you have to search. Second, reading the first few pages of each chapter in the applicable category will show you pretty quickly if you’re in the right place. From there, the more you use design patterns, the more you’ll get a feel for the problems and effective solutions out in the wild. As you’ll see, design patterns offer solutions to well-documented problems, but they’re not set in stone; it’s up to you to adapt them to your project.

Now that we know the basics, let’s dive into the nitty-gritty of each design pattern category and what specific problems they aim to solve.

Creational patterns

Creational patterns deal with creating objects that are uniquely suited to a given situation or use case. More specifically, these patterns deal with how to hide object and class creation logic, so the calling instance doesn’t get bogged down with the details. As your object and class creation needs become more complex, these patterns will help move you away from hardcoding fixed behaviors toward writing smaller behavior sets that you can use to build up more complex features (think LEGO). A good creational pattern black-boxes the creation logic and simply hands back a utility tool to control what, who, how, and when an object or class is created.

The creational patterns we’ll cover are listed in the following table:

Pattern

Description

Singleton

Ensure a class has only one instance and provide a global point of access to it – commonly used for features like logging or database connections that need to be coordinated and shared through the entire application.

Prototype

Specify the kinds of objects to create using a prototypical instance and create new objects from the “skeleton” of an existing object.

Factory Method

Define an interface for creating a single object, but delegate the instantiation logic to subclasses that decide which class to instantiate.

Abstract Factory

Define an interface for creating families of related or dependent objects, but let subclasses decide which class to instantiate.

Builder

Allows complex objects to be built step by step, separating an object’s construction from its representation – commonly used when creating different versions of an object.

Object Pool

Avoid expensive acquisition and release of resources by recycling objects that are no longer in use – commonly used when resources are expensive, plentiful, or both.

Table 1.1: List of creational design patterns with descriptions

Behavioral patterns

Behavioral patterns are concerned with how classes and objects communicate with each other. More specifically, these patterns concentrate on the different responsibilities and connections objects have with each other when they’re working together. Like structural patterns, behavioral patterns use inheritance to divvy up behaviors between classes, which gives you the freedom to let go of any white-knuckled control flow responsibilities and focus on how objects can work together.

The behavioral patterns we’ll cover are listed in the following table:

Pattern

Description

Command

Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests and the queuing or logging of requests.

Observer

Define a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically.

State

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class – commonly used when object behavior drastically changes depending on its internal state.

Visitor

Define a new class operation without changing the underlying object.

Strategy

Define a family of interchangeable behaviors and defer setting the behavior until runtime.

Type Object

Allow the flexible creation of new “classes” from a single class, each instance of which will represent a different type of object.

Memento

Capture and externalize the internal state of an object so it can be restored or reverted to this state later – without breaking encapsulation.

Table 1.2: List of behavioral design patterns with descriptions

Structural patterns

Structural patterns focus on composition, or how classes and objects are composed into larger, more complex structures. Structural patterns are heavy on abstraction, which makes object relationships easier to manage and customize. Patterns in this category will use inheritance to let you mix and match your class structures as well as create objects with new functionality at runtime.

The structural patterns we’ll cover are listed in the following table:

Pattern

Description

Decorator

Attach additional responsibilities to an object dynamically keeping the same interface.

Adapter

Convert the interface of a class into another interface clients expect. An adapter lets classes work together that could not otherwise because of incompatible interfaces.

Façade

Provide a unified interface to a set of interfaces in a subsystem. Facade defines a high-level interface that makes the subsystem easier to use.

Flyweight

Shares common data between similar objects to limit memory usage and increase performance.

Service Locator

Provide a global access point for services without coupling client code to the concrete service classes.

Table 1.3: List of structural design patterns with descriptions

The goal with each of these problems is to use a solution that is coherent, reusable, and above all, designed for efficient change.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime