 I'm extremely happy to be here. It's like my first time in Belgium. And for the last few months, I've been practicing French. And I was so excited that I will finally, I will have, for the first time in my life, the chance to practice French. And then I came to Ghent and it appears that no one speaks French to me. So it didn't really work out well. But the first day I was in Brussels and then I went to restaurant and I sat down. I ordered something to drink, all in French, all perfect. And then I wanted to order something to eat. And I saw lasagna in menu. And when it comes to lasagna, I'm basically Garfield. Any time, any place, just always lasagna. But I had no idea how to pronounce it in French. Like, I still have no idea. How do you call it lasagna or lasagne or something else? So when the waitress finally came and asked me what I want, I was like, I panicked. And I said, lasagna bolognese with this characteristic hand move like Italian. And it went well. It went well, she understood me. And it went too, too well. I was too good. Because then when waitress came to tell me something, she was like lasagna diece minuto. It's like, what does it even mean? Like, why does she speak Italian to me? So probably I have too good Italian accent. But yeah, that was it about my French practice in Brussels. I had to speak Italian. Anyway, back to the topic. My name is Grzegorz Witek. I come from Poland. I am an empty stack developer. And today I will talk to you about software design patterns. So I hope every one of you heard about software design patterns at least once and knows a few examples. But just so that, oh my God, what did I do? Oh my God, this is the last slide because it's the same as the first one. Yay, thank you. Oh no, now you know how the last slide looks like. Okay, anyway, so that we are all on the same level. Design patterns appeared for the first time. This term appeared in architecture in the late 70s. And it used to describe solutions for commonly occurring problems in architecture. And a few years later, some smart computer guys like Kent Beck started working on design patterns in computer science, in programming. And 20 years ago, almost exactly 20 years ago, in October 1994, a book was released. It was called Software Design Patterns, an element of reusable object-oriented software, something like this. And it was written by a so-called gang of four, which was a group of four scientists led by Eric Gamma, a famous scientist who works in CERN in Switzerland. And this book was a huge success. And lots of people in programming started talking about patterns, started talking about the fact that lots of problems that we have in programming appear over and over and over. And we are reinventing the wheel while we shouldn't be because we can just apply these patterns. They are confirmed solutions for these problems. And today, 20 years later, I want to review those patterns. I want to answer a few questions. Like, if it's still worth to learn these basic, this traditional gang of four patterns, are they useful in dynamic languages like Ruby? Come on, it's been 20 years. Lots of things changed during this time. I want to tell you if it's worth to read the original gang of four book. Spoiler, no, but I will explain that later. The picture that you see on the right is Berlin, seeing from the sky at night. And even though Berlin has been reunited, it's one city for more than 20 years now, you can still easily recognize which was the eastern and which was the western part, just looking at the color and the intensity of lights. So, some things change and some things remain the same during these 20 years. So, let's see how it is with design patterns. Gang of four prepared 23 patterns. Like, they didn't invent them. They just gathered the solutions that were already used. They named them, they described, they split them into three groups. The first one on the left are creational patterns. They describe solutions to creating objects. The other one on the right are structural. While the last group, it's the least concise group. It's called behavioral patterns. You don't have to remember them all. I don't remember them all. Like, probably some of them are, like, haven't been used ever in Ruby. What does pattern consist of? So, each pattern has two parts. First is descriptive, which describes the intent, applicability, the problems that we may solve with this pattern. And the other one is implementation. It consists of example code, which in original book was either in Smalltalk or C++, and class diagram, and lots of stuff like this. I promise I will not show you any class diagrams here. Don't worry, don't worry. Let's start reviewing some patterns. I will not show you all of them because I don't have enough time and some of them are really boring, but let's start. The first one is one of my favorites. It's called command, and its intent is to encapsulate a request as an object so that we can parameterize client with different requests and we can support undoable operations. The possible use case for command is implement different buttons in text editor. So, these buttons look the same. They have the same structure as an object, but they have different behavior attached to them. So, here we've got this button class and it has one method called onClick. So, when I click on this button, it executes some action. And how can I implement it? So, in more static languages like C++ or Java, what I do is I have one interface, the command interface, which has a call or execute method, and then objects that implement that interface can be provided to this button. So, I provide instances of this copy class or paste class to my buttons, but as you probably already have noticed, this is not very good solution when we are in the land of Ruby, because in Ruby we've got something like closures. Like closures are so extremely important features, even Java has it right now, even C++ has it right now. So, instead of adding another class for each type of behavior for buttons, we are just providing block of code, and it's so much simpler. And we don't need these additional classes just to use them once, which makes our code more readable, more concise. And we may think that it makes actually the command pattern obsolete. However, if we check the intent, especially the last line, we want to support undoable operations, which means that except for this call method, we need another method, undo. And of course, we can provide two prox objects to our button or lambdas. But this is not very convenient, why? Because we want the same execute method to be coupled with undo. So, if I paste the piece of text, I always want the undo method to delete that. So, in that case, it's better to create just this one class and add these two methods and don't use it as a block of code, just methods, which means that despite the fact that command pattern is a workaround for missing feature, for extremely missing feature, it still might be useful in some cases. The second pattern I want to describe is probably more well known. It's decorator and its intent is to attach additional responsibility to object during runtime. And the use case here, it might be that I want to implement preview in HTML format for my pieces of text. So, I've got this text class and then I've got this decorator, which is kind of a wrapper around object. So, decorator takes my text as an argument and later I've got this render method. So, I may have italic text decorator or bold text decorator or some other ones. And the key about decorator is that it passes messages to wrapped objects. So, I do not only overwrite methods, I pass them and then I add something on the top, which means that I can use them as the layers. So, I've got this bold text decorator which decorates italic text decorator, which decorates the text object. And, of course, we are in land of Ruby, so we have some additional features that are not present in more static languages. So, instead of wrapping objects, decorating them, I may easily extend them. I mean, it's so convenient, I just create this text object and I extend it with whatever module I have and it works in exactly the same way. So, I don't need another classes, I don't need to wrap them, I would just extend the object. Of course, it comes as a price. In Ruby, the price is performance, calling extend on text, clears some global cache, but I will not go deeper into that topic. We just need to be aware that it comes as a price. So, decorator is, again, workaround for missing feature, but what is, in my opinion, extremely important is that we're using this name all the time. So, if someone asked me about intent of some class, I just say, hey, it's decorator, even though it's not this traditional implementation. The fact that I say decorator means that my colleague from my team already knows what I'm talking about and we can communicate much easier. The same is with the third pattern that I want to describe, it's iterator. And if you haven't heard about the previous two ones, like this is something that everyone has to know. Like, iterate, we say iterate over an array. So, iterator is, its intent is to provide an access to aggregate object, to elements of aggregate object without exposing its internal structure. So, if I want to open multiple files in my text editor and I want to open the new window for each file and print the text on the screen, I will just use iterator in that case. So, what does it do? The first method, open files, iterates over the paths, over the argument, and I have no idea what it is. It might be an array, which is most obvious choice, but it might be a set, it might be some custom collection object. The thing is that I've got this each method, which is internal iterator. I don't have separate object for iteration. I just call this method each on the paths and I provide each element to a block. And then I've got the second method called open file and this is example of external iterator, which means that this file, this variable is an iterator object. So, I run manually this while loop and every time I check, is it end of file? If not, then I go again. Is it end of file? If yes, then I skip it. And this method read line on file does two things. First, it returns another line of text from file, but second important is that it moves the cursor to another line. So, that's how iterator works. And needless to say, it's like this is core of many languages. It is available in standard libraries or in the core code of the language. So, iterator proved to be extremely important, which is not the case in another pattern. Singleton, it's like it's very infamous pattern. It ensures that we've got just one instance of an object and provide a global point of access to it. If you get nervous when you see this global point, that's right, that's good. So, use case for Singleton is like we've got settings object. We always want just one instance of settings for our application. And the very naive implementation of Singleton is just to make new method private and then have some other method that we'll call this new, but just once. And every next time it will return existing instance. We've got Singleton in Ruby standard library, so we don't have to implement it on our own. That previous implementation was very basic and there are tens of ways to break it. So we've got this more advanced implementation in Ruby standard library, which works, unless we decide to have some fun with that. So like, okay, there is nothing is private in Ruby. So I can call this method and yay, I've got new object. So deal with it, like it's not a real Singleton. I can do some more crazy stuff, like I can assign object class to settings and then I break the whole, probably in the whole application. Like I will get some warnings here but who cares about warnings, come on. Probably most of you don't even run the test with warnings flag, no. And another thing that I can do is I can use just global variable because if I can break Singleton in a number of ways, what's the difference between having a Singleton class and having just global variable? So they are, in my opinion, they are equally wrong. So Singleton, even though it is available in standard library, it is considered anti-pattern by the community. And features that are available in Ruby make it even less useful. So let's just decide that Singleton is an anti-pattern. It used to be described as a pattern but later, a long time, people decided that it shouldn't be used in our applications. The fifth pattern I want to talk about is Observer. So when you've got this one too many relation between object, that when an object changes its states and other should react to that, the solution proposed by Gang of Four is Observer. And for example, in text editor, when I have styles applied to some pieces of text and I change styles, each part of text should react to that change. So once again, very basic implementation is that I've got this method NotifyObservers, which iterates over Observers and calls NotifyMethod on each of them. And Observers should be able to register themselves to observe such object. And then of course, we've got this Observer object that registers itself and then responds somehow to NotifyMethod. And we don't need to write such code because once again, Ruby standard library has observable library and we just need to call this method change and then notify Observers. And that's it. It's totally enough. So Observer is available in standard library but once again, just like Singleton, it's not so obvious that it's anti-pattern but because of the coupling between the Observer and observable objects, it is considered obsolete. Like we should use something better like publisher subscriber that decouples Observer and observable objects. And there are a few more patterns that implement that solve this problem of having this one-to-many relation. So Observer is available in standard library but we shouldn't use them. Actually in Ruby on Rails, it used to be part of the core but it was moved to external gem because no one used it. Then we have a few patterns that almost no one talks about but everyone uses. So template method. I haven't heard about this name very often but if you have a method that calls a few different methods and in subclasses you override these smaller methods then you use the pattern. It's called template method. It's with us for 20 years. Like who would think that it has a name? It's so obvious. So it's example that everyone uses but nobody calls it template method. On the other hand we've got adapter. Like everyone knows the name adapter. The most common case I think is when we've got different databases we need to talk to different SQL dialects. So we have adapter for each of them. And in this case we use them very often and we know this name. We call these classes adapters. So when I see the name of a class I already know what's its intent. It's not only domain name of the class but also it describes its structure. Then again we've got bridge and bridge is something that I have never heard about. Like I have never seen it in real code. At least not called bridge. And this pattern is basically if you've got one-to-one relation and it's an abstract relation. So it's like polymorphic on both sides. If one part of relation, if one side can be abstract and the other can be abstract, that's a bridge. So it's used commonly and nobody calls it a bridge. And the last one I want to talk about is called facade. I don't really know. Some people pronounce it facade but facade sounds like facade. Like you know, so much better. And when you read the descriptions access or it provides a unified interface to a set of interfaces in a subsystem. But this sounds really serious but what facade is, basically if you have a few classes and it's complicated to use them, you just write one class with simple interface that uses the other ones and we've got facade. So once again, it's used all the time. Everyone uses that but nobody uses the name facade. In Ruby community we don't like design patterns. We don't talk about them a lot. And I was wondering when I was writing my master thesis about design patterns, I was wondering why? And I came up with a few reasons. First is that they are solutions to non-existent problems. So like as we saw some of them, we just, we don't need these patterns in Ruby. In Ruby, this language is so flexible. We've got closures. We can use classes as the values. We can assign a class to variable. It's something that when I use C++ or Java I couldn't even think about. And then they remind us of these static languages. So like when I think design patterns, I think, oh my God, so I have to write this class diagram and it will probably be like seven classes tied together and I don't even know why. And the third reason is that some of these patterns are overused. So there is this syndrome like when you learn how to use the hammer you see nails everywhere. And lots of people have this with design patterns. So they don't look for a solution to a problem. They just look for a problem that they know solution for. So they learn these 23 patterns and then they look for like, where can I use it? Where can I use it? But it's of course not the way to go and that's why Ruby community doesn't really like these patterns. And some of them like when we think about these patterns that I talked about, when we think about what happened with them after these 20 years, we see that some of them are considered harmful like Singleton and Observer. And when I read interview with Gang of Four which was like done three years ago, they presented some new patterns and they said that they would like to get rid of some of them and Singleton and Observer were those two. So it means that they are not perfect and even in languages like Java or C++, these are not the patterns that should be used. Some of them are totally useless in languages with certain features like abstract factory. Like this is basically workaround for the missing feature that you cannot use class as a value. If you can do it like in Ruby, there is absolutely no need to use abstract factory. Then some of them are deprecated and some of them are useful but in very, very rare cases. However, when we see at the other part, we have patterns that are very, very useful. So we've got iterator. We've got some that are, this is not a good example. Like in Starter Library, we've got Observer and Singleton. Like I don't know why we have just these two patterns in another library, they are deprecated. Nobody should use them. And we've got some that are very commonly used as adapter or decorator. And what's in my opinion most important is that some of them are used for communication purpose. And this is for me the biggest value of design patterns. So implementation is different than it used to be in other languages. But the name remains the same. The intent, the problem that we are solving remains the same. So if I say that something is decorator or iterator, my colleagues already know what I'm talking about. And that's why I think that we actually need more patterns. And I don't mean that we need patterns like presented in Gang of Four book. No, we don't need patterns that solve problems in Java or C++. We need more patterns that solve problems in Ruby. So we don't need design patterns in Ruby, but we need Ruby design patterns. Because they facilitate communication. And actually there are a few patterns that weren't, that didn't make into this book, but we use them quite commonly, like null object or dependency injection. There are a few patterns that were added later, like extension or type object, which are not very common, but still they solve problems and they can be used for communication. I think that in Ruby we miss patterns, or I don't know, maybe we should call them practices. We are missing best practice or patterns for metaprogramming and DSLs. We use lots of metaprogramming. We write lots of DSLs. And some of them are excellent. Some of them are nearly perfect. And some of them, when we see their code, we regret that we opened that file. So I mean that we should have some confirmed ways of designing these DSLs or using metaprogramming. We shouldn't abuse it, but we should use it and we should agree on some way, where is it okay and where it's not okay to use them. If you want to learn a bit more about design patterns, there are a few resources. First is design patterns in Ruby. It's a book written by Russ Olson and it covers I think 14 or 16 out of these 23 patterns. It's really interesting. In contrary to the second position, which is the original Gang of Four book. And as I told you in the beginning, I don't think it's worth reading it. I read it cover to cover when I was writing my master thesis. And when I finished it, I was like, I should got my master degree just because I finished that book. The first part of this book covers some pitfalls and problems with object-oriented software and it's really cool. But then the second, the big part, describes the pattern and it's full of code example in Smalltalk and C++. It's full of class diagrams and really, really boring descriptions. The third resource is a talk from last year Barucho by Corey Haines. It was a bit more general, but it was great inspiration for me to prepare this talk. And the last one, if you know this Wiki, if you know c2.com Wiki, you know it's value. And if you haven't seen that page, just go there. It's extremely interesting. This is the place where lots of discussions about design patterns took place. So that's all for today. Thank you very much for listening and enjoy the rest of conference. Thank you.