Very nice explanation and demonstration of the decorator pattern. And going the next step of Kotlin-izing it was very useful. I think an updated GOF book is in order with modern implementations.
Thanks so much, Guy! Yes, it sounds like there's some interest in the topic of applying design patterns in a more modern context. Not sure yet whether I'd be the one to write that book, but I think you're on to something there! 🙂
Thanks so much, Houssam! Yes, I'm starting to really appreciate functional interfaces. I love how they let you add a meaningful domain type on top of the basic function type, and without much code.
7:40 The abstract class was actually useful, because it had a single reference to the instance. Now each decorator has its own, and you need to also write the same for each new decorator. Also, it seems that no matter which way you want to use the decorator here, you are making new rules of how to use them. There is no place here to set the order in a fixed way, so depending on how you create each instance of a decorator, you will get a different output. It's also a good thing as it gives the user of the decorators more control. Just less control to the one creating the original class that you choose to decorate. I remember there are also annotations that you can add to classes. Can those also help with decorators?
Hey, thanks for reaching out, Liran! Yes, if you like the single reference, the abstract class does give you that benefit. And if you need a parent type just for the decorators (i.e., excluding the concrete components), it can give you that as well. I'd probably find the single reference benefit more advantageous in languages with a more verbose syntax. In Kotlin, it's just so doggone easy to add "val" to a constructor parameter (or even "private val", as I did in the video) - it's actually less syntax overhead than extending a class and relaying the parameter to it. Good thought on the order. In the example code, the decorator itself decides whether it'll insert content before or after the underlying `message`, but otherwise, the call site gets to dictate the order. Might or might not be what you'd want, depending on the situation. For other problem spaces, each decorator might always have a predictable effect, regardless of the order that they're applied in. About annotations - are you thinking of any annotations in particular? I haven't personally come across any that were designed to be used with a decorator pattern, but I suppose it'd depend on the framework providing the annotation.
Great video again, Dave! Your videos are always very informative, and I always learn something new from each one. I never fully understood design patterns, but with each of your videos on the topic , especially with the magic of Kotlin (P.S. I love Kotlin), they are becoming much easier to grasp . I hope you continue the good work!
I also have to look twice if the order/format is correct. But it looks like that's a characteristic of the decorator pattern to carefully connect all the wrappers aka features in the right order.
How does "unique id" printed after "date&time" and before "application initialized"?)) if this called as last extension, haven't it to be at the begining of the full log message? Update: finally got it, it starts collecting message reversely from the latest extension. Thanks a lot for the video!
Thanks, Otar! A few folks have asked for that now. I've got quite a lot of customization of my keyboard shortcuts, plus I usually end up needing to smooth over typos and bloopers after recording, so I haven't turned on presentation assistant yet. But most of it boils down to using multiple cursors. Since there's been some interest in it, I'm thinking I might just make a video about how to use them effectively.
Perfect explained ❤ I have a configuration class that's by itself doesn't do any changes, but it's used as a configuration for another block of code to implement it. I implemented to be created using DSL way, since it doesn't do any functionality by itself, do you think DSL way is better than this one for this use-case? And thanks again ❤
Hey, thanks so much! Yes, for constructing a configuration object, I would generally use a builder DSL in Kotlin, since it gives some good control around which elements are required, which are optional, which can have more than one value, which ones contain nested elements, and so on. Decorators are more focused on behavior, and since your configuration object has no behavior of its own, a builder DSL would be a more natural fit.
@@typealias another request, if you please You are using amazing shortcuts sometimes, such as the cursor multi-selection, can you please enable the presentation assistant in the settings so we can know what are these shortcuts. And thanks again ❤
woudl be a good example for compose something like this? interface Button class FilledButton : Button class TextButton : Button abstract class IconDecorator(button: Button): Button class LeadingIcon(button: Button) : IconDecorator(button) class TrailingIcon(button: Button) : IconDecorator(button)
The original Design Patterns book uses UI as its example for the Decorator Pattern - a text box that's decorated with a border, and also decorated with the ability to scroll, so it can be a good fit, depending on the tooling. When using class-based UI tooling, I'd expect something a little more like LeadingIcon(icon, Filled(color, Button(onClick, text, etc))) or maybe Button(onClick, text, etc).filled(color).leadingIcon(icon). I think you've got the main idea - but you'd want to make it a ButtonDecorator. Now, if you're referring to the actual Jetpack Compose / Compose Multiplatform tooling, its structure certainly makes it more natural to work with functions for this kind of thing, rather than classes. The idea of one `@Composable` function calling another, which calls another - that's effectively decorating. You can also see some similarities with the `Modifier` in Compose - in fact, the fluent approach above (Button(...).filled(...).leadingIcon(...)) has a very similar shape and purpose as chaining function calls on the `Modifier` object.
Well, the purpose of the decorator is to allow you to change the behavior of a function dynamically without class extension. A collection operator chain like you're talking about would work similarly in that it'd make incremental transforms to the data that it starts with. But the reason I wouldn't consider them decorators is that they aren't creating an object that can be called multiple times - when you call them, they return a result rather than an object that can return a result. With the logger example at the end of this video, the fluent function calls are creating something that you can call later. Hope that makes sense!
Hello Dave. I would like to become a Kotlin and Android Studio developer. I started with Google codelabs to start understanding the language. My issue is that I never programmed and I have no knowledge of logic. I can still continue or it will be a waste of time if I don't have a programming background. And if so, what do you recommend to start? I am 44 years old and even if it is not for the job market I want to learn for myself. Thank you very much for your time.
Hey, that sounds great! Everyone starts somewhere, and you don't need a logic background to get going. As long as you've got an excitement about programming, and as long as you're willing to take time to learn things, you'll do fine. I'm almost done authoring a book about Kotlin, and my aim was to make it accessible, even to those without a programming background. You can read it online here: typealias.com/start/ I hope that helps you get started!
Hi Azmo! The patterns I'm covering are catalogued in "Design Patterns: Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson, and Vlissides, published by Addison-Wesley. It's a classic - it popularized the concept of design patterns in the software development world.
Yes, for developers who aren't already familiar with the approach, it can require some thought to figure it out. Ultimately, it's really just function composition using extension functions, where each Logger calls the previous in the chain until it gets to the underlying `consoleLogger`. So, the function created by withUniqueId() calls the function created by withThreadName(), which calls the function created by withDateTime(), which calls the function assigned to consoleLogger.
I really like the way you describe the kotlin features. Nice work
Low-key best Kotlin related channel I've ever found.
Great explanation. Every time I watch your videos, I learn something new about the Kotlin language.
Kotlin is great, and so is your way of delivery!
I like the topic of Design Patterns, especially with your demonstrations!
Thank you so much, Sergey! I'm glad there's been so much great interest in the topic. I'll keep at it!
Very nice explanation and demonstration of the decorator pattern. And going the next step of Kotlin-izing it was very useful. I think an updated GOF book is in order with modern implementations.
Thanks so much, Guy! Yes, it sounds like there's some interest in the topic of applying design patterns in a more modern context. Not sure yet whether I'd be the one to write that book, but I think you're on to something there! 🙂
Great video as usual!
Really love functional interfaces, very neat and concise to implement.
Thanks so much, Houssam! Yes, I'm starting to really appreciate functional interfaces. I love how they let you add a meaningful domain type on top of the basic function type, and without much code.
7:40 The abstract class was actually useful, because it had a single reference to the instance. Now each decorator has its own, and you need to also write the same for each new decorator.
Also, it seems that no matter which way you want to use the decorator here, you are making new rules of how to use them. There is no place here to set the order in a fixed way, so depending on how you create each instance of a decorator, you will get a different output. It's also a good thing as it gives the user of the decorators more control. Just less control to the one creating the original class that you choose to decorate.
I remember there are also annotations that you can add to classes. Can those also help with decorators?
Hey, thanks for reaching out, Liran! Yes, if you like the single reference, the abstract class does give you that benefit. And if you need a parent type just for the decorators (i.e., excluding the concrete components), it can give you that as well. I'd probably find the single reference benefit more advantageous in languages with a more verbose syntax. In Kotlin, it's just so doggone easy to add "val" to a constructor parameter (or even "private val", as I did in the video) - it's actually less syntax overhead than extending a class and relaying the parameter to it.
Good thought on the order. In the example code, the decorator itself decides whether it'll insert content before or after the underlying `message`, but otherwise, the call site gets to dictate the order. Might or might not be what you'd want, depending on the situation. For other problem spaces, each decorator might always have a predictable effect, regardless of the order that they're applied in.
About annotations - are you thinking of any annotations in particular? I haven't personally come across any that were designed to be used with a decorator pattern, but I suppose it'd depend on the framework providing the annotation.
Thanks a lot. Kotlin is beautiful, and you make it so easy to understand.
It is a really successful interpretation of the GOF decorator pattern with Kotlin means.
Thanks for sharing your knowledge.
Thanks! I’d like to see more patterns modernised by you
Keep going!
Sounds good! I'm glad you're enjoying the topic. I'll keep at it! 👍
Great video again, Dave! Your videos are always very informative, and I always learn something new from each one. I never fully understood design patterns, but with each of your videos on the topic , especially with the magic of Kotlin (P.S. I love Kotlin), they are becoming much easier to grasp . I hope you continue the good work!
That's great to hear! I'm so glad you're finding them helpful. I'll keep at it! 👍
Thank you for this informative video on the Decorator Pattern in Kotlin. Your explanations were very helpful and practical.
Thanks Dave, your videos are always informative and I have learned something each time I watch yours.
Thank you so much! I'm so glad you're enjoying them!
I really love the Modernized implementation for kotlin section actually😃. Thank you very much for the great content as always🙂.
Fantastic explanation ❤
Very well explained.
Really love modern decorator!❤
Explanation is nice. Keep it up.
Love the way you explain step by step.More great videos like this!
Thanks so much, Sheen! I'll keep at it!
Another great video! 👌
Great! Are you going to make more videos about design patterns?
PLEASE!
There's been lots of great interest in the topic, so I'll keep at it! 👍
great video as usual 🎉
Thanks!
Hey, thank you so much, Konstantin! I really appreciate that!
@@typealias You deserve it! Your videos are excellently produced. Super concise, easy to follow and you provide just the right amount of context!
Excellent presentation! It would be great if you could do something about context receivers and compare them with typeclasses
Thanks so much! I'll add that to my running list of video ideas!
good one, looking forward to a design patterns series covering all the design patterns in kotlin :)
Such a beautiful video ❤. Thank you so much for the wonderful work.
Thanks so much, Paulo!
Excellent video, but am I alone in being confused regarding the ordering of the log operations related to the final format?
I also have to look twice if the order/format is correct.
But it looks like that's a characteristic of the decorator pattern to carefully connect all the wrappers aka features in the right order.
How does "unique id" printed after "date&time" and before "application initialized"?)) if this called as last extension, haven't it to be at the begining of the full log message?
Update: finally got it, it starts collecting message reversely from the latest extension.
Thanks a lot for the video!
Can you enable presentation assistant to your videos? Delivery and content are really awesome but IDE skills is also next level
Thanks, Otar! A few folks have asked for that now. I've got quite a lot of customization of my keyboard shortcuts, plus I usually end up needing to smooth over typos and bloopers after recording, so I haven't turned on presentation assistant yet. But most of it boils down to using multiple cursors. Since there's been some interest in it, I'm thinking I might just make a video about how to use them effectively.
Impressive!
Perfect explained ❤
I have a configuration class that's by itself doesn't do any changes, but it's used as a configuration for another block of code to implement it.
I implemented to be created using DSL way, since it doesn't do any functionality by itself, do you think DSL way is better than this one for this use-case?
And thanks again ❤
Hey, thanks so much! Yes, for constructing a configuration object, I would generally use a builder DSL in Kotlin, since it gives some good control around which elements are required, which are optional, which can have more than one value, which ones contain nested elements, and so on. Decorators are more focused on behavior, and since your configuration object has no behavior of its own, a builder DSL would be a more natural fit.
@@typealias Thanks for the great answers
@@typealias another request, if you please
You are using amazing shortcuts sometimes, such as the cursor multi-selection, can you please enable the presentation assistant in the settings so we can know what are these shortcuts.
And thanks again ❤
11:29 Can you show the code snipet?
woudl be a good example for compose something like this?
interface Button
class FilledButton : Button
class TextButton : Button
abstract class IconDecorator(button: Button): Button
class LeadingIcon(button: Button) : IconDecorator(button)
class TrailingIcon(button: Button) : IconDecorator(button)
The original Design Patterns book uses UI as its example for the Decorator Pattern - a text box that's decorated with a border, and also decorated with the ability to scroll, so it can be a good fit, depending on the tooling. When using class-based UI tooling, I'd expect something a little more like LeadingIcon(icon, Filled(color, Button(onClick, text, etc))) or maybe Button(onClick, text, etc).filled(color).leadingIcon(icon). I think you've got the main idea - but you'd want to make it a ButtonDecorator.
Now, if you're referring to the actual Jetpack Compose / Compose Multiplatform tooling, its structure certainly makes it more natural to work with functions for this kind of thing, rather than classes. The idea of one `@Composable` function calling another, which calls another - that's effectively decorating. You can also see some similarities with the `Modifier` in Compose - in fact, the fluent approach above (Button(...).filled(...).leadingIcon(...)) has a very similar shape and purpose as chaining function calls on the `Modifier` object.
Thanks.
Based on this, operator functions like filter, map and find, all are using decorator pattern under the hood.
Well, the purpose of the decorator is to allow you to change the behavior of a function dynamically without class extension. A collection operator chain like you're talking about would work similarly in that it'd make incremental transforms to the data that it starts with. But the reason I wouldn't consider them decorators is that they aren't creating an object that can be called multiple times - when you call them, they return a result rather than an object that can return a result. With the logger example at the end of this video, the fluent function calls are creating something that you can call later. Hope that makes sense!
@@typealias thanks for the dedicated reply.
Thx a lot, very interesting but too high level for me ^^
Hey, thanks so much - I appreciate the feedback!
Hello Dave. I would like to become a Kotlin and Android Studio developer. I started with Google codelabs to start understanding the language. My issue is that I never programmed and I have no knowledge of logic. I can still continue or it will be a waste of time if I don't have a programming background. And if so, what do you recommend to start? I am 44 years old and even if it is not for the job market I want to learn for myself. Thank you very much for your time.
Hey, that sounds great! Everyone starts somewhere, and you don't need a logic background to get going. As long as you've got an excitement about programming, and as long as you're willing to take time to learn things, you'll do fine.
I'm almost done authoring a book about Kotlin, and my aim was to make it accessible, even to those without a programming background. You can read it online here: typealias.com/start/ I hope that helps you get started!
🔥
On which book of this based on?
Hi Azmo! The patterns I'm covering are catalogued in "Design Patterns: Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson, and Vlissides, published by Addison-Wesley. It's a classic - it popularized the concept of design patterns in the software development world.
I can't wrap my head around about final kotlinish form
Yes, for developers who aren't already familiar with the approach, it can require some thought to figure it out. Ultimately, it's really just function composition using extension functions, where each Logger calls the previous in the chain until it gets to the underlying `consoleLogger`. So, the function created by withUniqueId() calls the function created by withThreadName(), which calls the function created by withDateTime(), which calls the function assigned to consoleLogger.
💪💪💪
😲