Your channel is absolutely brilliant! The delievery, the pace, lack of flashy distractions, and very clear explanations. Thank you from the bottom of my heart!
Series on design pattern and amalgamation of kotlin is what I needed the most. I have never understood the statement "encapsulate what varies" but now I would always remember "extract what differs". Keep up the good work Dave! Thanks for the video
That's fantastic, Vivek! Sounds like lots of Kotlin developers have been interested in the topic, so I'm glad these videos are resonating well. I'll keep at it!
I really like how this code looks after your refactoring. But I see one potential drawback. Before to create a concrete implementation of FormField you just needed to call the constructor and the validator is built-in. Now you need to make sure that you pass an appropriate validator for your field, and from my opinion this is error-prone, especially in the production. We might solve this problem by introducing a Factory or something similar combined with your refactoring but, again, we will get more code. What do you think?
Hey Ilian, thanks for reaching out! I think I understand what you're getting at - the earlier approach had an actual type (e.g., EmailValidator vs. UsernameValidator) whereas by the end, they're all just the same type - (String) -> Boolean, and we'd have to be careful to use the right validator on the right kind of value. If we want the compiler to enforce that, I'm thinking we could still keep the latter approach, but might consider using simple value classes for the types, and generics for the validators. Maybe something like this: ``` interface Value { val value: String } @JvmInline value class Email(override val value: String) : Value typealias Validator = (T) -> Boolean val emailValidator: Validator = { it.value.contains("@") && it.value.contains(".") } class FormField(val name: String, val value: T, private val validator: Validator) { fun isValid() = validator(value) } fun Validator.optional(): Validator = { it.value.isEmpty() || this(it) } ``` I only included the value class for Email in the code here, but same idea for the Username and Password. This wouldn't add too much code, and having strong types for those values would usually be a good idea anyway!
Thank you for this great content! It's an excellent start for a design patterns series. The video on the Strategy Pattern in Kotlin is informative and well-presented. Combining theory with practical Kotlin examples, this approach sets a strong foundation for an educational series on design patterns. Keep up the good work
Would be cool if you could show what shortcuts you are using during the presentation (I think it's called Presentation Assistant). Curious about the multi select + search...
I've customized my keyboard shortcuts quite a lot, so I'm sure I'd be lost if I started typing on someone else's installation of IntelliJ. 😅 But yes, the multi-caret feature is really useful! I most often use "Add Selection for Next Occurrence", which I think is Alt+J by default. You can also click and drag while holding down Alt if you just want a caret on each row. And there's also Alt+Shift+Click to add a caret wherever you click.
In Kotlin, I find myself making only data classes and functions and deriving interfaces only to object declarations. This seems to be a happy place; data and functions, OOP is a very minor part of it.
Great to see my favourite topic comming often! I am getting goose bumps when I see professionals like you being so good at explaining concepts in a very neat, simple and understandable way. Thank you very much Sir😊.
@@typealias I'm very curious about what comes next ;) The visitor pattern is another one that transforms tremendously with the flexibility of the language.
Yes! I had actually started working on the video for the visitor pattern before this one, but it was possible to take the visitor pattern in quite a few different directions, with a variety of different data types that it might operate on. So I decided to put it on the back burner until I had a little longer to mull it over. 🙂 Definitely looking forward to that one, though!
The Strategy pattern is one of those patterns that automatically emerge if you factor out, as you said it, only the stuff that is different. In general, the most useful patterns are the ones you constantly use or implement without realising it. Now, about monads...
I'm currently writing C# in my day job and I wish I could end up with code similar to your final Kotlin version yet C# does not support "top level functions". Another thing to keep in mind is that in your class based version you could instantiate the same validator even tough it makes no sense since as you said they have no state at all. You most likely want to use `object` rather than `class` if you want to keep the class based approach.
Thanks for the great explanation. Given the classic strategy pattern, that would mean you still have to implement the optional variants e.g. OptionalUsernameValidator, right? class OptionalUsernameValidator: Validator { override fun isValid(value: String) = value.isEmpty() || value.isNotEmpty() }
Your explanation was good but if you had given us more examples it would be awesome. but hey the tricks that you give us to ease our kotlin coding are unique and smart.
Pokemon-card syndrome. When you can't infer the meaning of a term from the actual words, it's already a smell that you're in an overhead/buzzword-driven science culture. OOP is such a crippled world.
Yeah, it seems like many of the terms and phrases that stuck were rooted in a context that's been lost now. For example, I'm sure "inversion of control" made sense at the time, but once it became a more common practice, it's no longer an "inversion". It's sometimes also called the Hollywood Principle - "don't call us; we'll call you". I'm sure that idea works great if you can remember who is "us" and who is "you", but I never can 😁
Your channel is absolutely brilliant! The delievery, the pace, lack of flashy distractions, and very clear explanations. Thank you from the bottom of my heart!
Oh wow, thank you so much! I'm really glad you're enjoying it!
Ok, now I need - Design Patterns in Kotlin: An illustrated guide!! 📖📖
Haha, I don't know if I'm ready to start another book just yet, Luis! 😅 But it's a fun idea! 😁
Your content is extremely valuable for teaching my trainee. 👌👍
That's so great to hear, Stefan! 🎉
Series on design pattern and amalgamation of kotlin is what I needed the most. I have never understood the statement "encapsulate what varies" but now I would always remember "extract what differs".
Keep up the good work Dave!
Thanks for the video
That's fantastic, Vivek! Sounds like lots of Kotlin developers have been interested in the topic, so I'm glad these videos are resonating well. I'll keep at it!
Wow, you are awesome! That's a very smooth way of teaching.
Thank you so much, Guillermo!
I really like how this code looks after your refactoring. But I see one potential drawback. Before to create a concrete implementation of FormField you just needed to call the constructor and the validator is built-in. Now you need to make sure that you pass an appropriate validator for your field, and from my opinion this is error-prone, especially in the production. We might solve this problem by introducing a Factory or something similar combined with your refactoring but, again, we will get more code. What do you think?
Hey Ilian, thanks for reaching out! I think I understand what you're getting at - the earlier approach had an actual type (e.g., EmailValidator vs. UsernameValidator) whereas by the end, they're all just the same type - (String) -> Boolean, and we'd have to be careful to use the right validator on the right kind of value.
If we want the compiler to enforce that, I'm thinking we could still keep the latter approach, but might consider using simple value classes for the types, and generics for the validators. Maybe something like this:
```
interface Value { val value: String }
@JvmInline value class Email(override val value: String) : Value
typealias Validator = (T) -> Boolean
val emailValidator: Validator = { it.value.contains("@") && it.value.contains(".") }
class FormField(val name: String, val value: T, private val validator: Validator) {
fun isValid() = validator(value)
}
fun Validator.optional(): Validator = { it.value.isEmpty() || this(it) }
```
I only included the value class for Email in the code here, but same idea for the Username and Password. This wouldn't add too much code, and having strong types for those values would usually be a good idea anyway!
@@typealias Thank you VERY much for the detailed answer.
Thank you. I like how you start simple and evolve the code from java like to Kotlin specific. Design patterns are always a good subject.
Thanks, Guy! Yes, there were enough viewers asking me to cover design patterns that I couldn't say no. 😅
Thank you for this great content! It's an excellent start for a design patterns series. The video on the Strategy Pattern in Kotlin is informative and well-presented. Combining theory with practical Kotlin examples, this approach sets a strong foundation for an educational series on design patterns. Keep up the good work
Thanks so much, Mohammad! I'll keep at it! 👍
You explain very well, I'm very glad I found you!
Thanks so much, Ramazan! I'm glad you're here!
Would be cool if you could show what shortcuts you are using during the presentation (I think it's called Presentation Assistant).
Curious about the multi select + search...
I've customized my keyboard shortcuts quite a lot, so I'm sure I'd be lost if I started typing on someone else's installation of IntelliJ. 😅 But yes, the multi-caret feature is really useful! I most often use "Add Selection for Next Occurrence", which I think is Alt+J by default. You can also click and drag while holding down Alt if you just want a caret on each row. And there's also Alt+Shift+Click to add a caret wherever you click.
amazing and informative as usaul! Thanks so much Dave. You always rock
me!
Your content is very valuable; keep going!
In Kotlin, I find myself making only data classes and functions and deriving interfaces only to object declarations. This seems to be a happy place; data and functions, OOP is a very minor part of it.
That's a great approach! I do love that Kotlin doesn't box us in to one paradigm or another.
I stopped crying on this video, when I read your comment. Thanks God, we are not the only ones who uses Kotlin the same way.
Useful breakdown
Great to see my favourite topic comming often! I am getting goose bumps when I see professionals like you being so good at explaining concepts in a very neat, simple and understandable way. Thank you very much Sir😊.
You are most welcome! More videos for this topic coming soon! 👍
This was a great video with high quality content, keep posting, the channel should boom soon.
Thank you, Vaibhav! I'm having a great time creating these videos, and I'm really glad others are finding them helpful!
Great content!
Thanks so much, Anton! I appreciate that!
@@typealias I'm very curious about what comes next ;) The visitor pattern is another one that transforms tremendously with the flexibility of the language.
Yes! I had actually started working on the video for the visitor pattern before this one, but it was possible to take the visitor pattern in quite a few different directions, with a variety of different data types that it might operate on. So I decided to put it on the back burner until I had a little longer to mull it over. 🙂 Definitely looking forward to that one, though!
The Strategy pattern is one of those patterns that automatically emerge if you factor out, as you said it, only the stuff that is different.
In general, the most useful patterns are the ones you constantly use or implement without realising it.
Now, about monads...
Haha, yeah! I might get into more FP approaches at some point.
3:47 What the heck happened? Can you explain how to do it
Amazing :) keep up the great work
Loved it!
Hi Dave, your content is awesome, totally loved it, Can you please make a video on MVVM architecture pattern? Thanks a ton :)
Thanks so much, Nahal! I'll add MVVM to the list of ideas for future videos!
Your video is just a one place to go - if you want to be a good software developer! Thank you!
I'm currently writing C# in my day job and I wish I could end up with code similar to your final Kotlin version yet C# does not support "top level functions".
Another thing to keep in mind is that in your class based version you could instantiate the same validator even tough it makes no sense since as you said they have no state at all. You most likely want to use `object` rather than `class` if you want to keep the class based approach.
Looking forward to seeing more videos
Thanks for the great explanation. Given the classic strategy pattern, that would mean you still have to implement the optional variants e.g. OptionalUsernameValidator, right?
class OptionalUsernameValidator: Validator {
override fun isValid(value: String) = value.isEmpty() || value.isNotEmpty()
}
Good video!
You are the King of Kotlin!
Thank you, Aliaksandr! That's kind of you to say!
Your explanation was good but if you had given us more examples it would be awesome. but hey the tricks that you give us to ease our kotlin coding are unique and smart.
Hey, thanks for the feedback, Mike! 👍 I appreciate it!
Gold content.
Ha-ha, yes! I knew this video was going to have a "fun" twist!
Haha, yeah! Sounds like you figured out where I was going with it! 🙂
Gold 🤑
Pokemon-card syndrome. When you can't infer the meaning of a term from the actual words, it's already a smell that you're in an overhead/buzzword-driven science culture. OOP is such a crippled world.
Yeah, it seems like many of the terms and phrases that stuck were rooted in a context that's been lost now. For example, I'm sure "inversion of control" made sense at the time, but once it became a more common practice, it's no longer an "inversion". It's sometimes also called the Hollywood Principle - "don't call us; we'll call you". I'm sure that idea works great if you can remember who is "us" and who is "you", but I never can 😁