Main

Are Design Patterns Dead in C#?

Become a patron and gain access to source code and exclusive live streams: https://www.patreon.com/posts/are-design-dead-81382714 When was the last time you implemented a proper design pattern in your object-oriented code? Not a factory method, but a proper, complex design pattern! If it was long ago, then you are not alone. Think of all the decorators, adapters, builders, chains of responsibility, observers, states, and visitors you never made. You never made... because they were there. This video will show you a glimpse of modern code which will incorporate no design patterns at all. And yet, it will mostly consist of design patterns. How come? The answer is in libraries, the framework, the language syntax, in all the elements we use when writing code. Those elements are built on top of numerous patterns and they are exposing interfaces and methods that are so simple, that consuming any of these design patterns takes no more than a single method call or instantiation of a single object. By the end of this video, you will learn that design patterns are still everywhere in our code, the same as they ever were, but that we are not responsible to implement them in most cases. Corner cases will remain, though. If you are writing low-level library code, extensions, and frameworks, then you will likely keep implementing all those design patterns over and over again. But keep this principle in mind: implement the design patterns in your library, so that its users won't have to. ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ Thank you so much for watching! Please like, comment & share this video as it helps me a ton!! Don't forget to subscribe to my channel for more amazing videos and make sure to hit the bell icon to never miss any updates.🔥❤️ ✅🔔 Subscribe ► https://www.youtube.com/channel/UCxsWfh8LCcn55mFB6zGBT1g?sub_confirmation=1 ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ ⭐ CONNECT WITH ME 📱👨 🌐Buy me a Coffee ► https://ko-fi.com/zoranhorvat 🗳 Pluralsight Courses ► https://codinghelmet.com/go/pluralsight 📸 Udemy Courses ► https://codinghelmet.com/go/udemy 📸 Join me on Twitter ► https://twitter.com/zoranh75 🌐 Read my Articles ► https://codinghelmet.com/articles 📸 Join me on LinkedIn ► https://www.linkedin.com/in/zoran-horvat/ For collaboration or any queries: ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ 👨 About Me 👨 Hi, I’m Zoran, I have more than 20 years of experience as a software developer, architect, team lead, and more. I have been programming in C# since its inception in the early 2000s. Since 2017 I have started publishing professional video courses at Pluralsight and Udemy and by this point, there are over 100 hours of the highest-quality videos you can watch on those platforms. On my YouTube channel, you can find shorter video forms focused on clarifying practical issues in coding, design, and architecture of .NET applications. ❤️ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ ⚡️RIGHT NOTICE: The Copyright Laws of the United States recognize a “fair use” of copyrighted content. Section 107 of the U.S. Copyright Act states: “Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phono records or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright." This video and our youtube channel, in general, may contain certain copyrighted works that were not specifically authorized to be used by the copyright holder(s), but which we believe in good faith are protected by federal law and the Fair use doctrine for one or more of the reasons noted above. ⭐For copyright or any inquiries, please contact us via a comment #designpatterns #dotnet #csharp

Zoran Horvat

11 months ago

"... you can use this solution a million  times over without ever doing it the same way twice" - and the authors continue saying  "even though Alexander was talking about patterns in buildings and towns, what he says  is true about object-oriented design patterns." What's true? - "you can use this  solution a million times over without ever doing it the same way twice"? You can use the solution a million times over and use it the same way every time. That is because languages today, C# and .NET
today, are not what the languages were in 1994. And listen, some of the things I plan to demonstrate in code today, you  may have never heard before. Let's start. This is the code from a previous video  where I have implemented an efficient intersection of two sorted sequences. This method is using the Iterator design pattern explicitly. I'm manually implementing the consumer of the Iterator. It begins by calling the GetEnumerator, calling the MoveNext, testing  its result, typically in a loop.
Here is the loop below. Eventually, either yield break, or just leave the loop to terminate the iteration. You can watch that previous video. It was dedicated to LINQ. In that video I have explained why this operator implementation is better than that general  purpose Intersect operator from LINQ, in cases when you know that both sequences are sorted. Here I want to show you what happens to the Iterator pattern for example  and other design patterns. The point that I want to prove with this  vid
eo is that it is exceptionally hard to find a realistic, real world example,  where this kind of code is required. Here is an example that might request  using the Iterator pattern explicitly. Format a book signature. Now comes the funny part: an unknown number of authors in this IEnumerable. We don't know how many people there are. But okay, let's suppose that this IEnumerable  comes from some stream, from the socket stream, from a database, and we really don't know how many  people there are u
ntil all of them are in memory. And we don't want to put them into  memory because we don't need them. We need the printout of the book signature,  like this book was written by these people. There will be several distinct  use cases we must cover. You will see that each of these cases will  produce a substantially different printout. And we must solve all of those separately. And all of those in this single method. So, I will start by really implementing the  Iterator pattern explicitly, or con
suming it. The Iterator pattern is  implemented by the IEnumerable. I will Implement an explicit  consumer of the Iterator here. If there are no authors, then the  first call to MoveNext return false. In that case we have a book with no known author. Just return the title and that's it. Otherwise, we must take the title of the book, append "by", and then follow it  by the name of the first author. And again, if there are no more authors than this  one, return what we have done so far and quit. S
o, we have two use cases implemented  so far, in these four lines of code. All other authors should be separated  with a comma except the last one who must be separated with "and". So, it would be: the book written by this, this, and that author. That is the specification of requests. Now, that will be complicated. I need a kind of a state machine for that. Keep the last author seen aside and, while  there are others, that will mean that this latest variable is not really the last  author, but t
he one that precedes the last. Add that one, separated by the comma, and keep  the current one as a possible last author. One day this loop will end and the latest variable  will really be the last author in the list. Separate the latest author with "and"  and return that from the method. Let's run the application and see what it prints. Well, it has printed all the cases correctly. This is really good. First case: no author. Second: just one author. These are right. The third case: two authors
separated by "and". And the fourth case: all outers separated by commas except the last one separated by "and". This is just as requested. But again, how likely is it that you will  ever encounter a case where you need to do special attention to the first and the last  element in the sequence and the different attention to all the elements in between? I don't know, this is really not so realistic. That adds to my point that true requests  to implement a design pattern such as an Iterator explici
tly is really a  rare occurrence in practical coding. Here's the alternative. What if we really knew the number of authors? How hard can it be to know how  many people wrote the book? The alternate implementation  will be next to trivial. I will use pattern matching  with the switch expression. And I will use list patterns  to implement this method. Look, the first pattern is an empty array. In that case just return the title. Then the case with a single author. Note that I'm capturing the singl
e string value into a variable and then  using that variable to format the string. It's all getting very easy with list  patterns that are fairly new in C#. And the most complex pattern comes here. An unknown array of authors comes first. This range pattern here matches zero or  more elements and it will capture them in the string array I called fore here. This range of items must be followed by a single string which I will capture  into the variable called last. Now, as I said, the range patter
n  is capturing zero or more strings. But that's not what I need. I have the single element pattern preceding and if that pattern didn't match, then  there must be at least two elements in the array. So, in practical sense, this array  fore will never be empty in this case. But there is one interesting point to make here. If you noticed, while I was developing this expression, there was constantly a  compile-time warning at the switch expression. That was so because the compiler was complaining 
that the switch expression was not exhaustive. But as soon as I have completed this  last pattern, compiler has figured out that I have covered all possibilities  and compile time warning has disappeared. This expression is exhaustive. It is checking and matching every conceivable array of strings. I want to separate those preceding authors with commas, then append  "and" and append the last author. This is the entire expression - three  lines of code - replacing that state machine with the Get
Enumerators and MoveNexts. This is much simpler, much easier to understand. And here are those same four books we  had before, this time instantiated as the Book record instances. I will just print them out, using the pattern matching expression. Let me run the application and we will see. Here, the two printouts are letter-to-letter  exactly the same, which proves my point, I guess. There's really no need to consume the  Iterator explicitly, even in such a complicated case like this one, when t
here are  several different use cases that you must cover. Implementing a state machine with  explicit MoveNext... well that is crazy. How can you know that that code is  correct when it is so complicated? Compare that to three lines of code with the  pattern matching and you will see that the second implementation is certainly correct because  it reads exactly the same like the requests. But this is a video about design  patterns, not just the Iterator. There is more in design  patterns than th
e Iterator. By the way, if you liked this video  so far, please press the like button. That will help others find it, thank you! Let's move on. What if I wanted to sort the books? But I will insert a few collisions, intentionally, into this array. That will put emphasis on comparison used in sorting. That will be a problem, you will see. One will be the book with the same  title name but a different author. I'm cheating a little bit. This book is really not named the same. And another one, I als
o made  up, varying in authors list. So, the title is the same again, but  the author list will be a bit different, with the collision on the first author. This will be Domain-Driven Design written by Eric Evans and nobody else. Now, title is comparable already. But the array of authors is not. I will prepare a helper method. It took me a couple of minutes to implement this. It is comparing two arrays of elements of comparable type T lexicographically, which  means like the way you would sort wo
rds in a dictionary: left-align them and start  comparing until either they're equal or you find a different letter or one of the  words is exhausted - then it is smaller. Funny enough, this implementation  is not using the Iterator. It is procedural, it is using  the for loop with the index. Now, this static method used as the method group  is assignable to the Comparison delegate in .NET and you can pass this method group in any  place into any method that expects comparison, like List's sorti
ng does that. But what if we needed an IComparer? LINQ's OrderBy expects an IComparer. Shall we implement the Adapter design pattern to adapt Comparison  delegates to IComparer of T interface? Yes and no. No because it is already implemented for us. Generic Comparer class has a static method  named Create which wraps a Comparison delegate into an IComparer of T object. This is adapter design pattern implemented right in the BCL. Let's get back to sorting books. We need a two level sorting. One l
evel is to compare titles. But if the titles are equal,  then we need to step to the second level that is comparing author lists. Well, that sounds like Chain of Responsibility. And I have even published an entire  video using Chain of Responsibility to chain IComparable implementations to  make this very effect I'm showing you here. So, is this the place to  use Chain of Responsibility? Yes, for example, sorting a  list again is the case for that. But we are not using List.Sort here. I'm using
LINQ and LINQ already implements the Chain of Responsibility with its OrderBy method. Order by the book's title. And if titles are equal, put the next link  in the chain: ThenBy the authors array, sort using the lexicographical  comparer we prepared before. And this is the Chain of  Responsibility right inside LINQ. Let me write down the patterns  I'm using in this piece of code. Here begins the Chain of Responsibility. The other one, let me expand it so that you can see it better, that is the 
use of the Adapter design pattern. And there was another video I also  made on Decorator design pattern. Now here is the problem. If you want to invert the sort order, some methods, some classes will not help you with that. Again, List.Sort - there is no sort descending. You must implement your own Decorator  around it to reverse its decision. Again, there is the entire  video I made on that example. And again I'm not using the  List.Sort here, I'm using LINQ, and LINQ does have a variation whic
h applies the  Decorator to your comparer: ThenByDescending. It will be an inverting  decorator for the comparer. In the end, the almighty Iterator. This time I'm consuming the Iterator design pattern using the foreach keyword. It's four lines of code using four different design patterns. Chain of Responsibility and the Decorator are implemented by LINQ here. Adapter is implemented in BCL, the framework. And the Iterator consumer is  supported by syntax of C#. Just in case you don't believe me t
hat  this will work, I will run the application. Books are indeed sorted ascending by the  title and then descending by the authors list. The code looks correct to me. Did I use design patterns in .NET? Yes, all the way. Did I Implement design patterns? No, none of them. They are all there for us. You will use design patterns implicitly  today, that is the point of this video. And then, what was that sentence again? "... you can use this solution a million times over without ever doing it the sa
me way twice." That was published in 1977. Well, in 1977, I was two years old. Have you been born then? This sentence may be true if you are  writing code close to bare metal. Every implementation in a library  will potentially be unique. That's why you will develop it, because  there's no library that does it. But if you are writing business  applications today, in 21st century, three decades after this book was published, you  will not be writing it over every time again. You will have framewo
rks, you will have  base classes, you will have the language syntax that will do that for you. That doesn't mean that design patterns in business applications are dead. No! It only means that they are buried deep under the surface where you cannot see them. But you can benefit from them. I hope you have learned  something valuable in this video. Like it, share it, subscribe to my channel  and come again when the new videos appear. Thank you for watching till  the very end and see you again.

Comments

@zoran-horvat

Become a patron and get access to source code and exclusive live streams: https://www.patreon.com/posts/are-design-dead-81382714 Write your thoughts about design patterns in modern business applications! I'd like to hear your opinion on the frequency and place of design patterns in your job today.

@usamesavas9848

Your explanation is amazingly clear and short pauses here and there let the viewer have time to digest the content. I appreciate this video <3

@purplebytessolutions6994

I now watch at least one video on this channel every day!

@wobblejuice

You should write a book on modern C# design matters!

@nandomax3

I thought I never knew what desing patterns were, but the more I study, the more I see them in my daily life as a developer. For example, observers are used a lot in game development to manage signals and in asynchronous tasks, the Future or premise are always an observable

@spechulfapticks3108

totally agree. i never implemented "chain of responsibilities" myself, but i do use thenby from time to time. usually development (at least for me) looks like "you just use the existing thing and only go dig the internals + implement yours, if the existing one does not work, as you want it to". having powerful means of programming, leads to that we need to have less self-made implementations for day-to-day routine

@nalinsharma9881

Well he is like a strict Professor who brings unique ideas and is always correct 😄. Huge respect sir !!

@creamyhorror

I appreciate your clear explanatory style. I just want to point out you're talking about design patterns used in standard language functions like pattern-matching and LINQ, but as developers, we're usually working within our applications' business domains (where Microsoft isn't writing the code) and so still (occasionally) need to use design patterns for our domain objects. So your title is a bit misleading (maybe intentionally clickbaity?). Nonetheless, it's really nice to have new powerful language features that simplify coding: pattern-matching is a great, simple replacement for the Visitor pattern, which is a bit complicated and not needed in most cases.

@vatyunga

Liking this video did help others to find your videos. I'm one of the others and I'm very glad I found your channel.

@49riddickful

The outro was very nice! Thanks for those videos, I hope to gather all the knowledge I can

@akhilbandari629

Great content Zoran as usual Always waiting for your videos to learn some C# internal concepts

@HOSTRASOKYRA

My mindset was changed forever. Thank you!

@kristianaranda

Another masterclass, thank you! I was hoping you would finally open up the possibility to become patreons of your channel, so you don't stop making videos!

@adrianterencehand

Love this gentleman’s delivery, he is like Vigo Tarasov dropping OOP knowledge instead of tales of baba yaga

@nkesteren

Fantastic explanation! Thanks for sharing your insights.

@habibahmad1

Crystal clear explanation. 👌

@ApacheGamingUK

This video highlighted to me, the importance of the Oxford Comma. First, second, third, and fourth.

@slimbofat

IEnumerator<T> is disposable, no? important to clean up usings inside of a "yield" function.

@MrBenMcLean

The fact that you no longer need to implement the design patterns yourself does not make the Gang of Four book irrelevant for most coders. Their work is still important for you to understand what's actually happening when you use those modern language features. But yes, you should avoid rolling your own whenever possible.

@TheAlStewartArchives

You are a very talented broadcaster. I’ve never seen someone talk about programming on YouTube in such an informative and enjoyable way. Your pacing etc… is perfect. Keep at it and this channel will be huge!