Introduction to Patterns
So what is a pattern? Patterns were first described by a real "Bricks and Stones" architect. A pattern is a re-usable
solution to a common type of problem, without ever repeating the actual way the solution is implemented. This means that
patterns are an ideal learning tool and also ideal for communicating design ideas. Of course there are also anti-patterns,
things often used, but actually better avoided.
- What is a Pattern?
- The Gang of Four: Erich Gamma, Ralph Johnson, Richard Helm and John Vlissides.
- Different kinds of design patterns: creational, structural and behavioral patterns.
- Patterns everywhere: the difference between implementation, design and architecture patterns...
- When to apply patterns, and when not to.
- Some anti-patterns.
Implementing patterns in .NET
Implementing patterns actually depends on a number of things, especially the programming language being used.
- How you implement a pattern depends on the programming language in use.
- An example: implementing the Singleton pattern.
- Considering lazy instantiation and thread-safety.
- The easy - let the .NET runtime handle it - implementation.
Some basic patterns
Some patterns are so common that you have been using them for ages without realizing it. Of course it is still important
to understand these patterns, so you will know better when (and when not) to apply them. We will also look at some
commonly used implementations in C#.
- Template Method: Better class inheritance and extensibility.
- Factory Method: Don't hard-code key classes in your code.
- Abstract Factory example: Writing database independent code.
- Strategy: Allow your software to be easily customized.
- How to implement the strategy pattern in .NET so developers can easily discover it.
- Chain-Of-responsibility: Try till you succeed.
Ways to avoid the inheritance trap
Do be careful with inheritance. Before you know it you might end up with lots of classes.
Luckely there are a number of patterns which allow you to design your software in a more flexible way,
and compose different objects toghether to form various behaviors.
- Some examples of the inheritance trap.
- State: Implement objects with complex behavior the maintainable way.
- Flyweight: Optimize your code for less memory usage and less garbage collection.
- Adapter: Change the shape of an object to fit another object.
- Decorator: Change the behavior of an object; with an actual example applied in WPF.
- Implementing decorator the .NET way - using extension methods.
Patterns you have been using but never noticed
Of course the .NET framework uses a lot of patterns, some of these patterns are even built-in
(known as first-class citizen) into .NET. So let's have a look at how these are implemented in .NET,
and how you can extend some of these yourself.
- .NET came with a bunch of patterns - built-in.
- Observer: Notifying objects; better known as .NET events.
- Mediator: When two objects cannot see each other; for example .NET databinding.
- Anti-pattern: String based coding - and how Luciano Pavarotti can help.
- Novel ways of implementing INotifyPropertyChanged, and which way is the best?.
- Iterator: One way to walk over collections of objects.
- How iterator became LINQ.
- Composite: Build part-whole hierarchies where each element can be treated uniformally.
- How Windows uses composite to build expressive UI's.
- Guidelines for implementing interfaces.
Building your own little programming language with some patterns - Fun!
Programming languages also use a bunch of patterns in their implementation. In this chapter you will build your own little
programming language, which is extensible by the way. While doing so you will discover some very important patterns which
are perfectly useable outside of the scope of building programming languages!
- Interpreter: Build your own expressive language-grammar and execute it.
- How LINQ uses Interpreter - and how you can take advantage of it yourself.
- Building your own interpreter for simple math.
- Builder: Hide how complex hierarchies of objects get built - and allow variations.
- XAML as the ultimate builder.
- Reflection: the ideal .NET way for implementing your own builder.
- How NOT to use reflection.
- Visitor: When you need a lot of different operations on the same object structure.
- Building a pretty-printer using Visitor.
- Implementing Visitor the dynamic way.
Big applications use layers - which is an architecture pattern by the way. But big enterprise applications can also take
advantage of other patterns.
- Enterprise Applications are hard to build - soften it with patterns.
- Facade: Hide a complex hierarchy of classes and operations behind a unified interface.
- Proxy: Hide complex behavior behind a proxy: Lazy instantiation and networking for example.
- Inversion-Of-Control: make your enterprise application more maintainable and testable.
Most developers make lousy graphic designers. That is why we see the emergence of patterns that allow developers to focus
on writing code to implement the behavior of the application, while allowing graphics designers to build kick-ass user
interfaces. The main pattern is called Model-View-*Whatever*, with *Whatever* replaced depending on the technology you
are using. Understanding the MVW pattern is important as it is used to develop both windows and web applications.
- Model-View-Controller: An ancient pattern back in fashion.
- ASP.NET MVC - an introduction.
- MVVM in WPF - MVC taking advantage of powerful databinding capabilities.
- Command: Encapsulate behavior in objects.
- Implementing commands using closures.
Unit testing in .NET
Every developer's dream: maintainable code that works. How do you keep your code maintainable?
And how do you ensure some small change does not break your code? Unit testing to the resque!
- What every developer wants: Quality code that works; and keeps on working.
- Finding bugs: not just in code. - Or how NASA lost a 125.000.000$ Mars orbiter.
- What is unit testing? And what is a good unit test?
- Understanding the difference between a unit test and an integration test.
- Test Driven Development - Should you be doing it?
- Role-playing: Marge, Homer and Bart
- The Triple-A of unit testing - and what has cooking to do with this?
Unit testing with Visual Studio
In this chapter we will look at building unit tests with the built-in features of Visual Studio.
- MSUnit - Built into Visual Studio
- Building and running Unit Tests with MSUnit.
- Using the Test Explorer Window
Domain Driven Design
Getting the software right is a hard thing to do. This is because business and developers do not always talk
the same language. Domain Driven Design is all about getting the language right between them -
the ubiquitous language. We'll discuss the patterns used in DDD, and also look at some anti-patterns.
- What is Domain Driven Design?
- The Ubiquitous Language.
- Anti-Pattern: Bug Ball of Mud.
- Adding Bounded Contexts.
- Entities vs. Value Objects.
- Anti-Pattern: Death by a thousand dots.
- Using aggregate roots.
- Building Domain Services.
- Repository: keep the database out of your code.
Architecting Modern Web Applications
So what is a modern web application? One that uses Angular and TypeScript? With the speed that modern
web application developement evolves, there is the chance that your web site uses 'old' technology by
the time it is done. But sound architecture never goes stale.
As a wise man once said: 'If you think good architecture is expensive, try bad architecure'.
- S.O.L.I.D. principles.
- Separation of Concerns, Dependency Inversion, Explicit Dependencies, Persistence Ignorance.
- "Clean" architecture: put the business and application model at the center.
- Easily tested with Automated tests
Design Patterns Applied: Developing your own reusable library.
When do you need patterns the most?! When you are building a framework yourself. Building a framework means handling new
features while keeping backward compatibility. This very hard task can be make easier with the proper use of patterns.
So in this last part of the training we will build a reusable library, and while doing so encounter some problems and
then solve these problems by applying the right pattern.
- Adding the GoF Command pattern to MVVM.
- Using interfaces for flexibility.
- Building Command Objects - extending WPF's ICommand interface.
- Adding Undo and Redo functionality to the command pattern.
- Using a CommandManager class.
- Challenge: retro-fitting our commands into MVVM without lots of changes.
- Implementing Undo-Redo using the Memento pattern.
- Choosing whether or not to add the Prototype pattern.
- Ideas on how to proceed with the command pattern.