This course introduces key software design principles and GoF design patterns for .NET developers. The goal is to help developers write clean, maintainable, and extensible code while avoiding common pitfalls in real-world projects.
The course is structured around four main sections:
- SOLID Principles
- Clean Code, KISS & YAGNI
- Gang of Four (GoF) Design Patterns
- Behavioral Patterns (GoF)
Each section contains initial (bad) vs final (good) examples in C#/.NET 8, plus explanations and exercises.
| Principle | Folder / File | Description |
|---|---|---|
| Single Responsibility Principle (SRP) | SOLID/1.SRP/ |
Each class should have only one reason to change. |
| Open/Closed Principle (OCP) | SOLID/2.OCP/ |
Software entities should be open for extension, but closed for modification. |
| Liskov Substitution Principle (LSP) | SOLID/3.LSP/ |
Derived classes should be substitutable for their base classes. |
| Interface Segregation Principle (ISP) | SOLID/4.ISP/ |
Clients should not be forced to depend on interfaces they do not use. |
| Dependency Inversion Principle (DIP) | SOLID/5.DIP/ |
High-level modules should not depend on low-level modules; both should depend on abstractions. |
| Topic | Folder / File | Description |
|---|---|---|
| Clean Code | CleanCode/1.CleanCode |
Write readable, maintainable code following Uncle Bobβs principles. |
| KISS (Keep It Simple, Stupid) | CleanCode/2.KISS/ |
Avoid unnecessary complexity in your code. |
| YAGNI (You Aren't Gonna Need It) | CleanCode/3.YAGNI/ |
Implement only what is necessary for the current requirements. |
| Pattern | Folder / File | Description |
|---|---|---|
| Abstract Factory | GoF/1.Creational/1.AbstractFactory/ |
Provides an interface for creating families of related objects. |
| Builder | GoF/1.Creational/2.Builder/ |
Separates the construction of a complex object from its representation. |
| Factory Method | GoF/1.Creational/3.FactoryMethod/ |
Defines an interface for creating objects but lets subclasses decide which class to instantiate. |
| Prototype | GoF/1.Creational/4.Prototype/ |
Specify the kinds of objects to create using a prototypical instance. |
| Singleton | GoF/1.Creational/5.Singleton/ |
Ensure a class has only one instance and provide a global point of access. |
| Pattern | Folder / File | Description |
|---|---|---|
| Adapter | GoF/2.Structural/1.Adapter/ |
Converts the interface of a class into another interface clients expect. |
| Bridge | GoF/2.Structural/2.Bridge/ |
Decouple an abstraction from its implementation so the two can vary independently. |
| Composite | GoF/2.Structural/3.Composite/ |
Compose objects into tree structures to represent part-whole hierarchies. |
| Decorator | GoF/2.Structural/4.Decorator/ |
Attach additional responsibilities to an object dynamically. |
| Facade | GoF/2.Structural/5.Facade/ |
Provide a unified interface to a set of interfaces in a subsystem. |
| Flyweight | GoF/2.Structural/6.Flyweight/ |
Use sharing to support large numbers of fine-grained objects efficiently. |
| Proxy | GoF/2.Structural/7.Proxy/ |
Provide a surrogate or placeholder for another object to control access. |
| Pattern | Folder / File | Description |
|---|---|---|
| Chain of Responsibility | GoF/3.Behavioral/01.ChainOfResponsibility/ |
Avoid coupling sender and receiver by giving multiple objects a chance to handle a request. |
| Command | GoF/3.Behavioral/02.Command/ |
Encapsulate a request as an object. |
| Interpreter | GoF/3.Behavioral/03.Interpreter/ |
Represent a grammar as classes and interpret sentences in the language. |
| Iterator | GoF/3.Behavioral/04.Iterator/ |
Provide sequential access to elements without exposing the underlying representation. |
| Mediator | GoF/3.Behavioral/05.Mediator/ |
Define an object that encapsulates communication between objects. |
| Memento | GoF/3.Behavioral/06.Memento/ |
Capture and restore object state without violating encapsulation. |
| Observer | GoF/3.Behavioral/07.Observer/ |
Define a one-to-many dependency so that observers are notified automatically. |
| State | GoF/3.Behavioral/08.State/ |
Allow an object to change behavior when its internal state changes. |
| Strategy | GoF/3.Behavioral/09.Strategy/ |
Encapsulate interchangeable algorithms and make them selectable at runtime. |
| Template Method | GoF/3.Behavioral/10.TemplateMethod/ |
Define the skeleton of an algorithm and defer some steps to subclasses. |
| Visitor | GoF/3.Behavioral/11.Visitor/ |
Represent operations to be performed on elements of an object structure. |
-
Each folder contains:
Initialβ Bad example demonstrating common mistakes.Finalβ Good example applying best practices or design patterns.README.mdβ Explanation, problems, solutions, and suggested exercises.
-
All examples are written in C# / .NET 8 as Console Applications and can be run individually.
-
Follow the
README.mdin each folder to understand the pattern/principle and experiment with exercises.
- Design Patterns β DoFactory
- Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
- Apply SOLID principles first, then leverage Clean Code, KISS, and YAGNI.
- Use GoF design patterns to solve common software design problems efficiently.
- Always strive for readable, maintainable, and extensible code.
Please see our Contribution Guide to learn how to contribute.
(LICENSE) Β© 2025 ERNI - Swiss Software Engineering
Please see our Code of Conduct
Check https://repobeats.axiom.co/ for the right URL
π§ esp-services@betterask.erni
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!