Design Patterns in C# Made Simple
4.7 (41 ratings)
Course Ratings are calculated from individual students’ ratings and a variety of other signals, like age of rating and reliability, to ensure that they reflect course quality fairly and accurately.
309 students enrolled

Design Patterns in C# Made Simple

Using patterns to improve flexibility of the design
Highest Rated
4.7 (41 ratings)
Course Ratings are calculated from individual students’ ratings and a variety of other signals, like age of rating and reliability, to ensure that they reflect course quality fairly and accurately.
309 students enrolled
Created by Zoran Horvat
Last updated 5/2020
Current price: $17.99 Original price: $29.99 Discount: 40% off
1 day left at this price!
30-Day Money-Back Guarantee
This course includes
  • 5 hours on-demand video
  • 15 downloadable resources
  • Full lifetime access
  • Access on mobile and TV
  • Certificate of Completion
Training 5 or more people?

Get your team access to 4,000+ top Udemy courses anytime, anywhere.

Try Udemy for Business
What you'll learn
  • How to apply design patterns to help simplify application design
  • How to reduce design complexity by moving responsibilities into collaborating classes
  • Fair understanding of the C# programming language
  • Working knowledge of software design
  • Any knowledge of design patterns is a plus

More than two decades since design patterns have appeared, many developers consider them the most important discovery in software development. Others still find them a bad idea. And both are right! How comes?

In this course, you will learn how design patterns can be applied to make code better: flexible, short, readable. Flexibility is the key element in design patterns. You will learn how to decide when and which pattern to apply by formally analyzing the need to flex around specific axis. You will learn which pattern is adding which kind of flexibility, and what are the most common forms of implementation in practice. You will also learn common pitfalls and ways to overcome them when applying specific patterns.

Who this course is for:
  • Hands-on programmers who are struggling to keep their source code clean and extensible
  • Programmers who wish to apply design patterns without causing more harm than good
  • All those who wish to improve their object-oriented programming and design skills
Course content
Expand all 54 lectures 05:01:17
+ Introduction
2 lectures 18:25

Answers basic questions regarding any design pattern: Why do we need it, when do we need it, and which pattern in particular do we need?

Preview 13:42

This clip will inform you about the structure of the rest of the course. It will also inform you where the resources are located and how to use them while watching the videos.

How This Course Is Structured
+ Adding Behavior to an Object with the Decorator Pattern
5 lectures 33:53

Identifies the need for the Decorator pattern by identifying problems in the design which is lacking it.

Motivation for the Decorator Pattern

Attempts to solve the problem by subclassing. This attempt will eventually fail.

The First Attempt to Decorate a Class

Demonstrates a programming bug that can be materialized and manifested when subclassing is used to implement a decorator.

The Downfall of the Subclassing Decorator

Introduces decorators based on object composition rather than inheritance.

Using Object Composition Instead of Inheritance

Summarizes this module.


Answer these questions to verify your understanding of the Decorator design pattern.

Decorator pattern questions
5 questions
+ Adapting to a Different Interface with the Adapter Pattern
5 lectures 30:27

Explains the need for the adapters and how they differ from decorators.

Advancing from Decorator to Adapter Pattern

Applies the Adapter design pattern to resolve the problem identified in the initial design.

Implementing a Transparent Adapter

Demonstrates common problems which appear when programmers start relying on adapters beyond reasonable bounds.

Towards a Heavyweight Adapter

Splits the adapter into smaller, interacting objects to resolve the issues appearing in the bloated, heavyweight adapter.

Limiting the Role of Adapters

Summarizes this module.


Answer these questions to verify your understanding of the Adapter design pattern.

Adapter pattern questions
5 questions
+ Constructing Flexible Behavior with the Strategy Pattern
8 lectures 40:11

Outlines problems that appear when domain-related behavior is implemented as a fixed block of code.

Understanding the Need for Flexibility

Demonstrates how basic implementation of the Strategy design pattern helps introduce flexibility in behavior.

Implementing the Strategy Pattern

Demonstrates how interface can be used to represent a Strategy.

Implementing Strategies via the Interface

Demonstrates how strategies can be made even more flexible without complicating the consumer.

Augmenting the Strategy Interface

Outlines full power of dynamically injected strategies.

Demonstrating the Power of Strategies

Introduces recursive nature of strategies by introducing strategies that depend on their own strategies.

Implementing Strategies with Strategies

Identifies Strategy as one of the most widely used patterns in the .NET Framework.

Strategies in the .NET Framework

Summarizes this module.


Answer these questions to verify your understanding of the Strategy design pattern.

Strategy pattern questions
6 questions
+ Decoupling Classes with the Abstract Factory Pattern
7 lectures 35:24

Introduces the problem domain where runtime types of objects used sometimes need to vary. Introduces Abstract Factory as the solution to varying types of consumed objects.

Understanding the Need for Abstract Factory Pattern

Outlines principal limitation of the Abstract Factory: Inability to reconcile constructor parameter lists in unrelated product bundles.

Understanding the Limitations of the Abstract Factory

Demonstrates possible solutions to the problem of constructor parameter lists through use of common, extensible document types.

Attempting to Overcome the Limitations

Demonstrates effective implementation of concrete factories when their common interfaces have been designed.

Implementing Concrete Factories

Completes the previous demonstration by implementing all the details in concrete factories.

Completing the Concrete Factories

Demonstrates the use and substitutability of concrete factories. Outlines pros and cons of applying the Abstract Factory pattern.

Demonstrating the Concrete Factories

Summarizes this module.


Answer these questions to verify your understanding of the Abstract Factory design pattern.

Abstract Factory pattern questions
5 questions
+ Constructing Objects on the Fly with the Factory Method Pattern
6 lectures 33:11

Explains how large Abstract Factory can be transformed into smaller, more focused mini-factories: factory methods.

From Abstract Factory to Factory Method

Explains how state can be retained behind the factory method, so that it doesn't have to be passed with every call to the method.

Holding State Behind a Factory Method

Introduces parameter fixing, so that the factory method can be consumed without knowing all the parameters.

Fixing Parameters with Factory Method

Demonstrates the principal power of factory methods to stop propagation of design changes that are affecting their products, but not their consumers.

Confining Propagation of Change with Factory Methods

Introduces the functional concept of currying to factory methods, demonstrating how factory methods can be simplified and made more powerful.

Currying Factory Methods

Summarizes this module.

+ Encapsulating Construction Rules with the Builder Pattern
6 lectures 33:54

Identifies principal limitations characteristic to all factories: inability to handle optional components and components that appear in multiple forms.

Understanding Limitations of Factories

Introduces the Builder design pattern as an alternative to factories.

Replacing Factory with Builder

Explains common methods of validating components passed to the Builder. Introduces the fail-fast principle.

Adding Validation to the Builder

Explains how Builder can cope with components that appear in multiple forms, and with optional components.

Handling Variation and Optional Components

Demonstrates how a fully populated Builder can be reduced to a Factory Method without making it visible to the client.

Building a Factory Method

Summarizes this module.

+ Constructing Complex Objects with the Builder Pattern
8 lectures 41:13

Introduces a new example domain: Building a large graph of objects. Explains how Builder pattern can apply to this problem.

Building a Graph of Objects

Outlines the principal problem with the Builder pattern: Inconsistency of the Builder object through its lifetime. Explains why we need the Builder object to be internally consistent despite missing components.

Understanding the Need for a Consistent Builder

Introduces a completely new design of the Builder, which only exposes parts of the builder object that are guaranteed to be consistent.

Designing a Consistent Builder

Extends previous design by supporting alternative representations of some components in the consistent builder.

Adding Alternatives to a Consistent Builders

Demonstrates fluent API applied to the Builder design pattern. Helps consumer retain full readability and safety when consuming a builder.

Designing a Fluent Builder

Explains complexities and solutions to the problem of designing an immutable builder in software which insists on immutability.

Designing an Immutable Builder

Demonstrates how use of immutable collections can help design an immutable builder almost with no effort.

Shameless Immutability in Builders

Summarizes this module.

+ Treating Collection as an Object with the Composite Pattern
7 lectures 34:39

Outlines how complexity of a class grows when it attempts to handle multiple contained objects.

Understanding Multitudes of Objects

Introduces basic implementation of the Composite design pattern. Demonstrates its immediate simplifying effect on the class that consumes it.

Inventing the Composite Element

Demonstrates that composite elements are recursive by definition. Explains how this recursive nature can be limited, depending on the problem domain to which it is applied.

Understanding Recursive Nature of Composites

Demonstrates how Composite pattern can be hidden behind a Factory Method, so that the client only remains dependent on an abstraction, not on concrete types used to implement the Composite pattern.

Combining Composite and Factory Methods

Introduces more variation into the Composite pattern by combining it with full-fledged Abstract Factory pattern.

Combining Composite and Abstract Factory

Experiments with the thought that some consumers have an opposite need: To view all occurrences as multiple objects, including to represent one object as many.

Reversing Composites: Representing One Element as Many

Summarizes this module.