We may earn an affiliate commission when you visit our partners.
Course image
Dmitri Nesteruk

Course Overview

This course provides a comprehensive overview of Design Patterns in Swift from a practical perspective. This course in particular covers patterns with the use of:

Read more

Course Overview

This course provides a comprehensive overview of Design Patterns in Swift from a practical perspective. This course in particular covers patterns with the use of:

  • The latest versions of the Swift programming language
  • Use of modern programming approaches: dependency injection, reactive programming and more
  • Use of modern developer tools
  • Discussions of pattern variations and alternative approaches

This course provides an overview of all the Gang of Four (GoF) design patterns as outlined in their seminal book, together with modern-day variations, adjustments, discussions of intrinsic use of patterns in the language.

What are Design Patterns?

Design Patterns are reusable solutions to common programming problems. They were popularized with the 1994 book Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, John Vlissides, Ralph Johnson and Richard Helm (who are commonly known as a Gang of Four, hence the GoF acronym).

The original book was written using C++ and Smalltalk as examples, but since then, design patterns have been adapted to every programming language imaginable: Swift, C#, Java, PHP and even programming languages that aren't strictly object-oriented, such as JavaScript.

The appeal of design patterns is immortal: we see them in libraries, some of them are intrinsic in programming languages, and you probably use them on a daily basis even if you don't realize they are there.

What Patterns Does This Course Cover?

This course covers all the GoF design patterns. In fact, here's the full list of what is covered:

  • SOLID Design Principles: Single Responsibility Principle, Open-Closed Principle, Liskov Substitution Principle, Interface Segregation Principle and Dependency Inversion Principle
  • Creational Design Patterns: Builder, Factories (Factory Method and Abstract Factory), Prototype and Singleton
  • Structrural Design Patterns: Adapter, Bridge, Composite, Decorator, Façade, Flyweight and Proxy
  • Behavioral Design Patterns: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Null Object, Observer, State, Strategy, Template Method and Visitor

Who Is the Course For?

This course is for Swift developers who want to see not just textbook examples of design patterns, but also the different variations and tricks that can be applied to implement design patterns in a modern way.

Presentation Style

This course is presented as a (very large) series of live demonstrations. All demos are single-file, so you can download the file attached to the lesson and run it in CLion, XCode or another IDE of your choice (or just on the command line).

This course does not use UML class diagrams; all of demos are live coding. I use Visual Studio Code for the demos.

Enroll now

What's inside

Learning objectives

  • Recognize and apply design patterns
  • Refactor existing designs to use design patterns
  • Reason about applicability and usability of design patterns
  • Implement each pattern in a coding exercise

Syllabus

A taste of things to come...

Five key principles of object-oriented design

What are SOLID principles, where do they come from and why do we care?

Read more

A look at the Single Responsibility Principle, which states that a class should only have one reason to change. Also tied to the concept of Separation of Concerns which is basically stating the same thing.

A discussion of the Open-Closed Principle, which states that classes should be open for extension, but closed for modification. In other words, you should extend functionality using interfaces and inheritance rather than jumping back into already-written/tested code and adding to it or changing it.

The Liskov Substitution Principle states that subtypes should be substitutable for their base types.

The Interface Segregation Principle is simple: don't throw everything in the kitchen sink into a protocol because then all its users will have to implement things they do not need. Instead, split the protocol into several smaller ones.

Not to be confused with dependency injection, dependency inversion specifies that high-level modules should not depend on low-level ones; both should depend on abstractions. Confusing, huh?

A summary of the things we've learned in this section of the course.

Learn to create and use the Builder design pattern

A discussion of the Builder pattern and what it's used for.

A look at why you'd want to have a builder in the first place.

We implement a simple builder for constructing trees of HTML elements.

We make the builder fluent by returning self from builder methods.

We look at a more complicated builder facade that exposes several sub-builders (builder facets) for building up parts of an object in a fluent manner.

Builder Coding Exercise

A summary of the things we've learned about the Builder pattern.

Effectively use the Factory Method and Abstract Factory patterns

A discussion of the general concept of factories and the two design patterns: Factory Methods and Abstract Factory.

A scenario where having a factory interface actually makes sense.

Implementing a factory method, as an alternative to an initializer, is easy.

When you want all the factory methods in a separate class.

An external factory needs the created object's constructor to be public. But what if you want it to be private? The solution is simple: stick a factory into the class whose instance it creates!

Sometimes, you want abstract factories with abstract objects; we support DIP but break OCP in the process.

Factory Coding Exercise

A summary of the things we've learned in this module.

Learn to use Prototype, a pattern that reuses already-constructed objects

A discussion of the Prototype factory (not to be confused with a rather good game of the same name) and what it's used for.

A copying approach straight from the land of C++.

What do you think about the idea of simply defining a protocol for deep-copyable reference types? Sounds like a simple idea, but we're going to encounter a problem with casting the result of out own initializer to Self. Don't worry, there is a fix for this.

Prototype Coding Exercise

A summary of all the things we've learned about the prototype pattern.

Learn to use (or avoid using) the much maligned Singleton pattern

Ahh, the much maligned Singleton? Is it really that evil? Let's find out...

Avoiding all the philosophical nonsense surrounding double-checked locking (it’s not thread-safe) and implementations involving inner static classes, we simply look at the safest possible singleton. But just because it's safe doesn't mean it's useful.

The singleton works fine, so what's the problem? Turns out, hard reference to a type means we cannot fake it in our tests. Oops!

The only socially acceptable way of using a singleton is with a DI framework. 
Typically, marking a component as a singleton is trivial.

A variation on a Singleton pattern, the Monostate lets the client instantiate as many copies of the singleton class as they want, but all those copies refer to the same static data. Is this a good idea? Let’s find out!

Singleton Coding Exercise

A summary of all that we've learned about the Singleton. As you can see, it's not really that evil provided it can be substituted by a different type (polymorphism). Also, lifetime management is best left to a specialized system (i.e. a DI container).

Learn to use the Adapter design pattern

A look at the Adapter design pattern.

We are going to build a simple adapter for the rending of vector data where only a raster renderer is available. 

An adapter can generate a large number of temporary objects. Caching helps us avoid doing extra work more than once.

Adapter Coding Exercise

A summary of all the things we've learned about the Adapter pattern.

Learn to use the Bridge design pattern

A discussion of the Bridge pattern and what it's used for.

A simple illustration of how to build a bridge.

Bridge Coding Exercise

A summary of all the important things we've learned in this section of the course.

Learn to use the Composite design pattern

A discussion of what the Composite pattern is for and how it's used.

Let's implement the Composite pattern by considering individual geometric shapes as well as grouping of shapes.

Let's apply the Composite pattern to the implementation of simple neural networks (individual neurons and layers of neurons).

Composite Coding Exercise

A summary of all the things we've learned about the Composite design pattern.

Learn to use the Decorator design pattern

A look at the Decorator design pattern.

Building strings is a common concern. Let's see how we can have its de facto inheritor as a Decorator.

When you implement pseudo-multiple inheritance using interfaces, you quite often end up implementing the Decorator pattern.

A look at how to make decorators-of-decorators.

Can decorators be composed as nested generic type arguments? They can, but things aren't as rosy in Swift as they are in C++.

Decorator Coding Exercise

A summary of all the things we've learned about the Decorator design pattern.

Learn to use the Façade design pattern

A look at the Façade design pattern. Also an explanation of that weird letter Ç.

An illustration of what a typical Facade looks like.

Façade Coding Exercise

A summary of the things we've learned about the Facade design pattern.

Learn to use the Flyweight design pattern

A discussion of the Flyweight design pattern and what it's used for.

An example of string space optimization when storing users' names.

Text formatting is a classic example of a Fliweight. Instead of keeping formatting flags for every single character in a line of text, let's implement ranges!

Flyweight Coding Exercise

A summary of all the things we've learned about the Flyweight design pattern.

Learn to use the Proxy design pattern

A look at the Proxy design pattern.

Let's implement a proxy which adds access control to the object.

One very common scenario is where developers replace ordinary properties with Property<T>-typed objects. Let's build out own implementation and discuss what it's for.

A comparison of the Proxy and Decorator design patterns.

Proxy Coding Exercise

A summary of the things we've learned about the Proxy design pattern.

Learn to use the Chain of Responsibility design pattern

A look at the Chain of Responsibility design pattern and discussion of what it's used for.

Brief discussion of the concept of Command Query Separation (CQS).

Chain of Responsibility implemented by chaining method calls together.

A more sophisticated approach to implementing the chain of responsibility.

Chain of Responsibility Coding Exercise

A summary of the things we've learned about the Chain of Responsibility design pattern.

Learn to use the Command design pattern

A look at the Command design pattern.

Let's implement the Command design pattern in a simple scenario.

A simple demonstration of how to implement Undo functionality while using Command.

Command Coding Exercise

A summary of all the things we've learned about the Command design pattern.

Learn to use the Interpreter design pattern

An overview of the Interpreter design pattern, which actually brings with it a whole field of Computer Science typically called Compiler Theory.

Lexing is the process of splitting textual input into lexical tokens.

Parsing is the process of converting a series of tokens into an Abstract Syntax Tree (AST).

Good to know

Know what's good
, what to watch for
, and possible dealbreakers
Explores major concepts of modern software engineering
Targeted to Swift developers
Modern industry practices
Covers all design patterns from the seminal book
Introduces language-intrinsic patterns

Save this course

Save Design Patterns in Swift to your list so you can find it easily later:
Save

Reviews summary

Insufficient practice

According to students, complex examples are used to explain design patterns, and they feel like they wasted time watching the instructor write code that could have been prepared in advance.
Time is wasted when instructor writes code.
"A lot of time wasted watching how teacher is writing code which could be already written."
Complex examples do not help explain concepts.
"In addition, a lot of no sense complex examples to explain patterns."

Activities

Be better prepared before your course. Deepen your understanding during and after it. Supplement your coursework and achieve mastery of the topics covered in Design Patterns in Swift with these activities:
Refresh knowledge on OOP concepts
Refreshes your understanding of OOP concepts, making it easier to follow along with the course material.
Show steps
  • Review notes or online resources on OOP concepts such as encapsulation, inheritance, and polymorphism
  • Complete practice problems or coding exercises related to OOP
Watch tutorials on design patterns
Provides a deeper understanding of how design patterns are applied in real-world scenarios.
Browse courses on Design Patterns
Show steps
  • Identify a specific design pattern you want to learn more about
  • Search for tutorials or online courses that cover that design pattern
  • Follow the tutorial and complete any accompanying exercises or projects
Complete coding exercises on design patterns
Provides hands-on experience in implementing and applying design patterns.
Browse courses on Design Patterns
Show steps
  • Find online coding platforms or resources that offer design pattern exercises
  • Select an exercise and read the problem statement carefully
  • Design and implement a solution using the appropriate design pattern
  • Test and debug your code to ensure it meets the requirements
Four other activities
Expand to see all activities and additional details
Show all seven activities
Mentor junior developers or students on design patterns
Strengthens your understanding of design patterns by teaching and assisting others.
Browse courses on Design Patterns
Show steps
  • Identify opportunities to mentor junior developers or students in your workplace or community
  • Share your knowledge and experience on design patterns, providing guidance and support
  • Provide feedback and review their work to help them improve their understanding and application of design patterns
Contribute to an open-source project that uses design patterns
Provides practical experience in applying design patterns in a real-world project.
Browse courses on Design Patterns
Show steps
  • Find an open-source project on platforms like GitHub or GitLab that uses design patterns
  • Review the project's documentation and codebase to understand its design and usage of design patterns
  • Identify an area where you can contribute by adding a new feature or fixing a bug using design patterns
  • Submit your pull request and work with the project maintainers to get it merged
Write a blog post or article about a design pattern
Solidifies your understanding of a design pattern by explaining it to others.
Browse courses on Design Patterns
Show steps
  • Choose a specific design pattern that you are familiar with
  • Write a blog post or article that explains the concept, benefits, and usage of the design pattern
  • Share your blog post or article with others for feedback and discussion
Develop a design pattern library or framework
Provides a comprehensive and reusable resource for design patterns in Swift.
Browse courses on Design Patterns
Show steps
  • Research and identify the most commonly used design patterns in Swift
  • Design and implement a library or framework that provides these design patterns as reusable components
  • Write documentation and examples to guide users on how to use the library or framework effectively
  • Share your library or framework with the community through platforms like GitHub or Swift Package Manager

Career center

Learners who complete Design Patterns in Swift will develop knowledge and skills that may be useful to these careers:
Software Engineer
As a Software Engineer, a key part of the job is designing and coding functional and robust solutions for a variety of business and technical use cases. The Design Patterns in Swift course on Coursera will help you to maximize your productivity in this process by teaching you advanced programming approaches and design principles which you can apply to your everyday work. The course's focus on practical implementation of these design patterns in your code will help you to develop software that can adapt easily to new requirements.
Computer Programmer
Computer Programmers are responsible for implementing new features and updates to existing software. This course will help build a foundation in this process through practical, hands-on exercises that teach you modern programming approaches and advanced design principles. The course's focus on discussions and alternative approaches to design patterns will also help you to think more flexibly and creatively about your work as a Programmer.
Web Developer
Web Developers use their programming knowledge to design and maintain websites and web applications. This course will help you to be more efficient in your work by teaching you advanced programming approaches and design principles. Specifically, the focus on modern developer tools will help you to work with a familiar toolset on a daily basis.
Mobile App Developer
Mobile App Developers typically design, develop, and implement mobile apps for various devices. This course will help build a foundation in this process by teaching you modern programming approaches and advanced design principles. In particular, the focus on discussions and alternative approaches to design patterns will help you to stay up-to-date with the latest developments and trends in mobile app development.
Software Architect
As a Software Architect, a major part of the job is designing and overseeing the development of software applications. This course will help build a foundation in this process by teaching you advanced programming approaches and design principles and will help you to maximize your productivity in your work.
Data Scientist
Data Scientists use their programming and analytical skills to extract insights from data. This course will help you to be more efficient in your work by teaching you advanced programming approaches and design principles. In particular, the focus on modern developer tools will help you to work with a familiar toolset on a daily basis.
Database Administrator
Database Administrators use their programming skills to manage and maintain databases. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your database management work.
Systems Analyst
Systems Analysts use their programming skills to analyze and design business systems. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your systems analysis work.
Software Tester
Software Testers use their programming skills to test and evaluate software applications. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your software testing work.
Technical Writer
Technical Writers use their programming skills to create documentation for software applications. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your technical writing work.
Computer Support Specialist
Computer Support Specialists provide technical support to computer users. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your problem-solving work.
Information Security Analyst
Information Security Analysts use their programming skills to protect computer systems and data from unauthorized access. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your work.
Network Administrator
Network Administrators use their programming skills to manage and maintain computer networks. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your network administration work.
Webmaster
Webmasters use their programming skills to design, develop, and maintain websites. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your web development work.
Computer Systems Analyst
Computer Systems Analysts use their programming skills to analyze and design computer systems. This course may be useful for you in this role because it will teach you advanced programming approaches and design principles that you can use in your systems analysis work.

Reading list

We've selected 13 books that we think will supplement your learning. Use these to develop background knowledge, enrich your coursework, and gain a deeper understanding of the topics covered in Design Patterns in Swift.
More accessible and entertaining introduction to design patterns than the Gang of Four book. It uses humor and real-world examples to explain the concepts in a way that is easy to understand.
Comprehensive guide to design patterns in Swift. It covers all the GoF design patterns, as well as modern-day variations and adjustments.
Classic guide to writing effective Java code. It covers a wide range of topics, including design patterns, concurrency, and performance.
Practical guide to writing clean and maintainable code. It covers a wide range of topics, including naming conventions, coding style, and refactoring.
Clear and concise guide to design patterns. It uses simple language and examples to explain the concepts in a way that is easy to understand.
Classic guide to enterprise application architecture. It covers a wide range of topics, including design patterns, architectural styles, and best practices.
Practical guide to test-driven development. It covers a wide range of topics, including design patterns, testing techniques, and best practices.
Classic guide to domain-driven design. It covers a wide range of topics, including design patterns, domain-driven design principles, and best practices.
Practical guide to software architecture. It covers a wide range of topics, including design patterns, architectural styles, and best practices.
Classic guide to enterprise integration patterns. It covers a wide range of topics, including design patterns, integration patterns, and best practices.
Practical guide to cloud design patterns. It covers a wide range of topics, including design patterns, cloud computing concepts, and best practices.

Share

Help others find this course page by sharing it with your friends and followers:
Our mission

OpenCourser helps millions of learners each year. People visit us to learn workspace skills, ace their exams, and nurture their curiosity.

Our extensive catalog contains over 50,000 courses and twice as many books. Browse by search, by topic, or even by career interests. We'll match you to the right resources quickly.

Find this site helpful? Tell a friend about us.

Affiliate disclosure

We're supported by our community of learners. When you purchase or subscribe to courses and programs or purchase books, we may earn a commission from our partners.

Your purchases help us maintain our catalog and keep our servers humming without ads.

Thank you for supporting OpenCourser.

© 2016 - 2024 OpenCourser