Technical interview questions with detailed answers—organized by course, like Dot Net Tutorials interview sections. Original content for Toolliyo Academy.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Optimizations such as memoization (caching results) can be used to avoid
redundant evaluations, particularly for recursive expressions.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
over time and can save and restore its state using mementos.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
additional functionality like removing items during iteration.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
code more flexible. You can add new sorting algorithms without changing the
context class, thus adhering to the Open/Closed Principle (open for
extension, closed for modification).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
challenging. Every new element requires modifying all existing visitor classes
to implement the new Visit method.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the traffic light to transition between states (Red, Green, Yellow).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
instance, turning the amplifier on or off, or playing a movie in the DVD player.
These actions are usually cumbersome for the user to manage directly.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
code. The client doesn’t need to know which handler will process the request,
only that the request will eventually be processed by some handler in the
chain.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Dough, Sauce, and a list of Toppings. The ToString() method is
overridden to provide a string representation of the pizza.
public class Pizza
public string Dough { get; set; }
public string Sauce { get; set; }
public List<string> Toppings { get; } = new List<string>();
public override string ToString() =>
$"Pizza with {Dough} dough, {Sauce} sauce and toppings:
{string.Join(", ", Toppings)}";
Gang of Four Patterns Design Patterns in C# · GoF Patterns
expressions like 5 + 3 * 2 can leverage the Interpreter Pattern to handle
different operators and operands. Each part of the expression (numbers,
operators) is represented as an object that can be evaluated.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
method, which is designed to accept a visitor. This method typically calls the
appropriate visit method (Visit(Book book) or Visit(Fruit fruit))
on the visitor.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
is shared across multiple instances (the character symbol, in this case), and it
provides a Display method to show the character's symbol at a particular
coordinate.
public class Character
private readonly char _symbol;
public Character(char symbol) => _symbol = symbol;
public void Display(int x, int y) =>
Console.WriteLine($"Character: {_symbol} at ({x}, {y})");
Gang of Four Patterns Design Patterns in C# · GoF Patterns
interface, which defines the common method ShowInfo(). This allows us to
treat both files and directories uniformly.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the state (the text content) and doesn’t allow direct manipulation of that state.
public class TextMemento
public string Text { get; }
public TextMemento(string text) => Text = text;
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
swapped in and out. The context (Sorter) doesn't need to know the specifics
of the algorithm; it only knows that it can call the Sort method on any
strategy that implements this interface.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
perform operations on them that vary.
complex hierarchy (like a shopping cart with various types of products), and
you need to add new behaviors without changing the objects themselves.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
IDrawingAPI and delegates the drawing task to it. It defines the common
interface Draw() that all shapes must implement.
public abstract class Shape
protected IDrawingAPI _drawingAPI;
protected Shape(IDrawingAPI drawingAPI) => _drawingAPI =
drawingAPI;
public abstract void Draw();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
with complex subsystems. The user only needs to interact with a few
high-level methods, making the system easier to use.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
same interface (IImage) as the real subject (RealImage).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
projector, lights, sound system) to the facade without modifying the client
code. This extends the flexibility of the facade as the system becomes more
Follow:
complex.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
will be implemented by both leaf and composite components.
public interface IFileSystemComponent
void ShowInfo();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
algorithms is small, using the Strategy Pattern might be over-engineering.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
be created. The instance is stored in the static _instance field, ensuring
that only one object exists.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
that all iterators implement the basic functionality of checking for the next
element (HasNext()) and returning the next element (Next()).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
task and want to switch between them easily (e.g., sorting, encryption,
compression).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
of all users and broadcasts messages to all other users when one user sends
a message.
loose coupling.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
IFileSystemComponent interface. This makes it easier to manage a mixed
structure of individual and composite objects.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
scores). Using the Flyweight Pattern, you can optimize memory usage by
reusing the same Character objects for common letters or symbols, rather
than creating a new object for each instance.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
It calls GatherIngredients, Prepare, CookMethod, and Serve in a fixed
order. The first three steps are abstract and need to be implemented by
subclasses, while the Serve method is concrete and always works the same
way.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
observers. The subject manages a list of observers and notifies them when there is
an update.
public interface INewsPublisher
Follow:
void Subscribe(IObserver observer);
void Unsubscribe(IObserver observer);
void Notify(string news);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
operation, you could store the undone command in a separate stack and
allow users to redo the previous undo operation.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
file systems. A file system is inherently hierarchical: directories contain files
and subdirectories, and those subdirectories can contain further files or
subdirectories. The Composite Pattern allows for easy traversal and
management of this hierarchical structure.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
performed on the IShoppingCartElement objects. In this case, the visitor defines
Visit(Book book) and Visit(Fruit fruit) methods for different product
types.
public interface IShoppingCartVisitor
void Visit(Book book);
void Visit(Fruit fruit);
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the application (e.g., database connection strings, file paths, API keys).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
properties are copied. If the object contains references to other objects (e.g.,
arrays, lists), you may need to implement deep cloning to ensure that
referenced objects are also cloned, not just referenced.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
components. It could be improved by adding a Remove() method to allow for
the dynamic removal of files or subdirectories.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
■ SendMessage(string message, User user): Sends a
message from a user to all other registered users.
■ RegisterUser(User user): Registers users with the mediator so
they can send and receive messages.
public interface IChatMediator
void SendMessage(string message, User user);
void RegisterUser(User user);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
state to transition to another state. The method accepts a TrafficLight object as
a parameter to facilitate the state change.
public interface ITrafficLightState
void Change(TrafficLight light);
the specific behavior of the traffic light for that state.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
SetNext() on the infoLogger and passing it the errorLogger. This
ensures that the InfoLogger will process log messages with the Info level,
while the ErrorLogger will handle Error level messages.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
especially when dealing with high-resolution media files that could be costly to
load upfront.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
to undo the most recent changes. Each time the user types, the editor saves
a snapshot of the text as a Memento. Pressing Ctrl + Z restores the text to its
previous state.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
and subject to change. By defining expressions as objects, it’s easy to extend
or modify the grammar without affecting other parts of the system.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
types like buttons and checkboxes. This ensures that every concrete factory
will implement the same methods, but each will provide platform-specific
products.
public interface IUIFactory
IButton CreateButton();
ICheckbox CreateCheckbox();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
strategies must implement. This allows clients (in this case, the Sorter class) to
work with any strategy that implements this interface.
public interface ISortStrategy
void Sort(List<int> list);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
especially when the object is complex or expensive to create. This can be
particularly useful in performance-sensitive applications like games or
simulations.
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
actually needed, like the ProxyImage example above.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
libraries without modifying their code. It enables compatibility between
incompatible interfaces.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
representation. You can change the construction process without changing
the way the object is represented or structured.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
■ Execute(): Executes the command.
■ Undo(): Reverts the command if the user wishes to undo the action.
Follow:
public interface ICommand
void Execute();
void Undo();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
some of the steps need to be customized for different situations. For example,
when creating frameworks for processes like data parsing, game initialization,
or file handling.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
ChocolateDecorator, or CaramelDecorator, for a richer coffee
experience.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
The TextEditor only knows how to invoke commands but does not need to
understand the details of the operations (e.g., how the text is added or
removed).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
is shared across all instances. This makes it an ideal candidate for the
Flyweight Pattern because multiple characters (e.g., 'H', 'e', 'l') may appear
many times in the same text, but they only need one Character object for
the symbol.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
of an object. Any class that needs to be cloned must implement this interface.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
It has a method Request() that the client expects to call.
public interface ITarget
void Request();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
customer lists, or any other collection where you need to iterate over items
sequentially. For instance, in an e-commerce application, you might use an
iterator to list products, iterate through available categories, or paginate
results.
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
subclasses don't have to repeat the same steps. Only the details of specific
steps need to be implemented in each subclass.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
instance of it throughout the application.
ensuring that it's only created once and then reused.
public class ConfigurationManager
private static ConfigurationManager _instance;
private static readonly object _lock = new object(); // Lock
for thread safety
private ConfigurationManager() { } // Private constructor to
prevent instantiation
public static ConfigurationManager Instance
get
lock (_lock) // Ensure thread safety
return _instance ??= new ConfigurationManager(); //
Lazy initialization
Follow:
public string GetSetting(string key) => "some value"; // Example
method to return a setting
directly. This ensures that the class cannot be instantiated more than once.
ConfigurationManager. It uses lazy initialization to create the instance
only when it's first needed.
thread-safe, preventing multiple threads from creating multiple instances at
the same time in a multithreaded environment.
ensuring that the instance is created only once and reused thereafter.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
add text to the document as an object. This allows for parameterization of the
command with different requests (e.g., adding different text) while decoupling
the sender (the TextEditor) from the receiver (Document).
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
result in significant memory usage, as you need to store many copies of the
state (each memento).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
object (ProxyImage) implement. It defines the method Display() that both
concrete classes must implement.
public interface IImage
void Display();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
maintains a list of IObserver instances (subscribers) and provides methods
to add (Subscribe), remove (Unsubscribe), and notify them (Notify).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
provides a global access point to that instance. This is especially useful when
managing resources that should be shared across the application, such as
configuration settings, logging, or database connections.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
all types of loggers (e.g., file, console).
public interface ILogger
void Log(string message);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
new articles or breaking news are published.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
handling log messages. It includes a reference to the next logger in the chain
(NextLogger) and a method (LogMessage) to process a message. If the
current handler cannot handle the message, it passes the request along to
the next handler in the chain.
public abstract class Logger
protected Logger NextLogger;
public void SetNext(Logger nextLogger) => NextLogger =
nextLogger;
public void LogMessage(string message, LogLevel level)
if (CanHandle(level))
Handle(message);
else
NextLogger?.LogMessage(message, level);
protected abstract bool CanHandle(LogLevel level);
protected abstract void Handle(string message);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
returns an ILogger object. This is a generic interface for creating various
Follow:
logger types without specifying the concrete class directly.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Review the concept and prepare a concise verbal explanation with a real project example.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
thread safety without locking. However, it may have a slight performance
overhead due to the instance being created regardless of whether it is
needed.
public class Singleton
private static readonly Singleton _instance = new Singleton();
private Singleton() { }
public static Singleton Instance => _instance;
Gang of Four Patterns Design Patterns in C# · GoF Patterns
This allows the decorators to work with any class that implements this
interface, providing flexibility to decorate any coffee object.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
in the Memento object, and the TextEditor is not exposed to direct
manipulation of its internal state. The only way to change or access the state
is through well-defined methods (Save and Restore).
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
subclasses cannot change the overall order or flow of steps. If you need to
adjust the structure of the algorithm, it may require changes to the base class.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
critical part of the system. If the mediator fails, the entire communication
system breaks down. This could be mitigated by introducing fault tolerance or
redundancy in the mediator.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
state changes and can lead to issues with dependencies.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
grammar, allowing them to be interpreted (evaluated). Every class that
implements this interface will provide its own interpretation logic.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
different log outputs. For example, a logging framework can provide loggers
that write to the console, files, databases, or cloud services, with the user
choosing the appropriate logger type via a factory.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
player, and projector can be tedious. A Facade Pattern can simplify this into
a single button or command (like WatchMovie()), where the user only
needs to press one button to turn everything on.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
CharacterFactory can implement cache management strategies like
LRU (Least Recently Used) or FIFO (First In, First Out) to evict older or
unused objects and maintain memory efficiency.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
use based on external configurations, like settings or environment variables.
This would enable the system to switch between different logging
mechanisms or database connections without recompiling the application.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
implementation (drawing API) independently, providing a cleaner and more
modular design.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
and Description() that every coffee component will implement.
public interface ICoffee
double Cost();
string Description();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
observers. The subject does not know about the specific observers, only that
they implement the IObserver interface. This makes the system more
Follow:
flexible and easier to maintain.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
customers can customize their coffee with various add-ons (milk, sugar,
whipped cream, flavor syrups, etc.). Each add-on is a decorator that adds a
cost and modifies the description of the order without modifying the core
coffee object.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
mediator is responsible for sending messages between users. It ensures that
messages are routed correctly without the users needing to know about each
other.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
skeleton. It delegates the implementation of specific steps (GatherIngredients,
Prepare, and CookMethod) to subclasses by making them abstract. The Serve
method is concrete and always executes the same way for all recipes.
public abstract class Recipe
public void Cook()
Follow:
GatherIngredients();
Prepare();
CookMethod();
Serve();
protected abstract void GatherIngredients();
protected abstract void Prepare();
protected abstract void CookMethod();
private void Serve() => Console.WriteLine("Serving the dish.");
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Flyweight Pattern reduces memory consumption significantly. Instead of
creating multiple objects for each appearance of a character, only one object
is created for each unique character.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
behavior depends on the current state (e.g., traffic lights, order processing
systems).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
from the objects on which it operates. This makes the object structure
(elements) cleaner, as they are not responsible for the business logic.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
to an increase in the number of classes in the system. For systems with many
states, this can cause complexity.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
application log to the same destination (e.g., a log file or a central logging
service).
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
repeated elements (e.g., the same type of tiles or blocks). Using the Flyweight
Pattern, you can create a single object for each tile type and reuse it across
multiple grid locations, saving memory.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
group of shapes). Each shape (a circle, a rectangle, etc.) can be treated as
an individual object, while a group of shapes can be treated as a composite
object. The Composite Pattern makes it easier to manage complex graphical
objects that contain simple shapes.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
should be taken to ensure thread safety. The flyweight factory could use a
concurrent dictionary or apply locking mechanisms to prevent concurrent
access to the shared flyweight objects.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
providing specific behaviors for each state and defining how the transition to
the next state occurs.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
transitioning between states needs to be managed cleanly and without
complex conditionals.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
algorithm. These algorithms can be tested, optimized, or replaced without
Follow:
affecting the context or the other algorithms.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
price and a basic description. This is the base coffee that we will add features
to dynamically.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
might become complex and difficult to maintain. It's essential to manage its
complexity to avoid it becoming a bottleneck or overly complicated.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
expressions can be broken down into simpler expressions, and the results of
those can be combined to form more complex evaluations.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
replace it in unit tests, leading to potential challenges in testing.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
in the number of classes in your application, which might not be desirable in
simpler systems.
Follow:
Conclusion:
The Strategy Pattern is an excellent choice for applications that need to support multiple
interchangeable algorithms. By encapsulating algorithms in separate strategy classes and
delegating the task to the context, you avoid conditional statements and make your code
more flexible, maintainable, and extensible. It's especially useful in scenarios like sorting,
different payment methods, or compression algorithms where the behavior of the object
varies based on the strategy being used.
Template Method Pattern: Defining the Skeleton of an Algorithm
Definition:
The Template Method Pattern defines the skeleton of an algorithm in a method, deferring
some steps to subclasses. This pattern lets subclasses redefine certain steps of an
algorithm without changing the overall structure of the algorithm. Essentially, the Template
Method sets the "template" or the common sequence of steps, while allowing subclasses to
provide specific implementations for some of the steps.
Use Case:
A typical use case for the Template Method Pattern is creating a framework for a
cooking recipe where every recipe follows a similar structure (e.g., gather ingredients,
prepare, cook, and serve), but the actual details of each step can vary depending on the
type of recipe.
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Prepare, and CookMethod methods. These methods contain the specific
Follow:
details of the recipe, such as the ingredients, preparation steps, and cooking
process.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
case, the text content). It doesn't expose any internal details of the
TextEditor, preserving encapsulation.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
system more complex, especially when the number of elements and visitors
increases.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
It’s advisable to add error-checking mechanisms (e.g., checking for division
by zero, invalid operators, etc.) to make the interpreter more robust.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
to be iterated over. It provides the CreateIterator() method that returns
an iterator for that collection.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
collection (e.g., whether it's a list or a tree). It can use the iterator interface to
access the elements sequentially, leading to cleaner and more maintainable
code.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
removing handlers at runtime. This makes it flexible to change the behavior of
the system without modifying the request-handling code.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
decorate a button with additional features (like borders, shadows, or icons)
dynamically. You don't need to subclass the button every time you want to
add new functionality.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
menu structure can be achieved using the Iterator Pattern. Each menu can
be an aggregate, and each menu item can be iterated over using an iterator.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
might require synchronized access to the collection. The iterator can be
modified to handle concurrency issues.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Cost() method to calculate discounts or offer combo prices (e.g., a discount
when multiple ingredients are added).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
The client code doesn't need to manage state transitions; it's handled by the
state objects themselves.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
When a user sends a message, the mediator handles the responsibility of
broadcasting that message to other users.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
makes it easier to modify or extend how messages are passed. For example,
adding new features like message filtering or logging can be done in the
mediator without affecting the users.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
high-level methods: WatchMovie() and EndMovie(). These methods
internally call the relevant methods on the subsystem components (e.g., On()
for the amplifier, Play() for the DVD player). The user doesn’t need to deal
with the details of how the components interact or manage their state.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
classes. This is particularly useful in scenarios where the number of shapes
or rendering methods can grow over time.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
communication between different planes and the control tower. The control
tower acts as the mediator, relaying necessary information and ensuring that
planes don’t directly communicate with each other, reducing the chances of
collision or confusion.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the Interpret method is called, it returns the value of the number.
grammar.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
steps of a predefined process, the Template Method Pattern allows them to
override the necessary methods while ensuring the common workflow
remains intact.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Execute() method of the command, which in turn delegates the action to
the Document class (the receiver).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
actual state (the text) and provides methods to change the state, save the current
state to a Memento, and restore a previous state from a Memento.
editor.
public class TextEditor
private string _text;
public void Write(string text) => _text = text;
public TextMemento Save() => new TextMemento(_text);
public void Restore(TextMemento memento) => _text =
memento.Text;
public override string ToString() => _text;
Gang of Four Patterns Design Patterns in C# · GoF Patterns
structure in different ways, such as depth-first or breadth-first traversal.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the existing classes.
Follow:
functionality through new visitor classes.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
payment, inventory management, and shipping. A single checkout process
could internally handle all these complex operations.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
system to keep a history of states and revert back to any previous state.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
is complex (e.g., involving many interdependencies), it may be difficult to
capture it in a Memento without violating encapsulation or increasing
complexity.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
(such as player position, inventory, etc.) so that the player can undo or restore
their progress to a previous save point.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
functionality. The stack of executed commands allows for easy reversion of
actions without needing to track individual changes manually.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
observers. Each observer will receive updates from the subject when the state
changes.
public interface IObserver
void Update(string news);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
subclasses with different variations of steps, the code can become harder to
manage and maintain.
Conclusion:
The Template Method Pattern is a powerful way to define the structure of an algorithm
while allowing subclasses to customize specific steps. It's ideal when you want to reuse a
Follow:
common workflow while providing flexibility to modify particular steps. It is frequently used in
frameworks and libraries, where the overall process must remain consistent, but certain
aspects can be customized or extended. This pattern ensures that the general algorithm
remains the same while giving subclasses the freedom to tailor specific steps to their needs.
Visitor Pattern: Adding New Operations Without Modifying Object
Structures
Definition:
The Visitor Pattern separates an algorithm from the object structure on which it operates. It
allows you to add new operations to existing object structures without modifying the
structures themselves. Instead of embedding operations directly into the objects, you define
a visitor that knows how to operate on each type of object in the structure.
Use Case:
A typical use case for the Visitor Pattern is calculating taxes or discounts for different
product types in a shopping cart. Each product type (e.g., books, fruits, electronics) might
require different calculations, and the Visitor Pattern allows you to easily add new types of
operations (e.g., tax calculation, discount application) without altering the objects in the
shopping cart.
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
to the publisher and updates its state (in this case, by printing the news) when
the publisher notifies them.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
if-else or switch) to determine which algorithm to use. The strategy
pattern eliminates this by encapsulating the algorithm in separate classes.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the system based on user actions or conditions.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Visit method encapsulates the operation to be performed on the
corresponding element.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
CreateLogger method to create specific logger types, such as
FileLogger or ConsoleLogger. The subclass provides the implementation
details for object creation.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Sometimes, basic conditionals (e.g., if/else) might suffice, and the pattern
may add unnecessary complexity.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
execution. Multiple commands can be grouped together, and executing or
undoing the entire batch can be done in a single operation.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
dashboards) subscribe to receive updates on temperature, humidity, and
other weather conditions.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
new visitor classes without needing to modify the existing elements (Book,
Fruit). This makes it easier to extend functionality in the future.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the message. If the message level is Info, it processes the message. If not,
it passes the request to the next handler (errorLogger).
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
interface. It implements the Clone() method, which creates a new
GameCharacter object with the same properties as the original.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
achieved by selecting different algorithms.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
initialization when the object is not used. This ensures that resources are
used efficiently.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
The Interpreter Pattern can be used to build a query parser that interprets
the structure and conditions in the query, eventually transforming them into an
executable SQL statement.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
on the state of existing ones, without knowing the specific class of the object
you're cloning. This can be useful for creating different variations of an object
without manually specifying each one.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
object creation doesn't involve copying or if it requires significant setup, the
pattern might not be appropriate.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
multiple Character objects to save memory.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
any child components but implements the ShowInfo() method to display its
name.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
clone UI components (e.g., buttons, text fields) with predefined styles or
settings.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
processes. For example, factories might create loggers with specific
configurations, such as log levels (e.g., INFO, ERROR, DEBUG) or custom
output formats, allowing even more flexibility in how objects are created.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
object that we want to control access to. It contains the logic to load and display the
image.
public class RealImage : IImage
private readonly string _filename;
public RealImage(string filename) => _filename = filename;
public void Display() => Console.WriteLine($"Displaying
{_filename}");
This behavior can be resource-intensive, especially if the image is large.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
This is known as lazy loading. For example, the large image is only loaded
when the client requests it for the first time.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
code doesn’t need to change; just use the new factory.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
asynchronous, allowing components (like the DVD player) to load or process
content in the background, improving user experience.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
creation, deletion, or other operations are performed only when appropriate.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
of the steps defined in the abstract Recipe class. The steps like gathering
ingredients, preparing, and cooking are all tailored to pasta.
public class PastaRecipe : Recipe
protected override void GatherIngredients()
Console.WriteLine("Gathering pasta, sauce, and cheese.");
protected override void Prepare()
Console.WriteLine("Boiling pasta and preparing sauce.");
protected override void CookMethod()
Console.WriteLine("Cooking pasta with sauce.");
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
character is rendered) separately. It ensures that intrinsic state (the symbol)
is shared between all instances, preventing the creation of duplicate objects.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Review the concept and prepare a concise verbal explanation with a real project example.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
network), and it handles communication between the client and the remote
object.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
manner (i.e., chaining method calls), which can make the code cleaner and
more readable.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
remote server, managing the complexities of network protocols and making it
seem as if the remote object is local.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
or a Shortcut class) to the system without affecting the existing code. As
long as the new class implements the IFileSystemComponent interface, it
will fit seamlessly into the existing structure.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
class. This property ensures that no new instances are created, and the same
instance is returned every time.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the element to accept a visitor. Each element (like Book, Fruit) will implement this
interface to allow a visitor to operate on it.
public interface IShoppingCartElement
void Accept(IShoppingCartVisitor visitor);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
overhead of object creation and garbage collection. This is particularly
beneficial in performance-sensitive applications like games or graphical user
interfaces.
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
that in multi-threaded applications, only one instance is created even when
multiple threads try to access it concurrently.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
cache used by the entire application.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
when needed, with thread safety ensured by locking.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
and maintain since objects can rely on the Singleton without explicitly passing
it.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
where each flyweight can contain references to other flyweights. For example,
a complex character (e.g., with styling information) could consist of several
flyweight components (like the base character, font style, size, etc.).
Visual Diagram:
+---------------------------+
| CharacterFactory |
| (Flyweight Factory) |
+---------------------------+
+---------------------------------------------+
| |
+------------------+
+------------------+
| Character | | Character
| <--- Flyweight Objects
| (Intrinsic State)| | (Intrinsic
State)|
+------------------+
+------------------+
| |
| * Shared across all objects |
Follow:
+--------------------------------------------------->+
(Position, Size, Text displayed are external/unique)
(Memory saved by sharing the intrinsic state)
Conclusion:
The Flyweight Pattern provides a powerful way to manage large numbers of similar objects
efficiently by sharing common state and minimizing memory usage. It’s particularly beneficial
in scenarios like text rendering, game graphics, or large-scale simulations where creating
numerous identical objects would be costly in terms of memory and performance. By
applying this pattern, you can significantly reduce the memory footprint and improve the
performance of your application while maintaining flexibility in managing the objects' unique
properties.
Interpreter Pattern: Real-Time Example - Parsing and Evaluating
Mathematical Expressions
Definition:
The Interpreter Pattern defines a representation for a grammar along with an interpreter to
interpret sentences in that grammar. It is used to evaluate expressions or interpret complex
languages by breaking them down into simpler components that can be recursively
evaluated.
Use Case:
A typical use case for the Interpreter Pattern is parsing and evaluating mathematical
expressions, like addition, subtraction, multiplication, or division. It allows for flexible and
dynamic evaluation of complex expressions.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
This pattern provides a clean, reusable way to bridge the gap between incompatible
interfaces, making integration smoother and more manageable.
Bridge Pattern: Real-Time Example - Drawing Application with Multiple
Styles
Scenario:
Imagine you are building a drawing application that allows users to draw different shapes
(like circles) in various styles. The Bridge Pattern is a great solution when you want to
decouple the shape abstraction from the rendering logic, allowing both the shapes and the
drawing styles to vary independently.
The Bridge Pattern separates the abstraction (the shape) from its implementation (the
drawing API), allowing you to modify the shape or the rendering technique without affecting
the other. This makes your code more flexible and maintainable.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the state object. The context can change its state by calling the SetState
method, which updates the current state reference.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
specific level of message), it’s easier to modify or extend the system. For
example, adding a new log level (e.g., Debug) would only require creating a
new handler for that level without affecting existing code.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
switch statements) in the context class. Each state class defines its own
behavior, and the context class only delegates the work.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the Logger class. Each handler checks if it can handle a particular log level
Follow:
(e.g., Info or Error). If it can, it processes the log; otherwise, it passes it along
to the next handler in the chain.
public class InfoLogger : Logger
protected override bool CanHandle(LogLevel level) => level ==
LogLevel.Info;
protected override void Handle(string message) =>
Console.WriteLine($"Info: {message}");
public class ErrorLogger : Logger
protected override bool CanHandle(LogLevel level) => level ==
LogLevel.Error;
protected override void Handle(string message) =>
Console.WriteLine($"Error: {message}");
Gang of Four Patterns Design Patterns in C# · GoF Patterns
(leftExpression and rightExpression) and computes their sum.
sub-expressions.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
track down state-related bugs, especially in more complex systems.
Conclusion:
The State Pattern is an excellent choice when an object's behavior is contingent on its state,
and you need to manage the transitions between states in a clean, maintainable way. It's
ideal for situations like traffic lights, game characters, or process workflows, where the object
changes its behavior dynamically. By encapsulating the behavior of each state in separate
classes, you can avoid complex conditionals and promote better code organization and
flexibility.
Strategy Pattern: Encapsulating Algorithms for Interchangeability
Definition:
The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes
them interchangeable. This pattern allows an algorithm to vary independently from clients
Follow:
that use it. It is particularly useful when you want to choose between different algorithms
dynamically at runtime, without altering the code that uses them.
Use Case:
A typical use case for the Strategy Pattern is sorting. Instead of implementing multiple
sorting algorithms directly in the client code, you can use the strategy pattern to choose
which sorting algorithm to apply (e.g., QuickSort, BubbleSort, MergeSort) depending on the
context or runtime conditions.
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
directory, such as size, creation date, and file type. This could be added as
Follow:
properties in the File and Directory classes.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
buttons, labels, icons) can use the Flyweight Pattern to reuse common
elements while only storing the unique aspects (such as position, text, or
color).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the element classes, you still need to ensure that visitors and elements are
compatible. This can lead to some level of coupling between visitors and
element classes.
Conclusion:
The Visitor Pattern is an excellent choice when you need to separate the operations
performed on a structure from the structure itself, particularly in cases where the structure is
complex and may evolve over time. It allows you to introduce new operations without
modifying existing object classes. However, it can become difficult to manage when you
need to add new element types, as every visitor must be updated to handle the new type.
This pattern is often used in scenarios like processing different kinds of products in a
Follow:
shopping cart, applying various types of discounts or taxes, or performing different
transformations on elements of a composite structure.
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
SetStrategy that allows clients to set the desired sorting strategy dynamically. The
Sort method delegates the sorting task to the currently set strategy.
public class Sorter
private ISortStrategy _strategy;
public void SetStrategy(ISortStrategy strategy) => _strategy =
strategy;
public void Sort(List<int> list) => _strategy.Sort(list);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
delegates it to whatever strategy is currently set. The client can change the
strategy dynamically, making the system flexible and extensible.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
creating new non-terminal expression classes (e.g., Subtract, Multiply).
This makes the pattern highly extendable.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
departments (composites) contain teams or employees (individuals), and both
can be treated as "components" with a common interface for operations like
calculating total salary or generating reports.
Improvement Suggestions:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
algorithms, the Strategy Pattern can help simplify and modularize your code.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
domain-specific languages (DSLs) or simple programming languages. Each
statement or expression in the language can be represented as an object,
and the interpreter evaluates these statements to execute the program.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
this case). Different concrete implementations of this interface will represent
various drawing styles or technologies.
public interface IDrawingAPI
void DrawCircle(double x, double y, double radius);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
.LogMessage(...)).
This continues until a handler processes the message or the chain is
exhausted.
Key Benefits of the Chain of Responsibility Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
grammars. For example, adding new operations like subtraction or division
can be easily done by introducing new non-terminal expressions (e.g.,
Subtract, Divide).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
(MilkDecorator, SugarDecorator) extend this class. The decorator
wraps the SimpleCoffee object (or other decorated objects) and enhances
or alters its behavior, like adding extra cost or modifying the description.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
interface and keeps track of the current position in the
ProductCollection. It knows how to traverse the collection, check if
there’s a next item (HasNext()), and return the next item (Next()).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
look and feel, as each factory provides platform-specific products.
Improvement Suggestions:
dialogs) to your abstract factory. This would allow for more complex UI
systems that adapt to various platforms.
product creation methods (e.g., create UI components only when needed).
you need to dynamically select factories based on runtime conditions (e.g.,
based on user preferences or system environment).
Real-Time Use Case Example:
This pattern is extremely useful when building cross-platform desktop applications with a
consistent UI, like in Electron or Xamarin apps. It allows developers to write
Follow:
platform-agnostic code that automatically adapts to the underlying operating system's UI
conventions.
Adapter Pattern: Real-Time Example - Integrating Third-Party Libraries
Scenario:
You're working on a project where you need to integrate a third-party library with a
pre-existing system. However, the third-party library has a different interface than the one
your system expects. In such cases, the Adapter Pattern can be used to wrap the
third-party interface and make it compatible with your existing system.
The Adapter Pattern is a structural design pattern that allows incompatible interfaces to
work together. It "adapts" one interface to another by creating a wrapper class that translates
method calls between the two interfaces.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
in an object structure.
different types of objects, and each type requires specific behavior.
Drawbacks of the Visitor Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
don’t need to touch existing code. The new functionality is added without
altering or subclassing the core class.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
from the client. The client interacts only with the iterator, which means that
changes to the underlying collection (e.g., changing it from a list to a linked
list) do not affect the client code.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
options to text (bold, italic, underline) dynamically, without needing separate
classes for each combination of formatting.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
collection (like a list of rows). The Iterator Pattern is used to iterate over
these rows to access the data, rather than exposing the internal structure of
how the data is retrieved from the database.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
IShoppingCartElement interface. Each class has a price and the Accept
method that allows the visitor to perform an operation on it.
public class Book : IShoppingCartElement
public double Price { get; }
public Book(double price) => Price = price;
public void Accept(IShoppingCartVisitor visitor) =>
visitor.Visit(this);
public class Fruit : IShoppingCartElement
public double Price { get; }
public Fruit(double price) => Price = price;
public void Accept(IShoppingCartVisitor visitor) =>
visitor.Visit(this);
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
efficiently (e.g., lazy loading or batching) can improve performance.
Visual Diagram:
Follow:
+---------------------------+
| IIterator<T> |
| (Iterator Interface) |
+---------------------------+
+---------------------------+
| |
+-----------------+ +------------------+
| ProductIterator| | ProductCollection|
| (Concrete Iterator) | (Concrete Aggregate)|
+-----------------+ +------------------+
| |
+--------------+ +--------------+
| HasNext() | | Add() |
| Next() | | Count |
| | | CreateIterator() |
+--------------+ +--------------+
Conclusion:
The Iterator Pattern is a powerful design pattern for accessing elements of a collection
sequentially, encapsulating the iteration logic in a separate object. This allows for greater
flexibility and maintainability by decoupling the collection's internal representation from the
client code.
Mediator Pattern: Real-Time Example - Chat Application
Definition:
The Mediator Pattern defines an object that encapsulates how a set of objects interact. It
promotes loose coupling by preventing objects from referring to each other explicitly,
allowing them to communicate indirectly through the mediator. This pattern is useful when
you need to manage complex interactions between multiple objects, without them needing to
know about each other.
Use Case:
Follow:
A chat application is a perfect example of where the Mediator Pattern can be applied. In a
chat app, users (colleagues) need to communicate, but rather than each user being directly
aware of the others, a mediator handles all the communication between users.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
IChatMediator. It manages a list of users and is responsible for
broadcasting messages to all registered users, except the one who sent the
message.
to know about each other's existence.
public class ChatMediator : IChatMediator
private readonly List<User> _users = new List<User>();
public void RegisterUser(User user) => _users.Add(user);
Follow:
public void SendMessage(string message, User user)
foreach (var u in _users)
// Message should not be sent to the user who sent it
if (u != user)
u.Receive(message);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
interface. It encapsulates the request to add text to the document.
Undo() method removes that text.
public class AddTextCommand : ICommand
private readonly Document _document;
private readonly string _text;
public AddTextCommand(Document document, string text)
_document = document;
_text = text;
public void Execute() => _document.AddText(_text);
public void Undo() => _document.RemoveText(_text);
Gang of Four Patterns Design Patterns in C# · GoF Patterns
object. For instance, you could add a feature to customize the size of the
coffee (Small, Medium, Large) which would change both the cost and
description.
Visual Diagram:
+-------------------------+
| ICoffee | <-- Component Interface
+-------------------------+
/ \
+-------------------------+
| SimpleCoffee | <-- Concrete Component (Core Coffee)
+-------------------------+
+---------------------+ +----------------------+
| CoffeeDecorator |<--- | MilkDecorator |
+---------------------+ +----------------------+
| |
Follow:
+---------------------+ +----------------------+
| SugarDecorator | <-- | WhippedCreamDecorator |
+---------------------+ +----------------------+
SimpleCoffee.
Conclusion:
The Decorator Pattern provides a powerful and flexible way to extend the functionality of
objects at runtime. In real-time applications like customizing a coffee order, decorating UI
elements, or adding functionality to text, this pattern helps in achieving clean, modular, and
extensible code. You can add or remove features dynamically, ensuring that your base
classes remain unaltered and your system remains flexible for future extensions.
Facade Pattern: Real-Time Example - Simplifying a Home Theater
System
Definition:
The Facade Pattern provides a simplified interface to a complex subsystem, making it
easier for clients to interact with multiple components. It hides the complexity of the
subsystem and exposes only what is necessary, offering a higher-level interface to users.
Use Case:
A common example is a home theater system, where the user needs to interact with
multiple components like an amplifier, DVD player, or projector. The Facade Pattern
simplifies the process by providing a unified interface to these various components, making
the system easier to use.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
unified interface for the user. It wraps the complex subsystem and provides
higher-level methods that internally call the appropriate subsystem methods.
public class HomeTheaterFacade
private readonly Amplifier _amplifier;
private readonly DVDPlayer _dvdPlayer;
public HomeTheaterFacade(Amplifier amplifier, DVDPlayer
dvdPlayer)
_amplifier = amplifier;
_dvdPlayer = dvdPlayer;
public void WatchMovie(string movie)
Follow:
_amplifier.On();
_dvdPlayer.Play(movie);
public void EndMovie()
_amplifier.Off();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
The mediator centralizes communication, and the users only rely on the
mediator to send and receive messages.
Benefits of the Mediator Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
one the client expects. In this case, it has a method SpecificRequest()
that performs some action, but it does not conform to the ITarget interface.
public class Adaptee
Follow:
public void SpecificRequest() => Console.WriteLine("Specific
request from Adaptee.");
Gang of Four Patterns Design Patterns in C# · GoF Patterns
case), the mediator simplifies the process, as objects only need to
Follow:
communicate with the mediator.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the HomeTheaterFacade), which internally delegates tasks to the complex
subsystem classes. This makes the system much easier to use while hiding
unnecessary complexity.
Key Benefits of the Facade Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
of the IUIFactory interface. Each factory creates platform-specific objects
like buttons and checkboxes.
public class WindowsUIFactory : IUIFactory
public IButton CreateButton() => new WindowsButton();
public ICheckbox CreateCheckbox() => new WindowsCheckbox();
public class MacUIFactory : IUIFactory
public IButton CreateButton() => new MacButton();
public ICheckbox CreateCheckbox() => new MacCheckbox();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
to manage interactions between various components like buttons, text fields,
and labels. For example, clicking a button might update a text field, and the
mediator ensures that these updates are propagated correctly.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
you can modify or extend the sorting algorithms without affecting the code
that uses them.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
changes, the facade can be updated without affecting the client code.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
also create a dependency on the mediator itself. Over-reliance on the
mediator can lead to issues if the mediator needs to change.
Visual Diagram:
+----------------------+
| IChatMediator |
| (Mediator Interface) |
+----------------------+
+------------------------------------+
| |
+------------------+ +------------------+
| ChatMediator | | User |
| (Concrete Mediator) | (Colleague) |
+------------------+ +------------------+
| |
+-------------------+ +------------------+
| RegisterUser(User)| | Send(string) |
| SendMessage(...) | | Receive(string) |
+-------------------+ +------------------+
Follow:
Conclusion:
The Mediator Pattern is an excellent solution for managing complex interactions between
objects in a system, particularly when those objects don’t need to know about each other
directly. It reduces dependencies, simplifies communication, and centralizes control, making
it easier to manage interactions. However, it should be used judiciously, as a poorly
implemented mediator can become a bottleneck or a single point of failure in the system.
Memento Pattern: Real-Time Example - Undo Feature in a Text Editor
Definition:
The Memento Pattern is used to capture and externalize an object's internal state without
violating encapsulation. This allows the object to be restored to this state later. It’s commonly
used in situations where an object's state changes over time and you may need to revert to
previous states, such as an undo feature.
Use Case:
The Memento Pattern is widely used in scenarios where you want to implement an undo or
restore functionality, such as in a text editor. In this case, the pattern allows the editor to
save versions of the text and restore them when the user requests an undo.
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
(e.g., upgrading the drawing API) do not affect the shape logic, and vice
versa. This results in less risk of introducing bugs when making changes.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
can undo changes by restoring the TextEditor to its previous state stored
in the mementos stack.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Undo() method is called, it pops the most recent command from the stack
and calls its Undo() method, which reverts the action performed by the
command (removes the last added text).
Key Benefits of the Command Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
operations like credit checks, account updates, and transaction processing
are abstracted into a simplified process, allowing users to perform
transactions without understanding the underlying complexities.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
sophisticated memento management (e.g., limiting the number of mementos
kept in memory or implementing a more efficient undo/redo system).
Follow:
Real-Time Use Case Examples:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the Cook method) while customizing certain steps in different subclasses.
This makes it easy to add new recipes by simply extending the Recipe class
and overriding the abstract steps.
Benefits of the Template Method Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
state of form inputs at various stages. This allows users to undo their changes
or restore the form to a previous valid state.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
component fails (e.g., DVD player is missing), the facade could display a
user-friendly message or take an appropriate action.
Visual Diagram:
+-------------------------------------+
| HomeTheaterFacade | <-- Facade
(Simplified Interface)
+-------------------------------------+
/ \
/ \
+---------------+ +---------------+
| Amplifier | | DVD Player | <-- Subsystem
Classes
+---------------+ +---------------+
| |
(turn on, play movie) (play movie, etc.)
EndMovie()) to the user.
desired result.
Conclusion:
Follow:
The Facade Pattern is highly effective for simplifying complex systems by providing a
unified interface. In the case of a home theater system, it reduces the complexity of
managing multiple components and makes the system more user-friendly. Whether it’s home
entertainment, e-commerce systems, or banking software, the Facade Pattern is a valuable
design pattern for hiding complexity and improving usability.
Factory Method Pattern: Real-Time Example - Logging Framework
Definition:
The Factory Method Pattern defines an interface for creating objects, but allows
subclasses to alter the type of objects that will be created. This provides flexibility in creating
different types of objects while adhering to the same interface.
Use Case:
A common use case for the Factory Method Pattern is in logging frameworks. Such
frameworks can log messages to various destinations, like files, databases, or consoles. The
Factory Method allows the system to choose the appropriate logging mechanism
dynamically, based on configuration or user preferences, without tightly coupling the client
code to specific classes.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
maintains a list of observers and provides methods to subscribe, unsubscribe, and
notify them when a new news article is available.
public class NewsPublisher : INewsPublisher
private readonly List<IObserver> _observers = new
List<IObserver>();
public void Subscribe(IObserver observer) =>
_observers.Add(observer);
public void Unsubscribe(IObserver observer) =>
_observers.Remove(observer);
public void Notify(string news)
foreach (var observer in _observers)
observer.Update(news);
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
CloudLogger) by simply creating new factory subclasses without modifying
Follow:
existing client code.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
are logged (either to a file or the console).
FileLogger:
public class FileLogger : ILogger
public void Log(string message) => Console.WriteLine($"Logging
to file: {message}");
ConsoleLogger:
public class ConsoleLogger : ILogger
public void Log(string message) => Console.WriteLine($"Logging
to console: {message}");
Gang of Four Patterns Design Patterns in C# · GoF Patterns
includes methods for setting the dough, sauce, and adding toppings, as well
as a Build() method to return the fully constructed pizza.
public interface IPizzaBuilder
void SetDough(string dough);
void SetSauce(string sauce);
void AddTopping(string topping);
Pizza Build();
Gang of Four Patterns Design Patterns in C# · GoF Patterns
observer’s Update() method is called, and the news is sent to all registered
subscribers.
Benefits of the Observer Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
they all stay in sync with the subject’s state.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
performance overhead. You should evaluate the cost-benefit ratio of cloning
versus object creation.
Real-Time Use Case Examples:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
depend on each other in a way that could create an infinite loop or
inconsistent states.
Follow:
Real-Time Use Case Examples:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
and ConsoleLogger. These classes define how the log message will be
handled, either by writing to a file or outputting to the console.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
they follow (subject) posts new updates or content.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
logic for each element. In this case, the ShoppingCart visitor calculates the
total price, applying discounts where necessary.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
example, if the user performs a series of actions (like adding text, changing
fonts, and changing colors), you can encapsulate all of those actions into a
single composite command that can be undone in one step.
Real-Time Use Case Example:
The Command Pattern is often used in:
the entire system can be undone or redone.
allowing for consistent handling of actions across the UI.
encapsulated as commands and undone when necessary.
Follow:
Visual Diagram:
Here's a simple visual diagram to understand the Command Pattern:
+-----------------+ +---------------------+
+------------------+
| TextEditor | ---> | AddTextCommand | ---> |
Document |
| (Invoker) | | (Concrete Command) | |
(Receiver) |
+-----------------+ +---------------------+
+------------------+
| |
+-----------+
+-------------------+
| Undo | |
AddText / RemoveText |
+-----------+
+-------------------+
The Command Pattern provides a flexible and scalable way to handle requests in
object-oriented systems, especially when you need to manage complex workflows,
implement undo/redo functionality, or decouple senders from receivers.
Composite Pattern: Real-Time Example - Building a File System
Scenario:
The Composite Pattern is used when you need to treat individual objects and compositions
of objects uniformly. This is particularly useful when you have a hierarchical structure, like a
file system, where files and directories can be treated in a similar manner.
In a file system:
Follow:
(children).
This pattern helps to simplify the management of hierarchical structures, making it easier to
handle both individual items and collections of items in a unified way.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
it returns a new instance of the same type (e.g., GameCharacter) with the
same state (e.g., same Name and Health).
Benefits of the Prototype Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Prototype Pattern allows you to avoid duplicating these steps by cloning an
existing object and modifying only the necessary parts.
Considerations:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
formats, such as PDF, Word, or HTML. A Factory Method can be used to
create the appropriate document generator based on user input, allowing for
flexible document creation without hardcoding the specific document format
classes.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
character having different behaviors when idle, walking, running, or jumping.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
contain multiple IFileSystemComponent objects (both files and
subdirectories). The ShowInfo() method displays the directory’s name and
Follow:
recursively calls ShowInfo() on its children (whether they are files or
subdirectories).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
cloned, and then the cloned document can be customized with specific
content for each user.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
use dependency injection to pass the correct factory implementation into
the client code. This would make the code even more flexible and testable.
Visual Diagram:
+---------------------+
| LoggerFactory | <--- Abstract Factory
(Factory Method)
+---------------------+
+--------------------------+
| |
+-------------------+ +-------------------+
| FileLoggerFactory | | ConsoleLoggerFactory | <--- Concrete
Factories
+-------------------+ +-----------------------+
| |
+---------------+ +----------------+
| FileLogger | | ConsoleLogger | <--- Concrete
Products
Follow:
+---------------+ +----------------+
\ /
\ Client Code /
\_____________________/
Factory Interaction
factory (LoggerFactory), which then returns the appropriate logger (FileLogger
or ConsoleLogger).
Conclusion:
The Factory Method Pattern offers a flexible and extensible solution for object creation,
especially in scenarios where the type of object to be created is determined at runtime. It
decouples the client code from specific classes, making it easier to extend and maintain.
Whether it's for logging systems, database connections, or UI components, this pattern
allows developers to create objects in a controlled and predictable manner, improving
scalability and maintainability.
Flyweight Pattern: Real-Time Example - Managing Graphic Objects in a
Game
Definition:
The Flyweight Pattern is designed to reduce the cost of creating and manipulating a large
number of similar objects. By sharing common parts of an object between multiple instances,
it saves memory and improves performance.
Use Case:
A typical use case for the Flyweight Pattern is in applications like games or text editors
that need to handle a large number of similar objects. For example, in a game with many
characters displayed on the screen, each character might be similar but would take up
unnecessary memory if each instance stored its own version of a character object. The
Flyweight pattern can be used to share the common properties (like the character symbol)
and only store unique ones (like the position).
Code Explanation:
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
to the RealImage. It is responsible for lazy loading the real image only when needed
(i.e., the first time Display() is called).
Follow:
public class ProxyImage : IImage
private readonly string _filename;
private RealImage _realImage;
public ProxyImage(string filename) => _filename = filename;
public void Display()
if (_realImage == null)
_realImage = new RealImage(_filename);
_realImage.Display();
Display() method is called for the first time. This delays the loading of the
image, making it more efficient if the Display() method is not called
frequently.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
object. In our example, after the image is loaded by the proxy, it delegates the
Display() method to the RealImage class.
Benefits of the Proxy Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
complex operations. If multiple operations are performed on the same
structure, they can be handled by different visitors.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
improve the performance of applications, especially in cases of large datasets
or expensive operations (like network calls or file loading).
Gang of Four Patterns Design Patterns in C# · GoF Patterns
allow for customization in certain steps. For example, when implementing
generic frameworks for various kinds of workflows, like validation, report
generation, or business processes.
Drawbacks of the Template Method Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
is allowed. It can act as a gatekeeper for resources.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
abstract class. Additionally, the order and structure of steps remain consistent
across different subclasses.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
World", the CharacterFactory checks if the character already exists. If it
does, the existing object is reused; otherwise, a new Character object is
created.
common objects.
Key Benefits of the Flyweight Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
example, when displaying the contents of a directory, you don’t need to worry
about whether the child is a file or a subdirectory.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
only once, even when multiple threads access the Instance property
concurrently. This is important in multi-threaded applications where race
conditions could otherwise cause multiple instances to be created.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
whether a component is a file or a directory. It can just call ShowInfo() on
any component and let the pattern take care of the rest.
Follow:
Real-Time Use Case Example:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
of the application to access the same object without the need for passing
references.
When to Use the Singleton Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
animals in an ecosystem), the Flyweight Pattern can be used to share
common behaviors or attributes across many instances, reducing memory
overhead.
Improvement Suggestions:
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
overhead of locking once the instance has been created.
Follow:
public class Singleton
private static Singleton _instance;
private static readonly object _lock = new object();
private Singleton() { }
public static Singleton Instance
get
if (_instance == null)
lock (_lock)
if (_instance == null)
_instance = new Singleton();
return _instance;
Gang of Four Patterns Design Patterns in C# · GoF Patterns
static nature.
Conclusion:
The Singleton Pattern is a powerful tool for ensuring that a class has only one instance and
provides a global access point to that instance. It's useful for managing shared resources
like configuration settings, logging, or caching. However, care should be taken when using it,
especially in multi-threaded applications, and consideration should be given to the
challenges in testing and extending the class.
State Pattern: Allowing Object Behavior to Change Based on Its State
Definition:
The State Pattern allows an object to change its behavior when its internal state changes.
The object will appear to change its class. It's used when an object's behavior is dependent
on its state and the object needs to behave differently in different states without using
complex conditionals.
Use Case:
The State Pattern is useful in scenarios where an object's behavior is conditional on its
state. A typical use case is a traffic light system where the behavior (light change) varies
based on the current state (Red, Green, Yellow).
Follow:
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
action and then set the next state, allowing the traffic light to cycle through its
states (Red → Green → Yellow → Red).
Benefits of the State Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
directly returns the number it holds.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
making it easier to add or modify states without affecting the rest of the
system. You can add new states without altering the existing code too much.
When to Use the State Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
could be added to the IFileSystemComponent interface and implemented
by both files and directories.
Visual Diagram:
Here's a simple visual diagram to understand the Composite Pattern:
+----------------------+
| IFileSystemComponent |
+----------------------+
/ \
/ \
+-----------+ +-----------+
| File | | Directory |
+-----------+ +-----------+
/ \
/ \
+-----------+ +-----------+
| File | | Directory |
+-----------+ +-----------+
Conclusion:
The Composite Pattern is an effective design pattern for dealing with tree-like structures,
where individual objects and composites need to be treated uniformly. In real-time
applications like file systems, graphic design tools, and organizational hierarchies, this
pattern simplifies the client code and allows for flexible and scalable solutions. By using this
Follow:
pattern, you can easily manage complex structures and extend them with new types of
components as your system grows.
Decorator Pattern: Real-Time Example - Enhancing a Coffee Order
Scenario:
The Decorator Pattern is used to add new behaviors or responsibilities to objects
dynamically without affecting the behavior of other objects in the system. It’s perfect when
you want to extend or change the functionality of an object at runtime without altering its
original code.
Use Case:
A common example is a coffee order where you can add extra features such as milk, sugar,
or even whipped cream to a basic coffee without modifying the original Coffee class.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
change the strategy at runtime. This makes the system adaptable to different
sorting needs without changing the core structure.
Benefits of the Strategy Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
class, adhering to the Single Responsibility Principle. This separation
ensures that each class has a well-defined role in the expression evaluation
process.
Real-Time Use Case Examples:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
encapsulated in their own classes, you don't need to test them within the
context class.
Follow:
When to Use the Strategy Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
different ways, the Strategy Pattern can centralize and avoid code
duplication.
Drawbacks of the Strategy Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
fees), you can introduce new operations on the same set of elements without
modifying their classes. This is the key benefit of the Visitor Pattern.
Follow:
Benefits of the Visitor Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
interface. It performs specific operations on each element, like calculating the total
cost with any applicable discounts. For instance, it applies a 10% discount to books
but no discount to fruits.
public class ShoppingCart : IShoppingCartVisitor
private double _total;
public void Visit(Book book) => _total += book.Price * 0.9; //
10% discount on books
public void Visit(Fruit fruit) => _total += fruit.Price; // No
discount on fruits
public double GetTotal() => _total;
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
the Interpreter Pattern. Each element or configuration setting can be treated
as an expression, and the pattern allows for flexible and extensible parsing
rules.
Improvement Suggestions:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
always followed in the same sequence, regardless of the specific recipe. This
prevents inconsistent workflows in different implementations.
When to Use the Template Method Pattern:
Follow:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
tree (AST) (e.g., optimization or transformation), combining the Interpreter
Pattern with the Visitor Pattern can allow you to apply operations across
different types of expressions in a structured way.
Visual Diagram:
+-----------------------------+
| IExpression |
| (Abstract Expression) |
+-----------------------------+
Follow:
+------------------------------------+
| |
+-------------------+
+------------------+
| Number | | Add
| (Terminal Exp.) | | (Non-Terminal
Exp.) |
+-------------------+
+------------------+
| |
| |
(Interprets to a value) (Interprets to
sum of left + right)
Conclusion:
The Interpreter Pattern provides a robust and flexible way to interpret and evaluate
expressions, particularly when the grammar is dynamic or complex. By breaking down the
grammar into terminal and non-terminal expressions, it allows for recursive evaluation, which
is ideal for use cases such as mathematical expression parsing, query processing, or
language parsing. The pattern is extendable, allowing for easy addition of new operations,
and can be optimized for more complex scenarios with careful management of resources.
Iterator Pattern: Real-Time Example - Iterating Over a Collection of
Products
Definition:
The Iterator Pattern provides a way to access the elements of an aggregate object (like a
collection) sequentially without exposing its underlying representation. It allows for traversal
of the collection without needing to know the details of how the data is stored internally.
Use Case:
A typical use case for the Iterator Pattern is iterating over a collection of items, such as a
list of products or any other data structure like arrays, lists, or trees. It allows a client to
traverse through the collection's elements without needing direct access to the internal
structure.
Follow:
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
can be added dynamically, without changing the original SimpleCoffee
class. You can stack decorators as needed, allowing for flexible and
extensible object behavior at runtime.
Key Benefits of the Decorator Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
IAggregate<Product>, which provides an iterator to traverse through the
collection.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
This means that different parts of the program can independently iterate over
the collection without interfering with each other.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
can scale well as the number of log levels (or other request types) grows.
Improvement Suggestions:
Follow:
each handled by its own specific logger. You would just need to create new
concrete handlers for these levels.
files, databases, or remote servers. This way, the Chain of Responsibility
could support more complex logging systems with different outputs for each
level.
default handler (such as a DefaultLogger) that logs an unknown
message or performs some fallback action.
Real-Time Use Case Example:
The Chain of Responsibility Pattern is often used in real-time systems like:
Error, Warning).
and either processes or passes them on.
stages, and each stage processes the request in a specific way (e.g., authentication,
authorization, logging, validation).
Visual Diagram:
Here’s a simple visual diagram to understand the Chain of Responsibility Pattern:
+------------------+
| InfoLogger | <-- Handles LogLevel.Info
+------------------+
Follow:
+------------------+
| ErrorLogger | <-- Handles LogLevel.Error
+------------------+
(End of Chain)
The Chain of Responsibility Pattern is a powerful way to handle requests that need to be
processed by multiple handlers, each responsible for a specific part of the process. It is
especially useful when you have a sequence of operations (like logging, event handling, or
request processing) that may vary based on context.
Command Pattern: Real-Time Example - Undo Functionality in a Text
Editor
Scenario:
In a text editor, you often need the ability to undo actions (like adding or removing text) to
revert the document to its previous state. The Command Pattern is an excellent choice for
implementing undo functionality. This pattern encapsulates requests as objects, allowing for
parameterization of clients with queues, requests, and operations. It decouples the sender of
the request from the object that processes the request, making it easier to manage actions
and undo operations.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
streaming services. For example, you could decorate a base video stream to
Follow:
include ads, subtitles, or additional features like HD quality.
Improvement Suggestions:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
can be stored in collections. The Iterator Pattern can be used to iterate over
these objects, processing each object individually without exposing the
underlying collection implementation.
Improvements and Considerations:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
behavior of the communication or add new features. The changes are
contained within the mediator, and users don’t need to be modified.
Real-Time Use Case Examples:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
behaviors and the system needs to transition between steps (e.g., approval
Follow:
process, document processing).
Drawbacks of the State Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Follow:
subsystem. The facade hides this information, reducing dependencies and
improving modularity.
Real-Time Use Case Examples:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
changed. When an undo is triggered, the caretaker pops the most recent
Memento from the stack and asks the TextEditor to restore itself to the
state saved in that memento.
Benefits of the Memento Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Instead, you can simply reuse the same drawing API for multiple shapes.
Follow:
Improvement Suggestions:
Rectangle or Triangle, and have them use the same drawing API to
render their specific shapes.
IDrawingAPI for different rendering libraries, allowing the user to select their
preferred drawing style or technology.
rendering complex or large scenes), you could implement caching strategies
in your drawing APIs or leverage lazy initialization.
Real-Time Use Case Example:
The Bridge Pattern is particularly useful when building graphics software, drawing
applications, or game engines where you may need to render shapes in various styles. For
instance:
DirectX, or HTML Canvas).
need to be drawn using different rendering techniques.
Visual Diagram:
Here’s a simple visual diagram to understand the Bridge Pattern:
Abstraction (Shape) --> IDrawingAPI (Implementation)
| |
v v
Follow:
Refined Abstraction (Circle) --> Concrete Implementations
(DrawingAPI1, DrawingAPI2)
Builder Pattern: Real-Time Example - Building a Custom Pizza
Scenario:
Imagine you're building a pizza ordering system that allows customers to customize their
pizzas with different dough types, sauces, and toppings. The Builder Pattern is a perfect fit
for such use cases where you need to create complex objects step by step, each with
various configurations or options.
The Builder Pattern separates the construction of an object from its representation. This
means the same construction process can create different variations of an object. In this
case, the pattern allows for building different types of pizzas (e.g., Margherita, Pepperoni,
Veggie) with various ingredients.
Code Explanation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
transferring funds, managing accounts, and checking balances, so that users
don’t need to manually handle every step of the transaction.
Improvement Suggestions:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
useful in applications like text editors, form submissions, or game states
where you need to track changes and revert when needed.
Considerations:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
different states of a spreadsheet, enabling the user to undo changes like
deleting a cell or modifying a formula.
Visual Diagram:
+----------------+ +--------------------+
| TextEditor | Save() | TextMemento |
| (Originator) |------------>| (Memento) |
+----------------+ +--------------------+
| ^
Write Text Restore
| |
v |
+----------------+ +--------------------+
| Caretaker |<------------| TextMemento |
| (History) | Undo() | (Memento) |
Follow:
+----------------+ +--------------------+
Conclusion:
The Memento Pattern is a powerful design pattern for handling state restoration in software
systems, especially when implementing undo functionality. It helps maintain encapsulation
while allowing objects to restore their previous states. Although it has potential drawbacks in
terms of memory usage and complexity, the Memento Pattern remains invaluable for
applications that require maintaining and reverting state, such as text editors, games, and
form-based applications.
Observer Pattern: Real-Time Example - News Feed System
Definition:
The Observer Pattern defines a one-to-many dependency between objects, where when
one object (the "subject") changes state, all its dependent objects (the "observers") are
notified and updated automatically. This pattern is often used in scenarios where an object’s
state changes frequently and multiple objects need to react to those changes, like a user
interface or event-driven systems.
Use Case:
A common use case of the Observer Pattern is a news feed where users (observers) need
to be notified whenever a new article (news) is published (state change). For example, in a
news publishing system, the publisher notifies all subscribers when a new news article is
published.
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
and implements the Update() method to receive news updates from the publisher.
public class NewsSubscriber : IObserver
private readonly string _name;
public NewsSubscriber(string name) => _name = name;
public void Update(string news) => Console.WriteLine($"{_name}
received news: {news}");
Gang of Four Patterns Design Patterns in C# · GoF Patterns
making it suitable for scenarios where requests need to be delayed or
processed sequentially, such as in transaction management or job
Follow:
scheduling.
Improvement Suggestions:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
significantly affecting performance, as the publisher simply iterates through
the list of observers.
Considerations:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
stock prices (subjects) to receive real-time updates whenever the stock price
changes.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
with the factory (e.g., ConsoleLoggerFactory), which produces the
desired logger. This decouples the client code from the concrete logging
classes, promoting flexibility and scalability.
Key Benefits of the Factory Method Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
maintain and extend, since new behaviors are added in visitor classes rather
than modifying the core objects.
When to Use the Visitor Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the database is created and reused throughout the application.
Types of Singleton Implementation:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
components (e.g., buttons, text fields) that can differ based on the platform
(e.g., Windows vs. macOS). A factory method ensures the correct UI
components are created for the targeted platform.
Follow:
Improvement Suggestions:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
animals) can be cloned from a prototype, allowing for rapid creation of
multiple instances with different states.
Deep Cloning Example:
If you need to perform deep cloning, where not just the properties but also the referenced
objects are cloned, you can adjust the Clone() method to handle the deep copy:
public class GameCharacter : ICloneable
public string Name { get; set; }
public int Health { get; set; }
public List<string> Inventory { get; set; } = new
List<string>();
public ICloneable Clone()
var clone = new GameCharacter
Name = this.Name,
Health = this.Health,
Follow:
Inventory = new List<string>(this.Inventory) // Deep
copy of the Inventory list
return clone;
In this case, the Inventory list will also be cloned to ensure that modifications to the
Inventory of the clone do not affect the original object.
Conclusion:
The Prototype Pattern is a powerful creational pattern that allows you to clone objects
instead of creating them from scratch. It's especially useful when dealing with complex
objects or systems where performance and resource management are important. By using
this pattern, you can quickly create new objects with similar attributes and save time and
resources that would otherwise be spent constructing them from scratch.
Proxy Pattern: Controlling Access to Expensive Resources
Definition:
The Proxy Pattern provides a surrogate or placeholder for another object to control access
to it. The proxy acts as an intermediary, enabling you to perform additional actions (e.g., lazy
loading, access control, logging) before or after delegating operations to the real object.
Use Case:
The Proxy Pattern is useful when you need to control access to an expensive or
resource-intensive object. A common use case is controlling access to resources like large
images, network connections, or database connections. Instead of creating the actual object
immediately, a proxy can delay its creation or manage its lifecycle efficiently.
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
components. This is where the recursive nature of the Composite Pattern
comes into play. It doesn’t matter whether the child is a File or another
Directory; both types implement the ShowInfo() method, and the
directory simply iterates over its children.
Key Benefits of the Composite Pattern:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
access to the real object. For example, it could authenticate users before
allowing access to a sensitive resource.
Types of Proxy:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
that the flyweight (e.g., the Character object) is only created once per
unique symbol, and all subsequent requests for the same symbol reuse the
existing instance.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
subsequent requests, improving performance by avoiding redundant
operations.
Follow:
Real-Time Use Case Examples:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
when to send requests and how to handle responses. It can also perform
additional checks like authentication or caching.
Conclusion:
The Proxy Pattern is an excellent design pattern to control access to expensive or sensitive
objects. Whether it's controlling resource initialization (virtual proxy), managing remote
communication (remote proxy), or handling access control (protective proxy), proxies enable
efficient resource management and enhance security in an application.
Singleton Pattern: Ensuring a Single Instance
Definition:
Follow:
The Singleton Pattern ensures that a class has only one instance throughout the lifetime of
an application and provides a global point of access to that instance. It's often used for
managing shared resources, like configuration settings, logging, or database connections.
Use Case:
The Singleton Pattern is useful when you need to control access to a shared resource or
configuration. For example, when managing global configuration settings or database
connections, it ensures that the configuration or connection is accessed by all parts of the
application via a single, consistent instance.
Code Breakdown:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Review the concept and prepare a concise verbal explanation with a real project example.
Gang of Four Patterns Design Patterns in C# · GoF Patterns
Error).
public enum LogLevel
Info,
Error
Gang of Four Patterns Design Patterns in C# · GoF Patterns
the visitor (ShoppingCart) to calculate the total cost, which includes applying the
discount to books.
class Program
static void Main()
var items = new List<IShoppingCartElement>
new Book(20),
new Fruit(5)
var cart = new ShoppingCart();
foreach (var item in items)
Follow:
item.Accept(cart); // Visitor applies operation
(discount/tax)
Console.WriteLine($"Total: {cart.GetTotal()}"); // Total:
24.5 (Book with discount + fruit without discount)
Output:
Total: 24.5
How the Visitor Pattern Works:
Gang of Four Patterns Design Patterns in C# · GoF Patterns
ICoffee interface and holds a reference to an ICoffee object. This class
allows us to add additional behavior to the coffee object, but we don't modify
the base class (SimpleCoffee).
public abstract class CoffeeDecorator : ICoffee
protected ICoffee _coffee;
protected CoffeeDecorator(ICoffee coffee) => _coffee = coffee;
public virtual double Cost() => _coffee.Cost();
public virtual string Description() => _coffee.Description();