I've gotten a lot out of your videos and I'm really happy to see the addition of UML diagrams. I've been learning more about design patterns (after discovering them through your videos) and UML diagrams have been really helpful for my visual learning brain. I'd love to see you revisit some of your old design pattern videos and give a UML overview!
I love the way you presented the use case in this video. Normally your explanation involve going through the code. This video's method of presenting what we want to do and then asking how do we do it made it so much easier to understand and to focus. Thanks Arjan!
I really love your videos on design patterns and have been following them for a while. I've really begun understanding a lot about software design and have been trying to implement good practices wherever possible. Thank you so much! If it interests you, I would love to hear your opinions on using design patterns in frameworks like Django
By far the best explanation I've seen of the Bridge Pattern. Looking at the UML diagram from the book I was so confused I essentially wrote off this pattern as being something I probably wont understand. 😂 Awesome to see this explained in a reasonable way. Keep up the great work man. Love the videos.
Awesome, like all of your videos! When implementing some functions of the superclass and the rest in child classes, isn’t that in conflict with the concept of loose coupling and high cohesion?
As someone that uses typing quite a bit I know it seems quite esoteric to some python programmers. Would you consider a video on typing in python? I think it's something that most people don't use or are not taught.
I can definitely see the appeal of the bridge pattern. This is a video I can see myself revisiting when I start refactoring for sure. It seems like I should look into your abstract factory video soon as well. By the way, great talk at ELU!
Hi @ArjanCodes , thank you so much for your videos. Is there any tool to create the base classes from the mermaid markdown file? Or the opposite, generate a mermaid markdown scanning a project?
The code reviewers make a *huge* difference in the quality of the videos. Having those extra pairs of eyes go over the code before filming really helps weed out a lot of issues - the kudos are well deserved!
Not sure if this is mentioned somewhere, but what are you using for your intellisense/code complete extension? That looks a bit more robust than what I'm currently using, it seems quite useful
I don't really like replacing the device classes with functions. It might simplify the code, but those classes could probably contain some state. By using functions, we deprive ourselves of the ability to store and use state. It's not obvious in the example above, but if you do the actual implementation, it becomes a problem. Anyway, thanks for the video. It became more obvious to me in which cases it's more practical to use ABC instead of protocols 👍
Glad the video was helpful! Actually, the switch to functions still allows having a device class with state. As long as that device class contains a method that returns buffer data, you can create an instance my_device of that class (containing any state you like), and then you can add my_device.get_buffer_data to the streaming service.
I follow a lot of your video especially from the playlist "Software design in Python". It's not very clear for me what is the difference between the bridge pattern and the strategy pattern. I read some stuff and it comes like "Strategy pattern is meant for behavior, the Bridge pattern is meant for structure." I think, it would be better to show the difference with a concrete example. What do you think?
Hi Arjan I have coding problem relating to classes and inheritance. Basically what I want to know is how to inherit multiple traits. Lets say I am making a RPG game where you can play as a character that has a race and a class. Lets say that there are 3 races and 6 classes, resulting in 18 possible combinations that are each played differently. I would say it makes sense to write one 'Character' class that sets up a basic framework, and then use inheritance to specify the details each race/class combination. My problem is that I have two traits (race and class) that each inherit from 'Character'. Of course, I dont want to write separate classes for all the 18 different combinations. So my question comes down to how I should design my code? I would like to have separate spaces for my code about classes and races, and I am looking for an easy way to use this to build a character.
Check Arjan's video on composition over inheritance. The solution is to have a single Character class, which contains a class object and a race object.
Hi, that’s hard to say. It depends very much on the type of package what kind of design pattern is most appropriate. I’d suggest to not worry too much about how often a design pattern is used. If it fits a type of problem you need to solve, try it out and see if it works for your use case.
What I have understood by reading Clean Architecture book: Web development is part of detail / delivery mechanism of your software system, You should forget that you have to serve it as a web app while making the main code (policy). It should be such that you can simply plugin the web code, console code, etc
Arjan is correct. You should use the pattern that is most appropriate. Having said that, I would opine the adapter pattern is the most commonly used in web development. I use adapters all the time to provide abstraction between my repository schema and business models. I typically use pydantic models for the business use cases. Each use case that interacts with a database is given a repository instance as an argument. The repository may store data in MongoDB, Postgres, Redis, etc., so their individual schema will often differ from the pydantic model. For each model handled by the repository, I create an adapter that transforms the pydantic model to an object that matches the db schema, as well as one that transforms the db schema to the pydantic model. Then, in my use case functions I manipulate the pydantic model, provide it as an argument to the repository which handles all of the attribute transformations internally and returns a pydantic model. This way my business logic is agnostic of which db I'm using, and only changes if the business rules change. This not only applies to persistence operations. Most third party software expects data in a certain format and returns data in a certain format, all of which is out of your control. Using the adapter pattern makes sure your core logic doesn't depend on the constraints of other packages.
Just a bit of inconsistency. You mentioned in a previous video that you should only have "abstractmethods" in an ABC; however you implemented "add_device" and "retrieve_buffer_data" in this ABC. Don't get me wrong, I prefer this way of doing it. But I would like to hear on why you decided to change your mind.
I did it this way here to stay close to the idea of the bridge pattern (which has the link between the two hierarchies on the abstract level). In a more complete application, I would probably introduce some sort of device manager class or module and let each streaming service use that via composition instead of putting it in the ABC. But you’re right that the example here is not entirely consistent with what I said before about adding implementation to an ABC.
@@ArjanCodes there seems to be a whole world of useful patterns that are unnamed or almost never mentioned. yet textbooks are filled with factories and decorators, which are never helpful in my experience. i don't get what is so special about those few from the books?
They’re not that special, but at the time those patterns were introduced (which was at the height of the OOP popularity), they were very helpful in understanding how to use OOP with care. I think nowadays, the principles behind the patterns (low coupling, high cohesion, composition over inheritance etc) are much more relevant than the patterns themselves and functions can achieve that very well.
@@ArjanCodes eg monoids are ubiquitous in datascience, but i have never heard about them outside of FP context. they have such useful properties. there is one an only sane way to configure a most programs in most languages, but apparently it's not a pattern. would have saved me weeks of trial and error, if it was in the beginner textbooks.
I thought we should prevent inheritance so that the users won't need to read a bunch of grandfather classes? So, I don't understand why in this video, we somehow prefer the inheritance approach?
It's not about preferring inheritance but about preferring abstraction. Abstraction is what makes the bridge pattern possible. For example, if you use Protocol classes in Python there's no need for inheritance at all and you can still build the bridge pattern that way (I think I do this in the video). Also, there's only a single layer of abstraction (one for each hierarchy in the pattern) so there are no "grandfather classes".
Your videos are very interesting, but always very difficult to understand. I think it may be because you explain everything "linearly", without repeting yourself or "spiraling" around the concept you're trying to explain. I really love the channel, it helps me write rlly better code, but so frustrating to watch the videos 3 times to understand :(
Which Mermaid extension are you using? (There are a handful of them.) Could you include the Mermaid diagram in the repository? GitHub now supports them in MarkDown files like README.md: github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/
💡 Get my FREE 7-step guide to help you consistently design great software: arjancodes.com/designguide.
I've gotten a lot out of your videos and I'm really happy to see the addition of UML diagrams. I've been learning more about design patterns (after discovering them through your videos) and UML diagrams have been really helpful for my visual learning brain. I'd love to see you revisit some of your old design pattern videos and give a UML overview!
Thanks Phil! I'll certainly revisit some of the patterns that I covered already a while ago at some point and then I'll include UML as well.
@@ArjanCodes that would be awesome
I love the way you presented the use case in this video. Normally your explanation involve going through the code. This video's method of presenting what we want to do and then asking how do we do it made it so much easier to understand and to focus. Thanks Arjan!
Glad you liked it, Noxee!
Agreed. This was great!
Yay, patterns are back! My most favorite topic on this channel!
Glad you liked it! Still lots of patterns to dive into, so they'll be occurring regularly in the future ;).
Agreed. The demonstrations of these patterns, I find, are extremely useful. Thanks
I really love your videos on design patterns and have been following them for a while. I've really begun understanding a lot about software design and have been trying to implement good practices wherever possible. Thank you so much!
If it interests you, I would love to hear your opinions on using design patterns in frameworks like Django
Glad you like the videos. And thanks for the suggestion!
By far the best explanation I've seen of the Bridge Pattern. Looking at the UML diagram from the book I was so confused I essentially wrote off this pattern as being something I probably wont understand. 😂 Awesome to see this explained in a reasonable way. Keep up the great work man. Love the videos.
Awesome video Arjan. Btw your studio setup and lighting look slick
Thank your for the videos. I plan to use your lessons for my projects. keep up the good work!
Awesome, like all of your videos! When implementing some functions of the superclass and the rest in child classes, isn’t that in conflict with the concept of loose coupling and high cohesion?
As someone that uses typing quite a bit I know it seems quite esoteric to some python programmers. Would you consider a video on typing in python? I think it's something that most people don't use or are not taught.
@ArjanCodes I would love to see an hexagonal architecture implementation in python, I think no one else has done something similar on yt
I can definitely see the appeal of the bridge pattern. This is a video I can see myself revisiting when I start refactoring for sure. It seems like I should look into your abstract factory video soon as well. By the way, great talk at ELU!
Thanks Jordan! And happy to hear you liked the ELU talk as well 😎
Dam, this is better than Netflix !
Hey Arjan, which extention do you use for the mermaid markdown preview? Thanks for the great content!
Hi @ArjanCodes , thank you so much for your videos. Is there any tool to create the base classes from the mermaid markdown file? Or the opposite, generate a mermaid markdown scanning a project?
You're welcome! I don't know about such a tool, but that would definitely be useful (in particular going from Mermaid -> Code would be really useful).
@@ArjanCodes it's time to build one, isn't? At least a prototype. It may be a very interesting series 😉
LOVE IT!
Thanks!
What editor are you using in your videos?
Awesome video! Thanks again :)
Thanks, glad you liked it!
i just now noticed the credits to code reviewers. kudos to the team, now we can be sure that the approach u used is almost flawless 😇
The code reviewers make a *huge* difference in the quality of the videos. Having those extra pairs of eyes go over the code before filming really helps weed out a lot of issues - the kudos are well deserved!
have you written a book covering a lot of the material in your youtube videos
Not yet, but I'm thinking about it!
That UML plugin is really neat! What extension do you use to auto import python packages?
Not sure if this is mentioned somewhere, but what are you using for your intellisense/code complete extension? That looks a bit more robust than what I'm currently using, it seems quite useful
I don't really like replacing the device classes with functions. It might simplify the code, but those classes could probably contain some state. By using functions, we deprive ourselves of the ability to store and use state. It's not obvious in the example above, but if you do the actual implementation, it becomes a problem.
Anyway, thanks for the video. It became more obvious to me in which cases it's more practical to use ABC instead of protocols 👍
Glad the video was helpful!
Actually, the switch to functions still allows having a device class with state. As long as that device class contains a method that returns buffer data, you can create an instance my_device of that class (containing any state you like), and then you can add my_device.get_buffer_data to the streaming service.
I follow a lot of your video especially from the playlist "Software design in Python".
It's not very clear for me what is the difference between the bridge pattern and the strategy pattern. I read some stuff and it comes like "Strategy pattern is meant for behavior, the Bridge pattern is meant for structure." I think, it would be better to show the difference with a concrete example. What do you think?
Hi Arjan I have coding problem relating to classes and inheritance. Basically what I want to know is how to inherit multiple traits.
Lets say I am making a RPG game where you can play as a character that has a race and a class. Lets say that there are 3 races and 6 classes, resulting in 18 possible combinations that are each played differently.
I would say it makes sense to write one 'Character' class that sets up a basic framework, and then use inheritance to specify the details each race/class combination.
My problem is that I have two traits (race and class) that each inherit from 'Character'. Of course, I dont want to write separate classes for all the 18 different combinations.
So my question comes down to how I should design my code? I would like to have separate spaces for my code about classes and races, and I am looking for an easy way to use this to build a character.
Check Arjan's video on composition over inheritance. The solution is to have a single Character class, which contains a class object and a race object.
Why do you not have cyclical imports from your typing?
Bright side of python.
Hi Arjan! which is the most used design pattern to make a python package for web development?
Hi, that’s hard to say. It depends very much on the type of package what kind of design pattern is most appropriate. I’d suggest to not worry too much about how often a design pattern is used. If it fits a type of problem you need to solve, try it out and see if it works for your use case.
What I have understood by reading Clean Architecture book: Web development is part of detail / delivery mechanism of your software system, You should forget that you have to serve it as a web app while making the main code (policy). It should be such that you can simply plugin the web code, console code, etc
Arjan is correct. You should use the pattern that is most appropriate. Having said that, I would opine the adapter pattern is the most commonly used in web development. I use adapters all the time to provide abstraction between my repository schema and business models. I typically use pydantic models for the business use cases. Each use case that interacts with a database is given a repository instance as an argument. The repository may store data in MongoDB, Postgres, Redis, etc., so their individual schema will often differ from the pydantic model. For each model handled by the repository, I create an adapter that transforms the pydantic model to an object that matches the db schema, as well as one that transforms the db schema to the pydantic model. Then, in my use case functions I manipulate the pydantic model, provide it as an argument to the repository which handles all of the attribute transformations internally and returns a pydantic model. This way my business logic is agnostic of which db I'm using, and only changes if the business rules change.
This not only applies to persistence operations. Most third party software expects data in a certain format and returns data in a certain format, all of which is out of your control. Using the adapter pattern makes sure your core logic doesn't depend on the constraints of other packages.
could you add the uml diagram to your github repo for this video?
Done!
Just a bit of inconsistency. You mentioned in a previous video that you should only have "abstractmethods" in an ABC; however you implemented "add_device" and "retrieve_buffer_data" in this ABC.
Don't get me wrong, I prefer this way of doing it. But I would like to hear on why you decided to change your mind.
I did it this way here to stay close to the idea of the bridge pattern (which has the link between the two hierarchies on the abstract level). In a more complete application, I would probably introduce some sort of device manager class or module and let each streaming service use that via composition instead of putting it in the ABC. But you’re right that the example here is not entirely consistent with what I said before about adding implementation to an ABC.
What is the difference between Bridge and Stragegy?
So basically a bridge pattern is 2 functions: `f::(a -> b) -> a -> c` and `g::a -> b`. How is this a pattern?
Yes, unless you need to represent state as part of the pattern. Most patterns in their essence can be achieved by connecting functions in some way.
@@ArjanCodes there seems to be a whole world of useful patterns that are unnamed or almost never mentioned. yet textbooks are filled with factories and decorators, which are never helpful in my experience. i don't get what is so special about those few from the books?
They’re not that special, but at the time those patterns were introduced (which was at the height of the OOP popularity), they were very helpful in understanding how to use OOP with care. I think nowadays, the principles behind the patterns (low coupling, high cohesion, composition over inheritance etc) are much more relevant than the patterns themselves and functions can achieve that very well.
@@ArjanCodes eg monoids are ubiquitous in datascience, but i have never heard about them outside of FP context. they have such useful properties.
there is one an only sane way to configure a most programs in most languages, but apparently it's not a pattern. would have saved me weeks of trial and error, if it was in the beginner textbooks.
What is the object oriented way to become wealthy?
Inheritance
I thought we should prevent inheritance so that the users won't need to read a bunch of grandfather classes?
So, I don't understand why in this video, we somehow prefer the inheritance approach?
It's not about preferring inheritance but about preferring abstraction. Abstraction is what makes the bridge pattern possible. For example, if you use Protocol classes in Python there's no need for inheritance at all and you can still build the bridge pattern that way (I think I do this in the video). Also, there's only a single layer of abstraction (one for each hierarchy in the pattern) so there are no "grandfather classes".
Where to actually find out what pythonic even is? Sometimes it makes sense but other times the idea can be really elusive.
Your videos are very interesting, but always very difficult to understand.
I think it may be because you explain everything "linearly", without repeting yourself or "spiraling" around the concept you're trying to explain.
I really love the channel, it helps me write rlly better code, but so frustrating to watch the videos 3 times to understand :(
Which Mermaid extension are you using? (There are a handful of them.)
Could you include the Mermaid diagram in the repository? GitHub now supports them in MarkDown files like README.md:
github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/