Design patterns are not just for architects. In fact, you already use Design Patterns but probably don’t know it. Observer, Proxy, Facade - these are patterns that allow us to better communicate our ideas with other developers. And once we understand the patterns, we can use solutions that people way smarter than us have already implemented.
In this session, Jeremy Clark takes a look at several Gang of Four patterns that we regularly use without realizing it. Don’t know who the Gang of Four is? Watch the webinar to find out.
Watch the webinar and learn:
- What design patterns are (and what they are not)
- How design patterns offer solutions to common problems
- How we already use many design patterns, including Observer, Proxy, and Facade
- How our modern languages support design patterns
Design Patterns: Not Just for Architects on Vimeo.
Download code samples.
Q: Out of all the design patterns, how does a newbie decide which patterns to use for a given problem1? In other words, is there a way to filter out the patterns to arrive at a subset of suitable pattern?
A: This is a difficult question to answer. There are multiple ways to solve a problem. And there are also multiple design patterns to solve a single problem. The differences in the pattern have to do with what approach is taken. And this often leads to a different set of consequences. I would start by understanding the Gang of Four patterns. These are very common problems/solutions. And it will help understand the more complex patterns than you might run across. Just like learning anything new, start with the basics and talk to people or look online to see what people who are working in the same problem-space are doing.
Q: Does design patterns always obey SOLID principles? Or is it even important to do so?A: The SOLID principles are “best practices” in the object-oriented programming world. I don’t like to use the term “best practice” because that sounds like it is always the right answer. But with my experience (but success and failures), I’ve found that they are a good place to start. If I have a reason to not use the practice, I’m okay with that as long as I understand the pros and cons of a particular situation. In general, the Gang of Four patterns can help us adhere to the SOLID principles, but it all comes down to how we use them.
Q: Any example of factory or abstract factory which we are using and not aware of?
A: Unfortunately, I can’t think of one off the top of my head. But I have use the Factory Method to dynamically load objects from the file system. If you’d like an example, you can see my materials on C# Interfaces: http://www.jeremybytes.com/Demos.aspx#INT.
Q: Isn't Proxy pattern built-in pattern with tools like Visual Studio?
A: The implementation of the Proxy pattern that we looked at (accessing a SOAP service) is definitely built in to Visual Studio. But there are other scenarios we might want to use the Proxy, such as using a thumbnail image instead of bringing down a full image or the difference between downloading a song and streaming a song. So we do have certain implementations of patterns that are built into our language and tools. Some other examples in C# are Iterators (IEnumerable) and Observers (Event Handers / IObservable).
Q: How do we know that we need to use design patterns to a specific problem? Because most of the problems can be solved without using any design pattern.A: Learning about design patterns helps us see what solutions are available (and hopefully we can borrow someone else’s solution rather than creating our own from scratch). We can build a house by stacking bricks, but if we understand the patterns of walls, lintels, and foundations, we’ll end up with a much better structure. Programming patterns are the same way. I spent many years using patterns accidentally because I ended up solving these common problems. But once I could put a pattern name to a problem, I could look at how other people implemented the pattern. Sometimes I use those solutions, and sometimes I used them for ideas to incorporate into my own solutions. But that lets me use much better than what I could come up with on my own.
Q: There are plugins which allow patterns to be implemented in Visual Studio. Would you advise using them or rather learn the codes and implement them?A: I haven’t used the tools, so I can’t give an informed answer. As a general rule, I like to understand what the tool is doing before I use it. For example, I use Dependency Injection (DI) containers when I code, but I was not able to use them effectively until I understood what the containers were doing – and more importantly why. I would think it’s the same with pattern tools. I want to understand the patterns (particularly the “why”), and then I would be fine with letting a tool do the hard work for me. This would be similar to how I let Visual Studio create the SOAP proxy for me. I don’t need to understand all of the details (XML, HTTP, etc.), but I do need to understand why I’m using the proxy.
Q: What pattern should I use for creating exception handling library?A: Exception handling is a pretty big topic. It turns out that the built-in exception handling in .NET uses the Chain of Responsibility pattern (this is one of the examples I show when I have a bit more time to talk about patterns). When an exception is thrown, it looks for a catch block that can handle it. If it can’t find one in the current method, it walks up the call stack to the calling method. Then it just keeps walking up the call stack until something can handle it, or it drops off the end. (And this is why it’s a good idea to put a global exception handler somewhere in the code to make sure the user has a good experience.)
Q: Instead of using Proxy pattern for WCF services, I prefer use ChannelFactory object to use same object from the service without any MAPPER. Is there any other way to use Proxy for this case?A: As we saw in the definition of design patterns, there are a million different implementations. If there is a built-in implementation (such as the WCF Proxy in Visual Studio), I like to start there since it’s “free”. But if I find that my needs are a bit different (like I want to optimize for speed), then I’m free to look for different implementations or create my own. So there are lots of ways to use a Proxy in this situation. Unfortunately, I haven’t looked into them since the built-in one has worked for the situations I’ve needed.
Q: What about structure diagram and code?
A: Often when patterns are described in pattern catalogs, they are accompanied by a UML class diagram. Personally, diagrams often cause more confusion for me than help, so I tend to not use them. It’s easy for me to look at a class diagram and get stuck in a particular implementation when I really would rather understand the spirit of the pattern and the concepts behind it. Both the Gang of Four book and Head First Design Patterns include class diagrams (although the Head First book uses them for specific example code rather than the overall pattern).
Q: What pattern should I use for micro service implementation?A:Micro-services is a big topic. Looking for *a* pattern is like looking for a pattern for a web site. Generally, we would use multiple patterns to address the different problems that we are trying to solve. If we think of each micro-service as a self-contained application, then we can imagine using quite a few different patterns in putting it together.
Q: What is the difference between proxy and facade?
A: The main thing about design patterns is to look at the problem they are trying to solve. One way to think of the Proxy pattern is as a way to access a remote resource as if it were a local one (it’s a bit more general than that, but that’s the example we saw with the SOAP proxy). The Façade pattern is a way to reduce complexity by creating an easier way to interact with something (as we saw with the “foreach” example). The implementation of the SOAP proxy can also be considered an implementation of the Façade pattern since it’s wrapping the complexity of making the SOAP call (XML, HTTP, etc.). This is part of the fun when we start looking at patterns. We find that complex systems are often a combination of multiple patterns.
Q: When I have multiple patterns that can be used to solve a problem, how can I choose one, or can I combine them?A: This is one of those areas where we try to understand our tools better. There are multiple patterns that address the same problem (for example, there are many patterns that are variations of the Gang of Four patterns). In that situation, look at what the pattern is optimizing for. It may be addressing a particular consequence, such as performance or memory usage. If you are concerned about that consequence, then it may be a good choice. But if that consequence isn’t important to you, then something else may be better.
Q: Taking into account the example of IEnumerator and foreach, what would be the most correct to use?A: Since “foreach” gets compiled into the same code as using “IEnumerator” directly, I would use foreach. This makes our code more readable – and we need to make sure our code is readable by humans in addition to the computer. If there were a difference (for example, if the direct use were faster), even then I would look very carefully to see if that difference is important to me.
Q: You said foreach is a facade pattern. Is it also an iterator? Does it mean that any concrete implemenation can be a combination of multiple patterns?A: Yes, foreach is an example of the iterator pattern. In fact, I talk about this when I have more time to talk about design patterns. Many things we run across are implementations of multiple patterns. Another example is data-binding. This implements the Observer (when the UI elements change, the backing objects are changed) and also the adapter pattern (when a backing field is a number, it is displayed in the UI as a string). In reference to “foreach”, I usually call this an ‘Iterator” since that is its primary purpose – to iterate over items. The “Façade” pattern is more an implementation detail than the primary purpose.
Q: Which design patterns are useful in writing cross-platform code?A: There are a lot of patterns that we can use in cross-platform code, just like there are lots of patterns we can use in any application. The patterns we use depend on the needs that we have. For example, if I wanted specific UIs for each platform and wanted to share presentation code, I would look at various patterns that could help with loose coupling, such as Abstract Factory or Inversion of Control. But these aren’t strictly limited to cross-platform concerns.
About the speaker, Jeremy Clark
Jeremy Clark makes developers better. By drawing on over 15 years of experience in application development, he helps developers take a step up in their skillset with a focus on making complex topics approachable regardless of skill level. He is a Microsoft MVP for .NET, and he has authored seven courses for Pluralsight, including "C# Interfaces", a course aimed at giving developers a clear understanding of abstraction. He loves speaking and has delivered over 200 technical presentations in the last 7 years in the United States and Europe. Jeremy lives in Southern California with 2 cats and a banjo. Jeremy's blog.
Structured exception handling and defensive programming are the two pillars of robust software.
Both pillars fail however when it comes to handling internal faults, those that normally originate in software defects rather than in any external factors.
In this webinar, Zoran Horvat demonstrates advanced defensive coding techniques that can bring the quality of your code to an entirely new level.
Watch the webinar and learn:
- When throwing an exception is the right thing to do
- Why exceptions and defensive coding cannot be applied to recover from defects
- How to handle situations when internal software defect is causing the fault
- How to treat fault detection as an orthogonal concern to normal operation
Advanced Defensive Programming Techniques on Vimeo.
Download code samples.
Q: Doesn't the argument against the rewriter for Code Contracts also apply to PostSharp?
A: Actually, no – IL rewriting done by Code Contracts makes the code you see during debugging not the same as the code you execute. PostSharp respects the whole development chain, so even though it is rewriting the IL, the debugging experience remains untouched. You can debug not only your production code, but also the aspect code including even your custom build-time logic. And the PostSharp Visual Studio extension helps you to keep track of all the enhancements PostSharp does in your code.
Q: Why not using the standard Microsoft Code Contracts library instead?
A: Code Contracts are obtrusive, and my experience shows that development teams are not ready to take the risk. The teams I was leading have never even considered using Code Contracts library, and I didn’t want to push the matters either.
If I had to pick the sole reason for not advocating use of Code Contracts library, it would be the fact that it is modifying the IL code in a non-transparent manner. Even the original documentation states that IL code rewriting may be the reason for teams to avoid using Code Contracts.
In my opinion, Code Contracts could have been designed as a regular library, and that would remove that veil of mystery that surrounds the process of code rewriting. I suspect that primary concern was performance. But then, if you look at spectacular performance gains of ASP.NET Core, for example, we could question that reasoning on grounds that performance could have been improved using other means. We will probably never know.
Q: How does this relate to Code Contracts?
A: If you decided to try Code Contracts on this same example, then you would find that there is correlation between syntax I have shown and Code Contracts syntax.
That is not a coincidence, because my example was strongly influenced by the Code Contracts library.
There are two reasons why I have opted to use custom contracts instead of a library. For one thing, I wanted to show you the bare bones, because that looks more convincing. Core of the contracts implementation is, as you could see, no longer than ten lines of code. The second reason is that in previous demonstrations part of the audience was complaining that I am pursuing a lost cause, predicting slow and painful death to Code Contracts. I am very fond of that library, it is very smart and also complete, but current level of support truly doesn’t fuel optimistic feelings.
Q: How does this presentation apply to PostSharp?
A: PostSharp tool supports code contracts as an aspect. You can add attributes to method arguments and describe preconditions that must be satisfied (e.g. that an argument must be non-null). It also supports custom extensions so that you can widen the use of aspects provided by the tool.
The theory which I have demonstrated is more general than any tool (except Code Contracts) currently supports, and that stands for PostSharp as well. I have insisted on unconstrained version of the theory so that you can see the direction in which that is going. Tools are getting better with every year anyway.
Q: How to extend code in a way that client code will know that method does not return null or does not accept null as an argument for instance?A: Expectations made by the method are called preconditions; promises made by the method are called postconditions. Failing to meet a precondition indicates a bug in the caller; failing to meet the postcondition indicates a bug in the called code. So much about terminology.
Preconditions and postconditions are part of documentation. You may wish to write unit tests which would document them in an executable way, but there is currently no way to rely on, say, language or Visual Studio about that.
There was an attempt to design a Visual Studio extension which would read Code Contracts and expose them as part of IntelliSense. That extension was unstable and I had to remove it from my copy of Visual Studio after trying it for some time. There are other similar attempts, but none which would make an impression.
There were requests to Microsoft to include contracts in Roslyn compiler, but the team has rejected that. It remains to wait for someone to develop an extension which would incorporate contracts validation into the build, I suppose.
Q: Are these given precondition contracts all we need, or do you use (many) different ones not shown here?A: As in previous question, we also have postconditions – promises made by the method. For example, method should never return null, and then it asserts that the return value is non-null before exiting. Such postcondition tells callers that they don’t have to guard against null before accessing the result of our method – a useful hint indeed.
But generally, even if you decide not to use any tools, preconditions that I have shown in this demonstration are pretty much everything you might need. As any great idea, Design by Contract is very simple.
There is, however, one subtlety. Preconditions are inherited, so that derived classes are satisfying the Liskov Substitution Principle out of the box. It is forbidden to add more preconditions in the derived class. Now, that sounds easy when you have base and derived classes. The real problem is that all this stands for interface inheritance as well, and that is what makes Design by Contract messy in .NET.
Code Contracts library came with a powerful (and complicated) solution to contracts inheritance problem. You may refer to their documentation for details.
Q: Where can I get more instructions on using contracts?A: The authoritative source of information on Design by Contract is Bertrand Meyer’s book Object-Oriented Software Construction. That is where Mr. Meyer has introduced and explained DbC theory in such terms that there is virtually nothing more to be added.
Q: Your idea of recovery is not technically sound... How this "separate" concern can work in multi-threaded environment?A: Multithreading is another concern. It is not advisable to enforce thread safety on any given piece of code. It is better to implement thread safety as a separate class which wraps a non-safe component. In that way, code is much simpler and usually less error prone.
When things are put that way, it turns that contracts will remain in the component which doesn’t deal with threads and therefore it is 100% sound.
Take TPL as an example – threading was incorporated in Tasks and Task Managers, leaving logic intact. If you take a look at the way Code Contracts library is already handling async/await constructs, you will see that there is nothing missing in their solution.
Q: How practical it is to remove precondition from production code? What should your method returns in production if someone violate your preconditions for method?A: Sometimes people decide to remove contracts checking from production code just for performance reasons. Note that contract clauses can also be viewed as part of a larger testing picture.
You can consider rigorous proofs as one level (which you run once – on paper), automated tests as another level (which you run sometimes), and then contract checks as the third safety valve (which you run every time the code executes). Now, it’s obvious that you can drop contract checks if you are pretty sure that automated tests have done the good job, or even that you have a formal proof that contract check will never fail.
In about one month from now a new course of mine will be published at Pluralsight – titled Writing Highly Maintainable Unit Tests. In that course I am explaining in great depth relation between formal proofs, unit tests and code contracts. For those of you having Pluralsight subscription, it might be useful to watch that course once it goes live.
Q: If we have checks/contracts on debug or staging, how would we not want that on production? Ex: checking to see if the students exists would have to be checked on production as well right?
A: This relates to previous question, where I have argued that code contracts are only one level of safety, though the most rigid one. If your code is tested well, then you don’t even have to put explicit contract checks into your code. However, I don’t think that any production code is tested enough to truly remove contract checks, because contract violation would then pass unnoticed and it could possibly damage data.
Therefore the conclusion. It pays to consider removing some of the costly contract checks. For example, remove quantifier which has O(N) complexity from methods with sub-O(N) complexity – like methods that have O(logN) or O(1) complexity. Leaving contract checks there would make the code observably slower. You probably don’t have to remove an O(N) contract check from a method which already has O(N) complexity or higher – like O(NlogN) or O(N^2). Contract check would then reduce performance by at most a constant factor, which we can survive.
Q: Wouldn't Debug.Assert be removed from Release build even without the #if DEBUG compiler directive?A: That is true in my example. I have included the conditional build just to show you the concept. But don’t forget that there is the Release version of assertions in .NET. Some people opt to assert in Release build as well. That makes sense in very sensitive code, where erroneous execution might cause unacceptable consequences.
Q: Is there any situation in which non-private custom Exceptions should be used?A: Exceptions remain valid solution in all exceptional situations. If you are writing a library, you would probably opt to throw a custom exception back to the caller, than to put a burden to the caller to have to use certain code contracts library (including your own).
However, inside your library, you could still be fine if you decide to institute contracts as the design strategy. That will at least save you from your own bugs, not related to any other code that might call your functions.
Other legitimate cases are already covered by the .NET Framework and other libraries and frameworks. Consider network exceptions as an example. Network communication is a typical example of the process which is full of exceptional cases, and that is where exceptions can be of great value.
Note, however, that there is one funny side of exceptions, which can give us a hint about when exceptions are a valid option. Although they are representing exceptional events, we always expect exceptions. We expect network exceptions when working with remote services. We expect database exceptions, like concurrent edit, deadlocks or timeouts. We expect IO exceptions when working with files. If you have a situation in which you actually do not expect anything exceptional to happen, than you will probably be better off if you avoid introducing an exception.
Q: Is it correct to say that catching or throwing exceptions in between the execution of a function is an anti-pattern?
A: Using exceptions to procure information or to alter control flow is definitely the anti-pattern. Just consider this case. You have caught a custom exception and you are ready to do what it says. Now – how do you know that the exception was thrown by the entity you expected? Exceptions can jump over activation frames. You are certainly not going to inspect call stack from the exception object to discover which function has thrown it.
This analysis can go much deeper than this. Maybe it is enough to think of catching specific exceptions as breaking encapsulation of the called code and knowing too much about its implementation. That is rigid and fragile and it breaks principles of OO programming - which is not the problem in itself, but then you won’t have any benefits of OO like polymorphic execution.
Q: Since preconditions have been rephrased as declarative code, can we use attributes to define contracts? Any frameworks for doing this?
A: PostSharp tool is defining contracts through use of attributes. However, keep in mind that attributes must be compile-time constant, and therefore you cannot pass just any expression as an attribute-based contract.
However, it is possible to cope with that (in theory). You could use static attribute to somehow point to another method which contains more elaborate contract verification code.
Q: Briefly, what was the purpose of the private ContractException?
A: Primary fear from throwing exceptions when precondition/postcondition is violated is that somebody might catch that exception and forget to rethrow it. In that way, operation might continue to run, even though we have just found sufficient reason to terminate it.
That is the reason why in Debug mode many developers opt to assert, i.e. to kill entire process, rather than throw an exception. But then, in production, killing the process is not the most user friendly behavior we could come up with, and for that reason we may decide to throw exceptions instead.
But then, we don’t want to throw an exception which can be explicitly listed in the catch block. We don’t want anyone to catch that exception for any reason. In order to catch a private exception, you must catch its base System.Exception instead. And it makes sense to expect that nobody will ever catch System.Exception deep inside code. That is the justification behind private exception class.
Q: If you want to access a resource such as database and you split it to two function: One to check whether there is a value, and another to fetch the value. This will use expensive resource twice, so maybe here return nullable value is ok?
A: Database access is not subject to Design by Contract. Database is to our code just another outer system and we are dealing with it with all precautions we would make in any other case. You have to catch exceptions coming out from the database because you have no idea what might go wrong there (like deadlocks or timeouts, or even plain failures such as corrupt index).
Then the question how to deal with a nonexistent value where it was expected becomes easier. You just query the database as it is. Then turn concrete data into concrete objects. And then those objects would be subject to Design by Contract. If an object requires a value, and you got nothing from the database, then don’t call the method and take a recovery course instead. Otherwise, if you try to invoke the method with null reference, just because database returned no rows, the called object would preserve right to explode.
About the speaker, Zoran Horvat
After fifteen years in development and after leading a dozen of development teams, Zoran has turned to training, publishing and recording video courses for Pluralsight, eager to share practical experience with fellow programmers. Zoran is currently working as CEO and principal consultant at Coding Helmet Consultancy, a startup he has established to streamline in-house training and production of video courses. Zoran's blog.