Why Use Design Patterns When Python Has Functions?

101,499
0
Published 2023-10-13
In this video, I'll demonstrate that functions don't make design patterns obsolete in Python. There's a lot of talk in the developer community on the topic, and to illustrate my point, I'll look at a few common design patterns and show you an alternative approach using functions.

👷 Join the FREE Code Diagnosis Workshop to help you review code more effectively using my 3-Factor Diagnosis Framework: www.arjancodes.com/diagnosis

💻 ArjanCodes Blog: www.arjancodes.com/blog

✍🏻 Take a quiz on this topic: www.learntail.com/quiz/vykuhf

GitHub repository ➡️ git.arjan.codes/2023/funcpatterns

🎓 Courses:
The Software Designer Mindset: www.arjancodes.com/mindset
The Software Architect Mindset: Pre-register now! www.arjancodes.com/architect
Next Level Python: Become a Python Expert: www.arjancodes.com/next-level-python
The 30-Day Design Challenge: www.arjancodes.com/30ddc

🛒 GEAR & RECOMMENDED BOOKS: kit.co/arjancodes.

👍 If you enjoyed this content, give this video a like. If you want to watch more of my upcoming videos, consider subscribing to my channel!

Social channels:
💬 Discord: discord.arjan.codes/
🐦Twitter: twitter.com/arjancodes
🌍LinkedIn: www.linkedin.com/company/arjancodes
🕵Facebook: www.facebook.com/arjancodes
📱Instagram: www.instagram.com/arjancodes
♪ Tiktok: www.tiktok.com/@arjancodes

👀 Code reviewers:
- Yoriz
- Ryan Laursen
- Dale Hagglund

🎥 Video edited by Mark Bacskai: www.instagram.com/bacskaimark

🔖 Chapters:
0:00 Intro
3:15 Strategy design pattern
8:04 Observer design pattern
15:06 Template Method
21:27 Bonus
22:39 Outro

#arjancodes #softwaredesign #python

DISCLAIMER - The links in this description might be affiliate links. If you purchase a product or service through one of those links, I may receive a small commission. There is no additional charge to you. Thanks for supporting my channel so I can continue to provide you with free cont

All Comments (21)
  • @dhariri
    This was great. One thing I will offer is that sometimes more lines of code is “less code” in the sense that it can be less complicated to understand and therefore more valuable. Not always, and I would agree that often a functional style is the right solution.
  • For people less familiar with design patterns, the side effect of such a video is that it explains them very well. By looking at the patterns from both the class and function implementation view, I really got the gist of the patterns. I'd like to see more videos like this with some of the other patterns, thanks! 😊
  • Insightful, would love a book on Design patterns and SOLID principles how they apply in Python ❤
  • @hcubill
    This is one of my favourite videos. Will come again to this again and again. It has sparked many ideas for my team already!
  • @vlademilian4937
    I am using most of these. It all comes down to the specific problem. For example, I use classes when I need to hold a context; for the observer example from the video, when you do email notifications, you will need a handler for email (probably a http endpoint or something); for that handler, you will need some api key or credentials or other specific information; if the observer is a class, then these informations can easily be stored in it's private attributes, but if we use functions, then we would need to store them in a global variable near the function and I believe that it is a messy solution; another solution would be to get the informations from a global module, but this introduces coupling between the config module and the notification handler function. Another thing that I consider important is that if we use abstract classes, using the IDE (pycharm), we can easily see all the classes that are derived from the base class. If we use functions, we can't do that. This is useful for when you need to change the abstract method in base to pass additional information and you also need to change it in all derived classes.
  • @scottmiller2591
    I wrote one of the few commercial Modula-2 programs - a logic simulator that took gate delays into account, but also trace lengths, capacitance, and inductance. I used it because it was one of the few languages that had the necessary scientific chops, while at the same time could talk directly to Mac handles. I haven't heard of anyone using Modula-2 since.
  • @thanasis2002
    Thanks Arjan! That's really interesting! In my case, what works very well for me is a mixed approach of having functions and classes. For example, I could have some concrete classes, but I would use a function as a factory to generate these objects.
  • @WalterVos
    I do really like juggling with functions, but when working with a team you've got to consider if the code remains readable for your team mates. In general I try to use functions when the class based version would be stateless. When dealing with state, and operating on that state, OO feels better. This is entirely different when working in a functional first language by the way! From my experimentation with fsharp, using types and related functions felt entirely natural.
  • @Lexaire
    Would be cool if you showcased dependency injection framework too, since people hopefully don't all have to reinvent the wheel.
  • @youmal30
    Thank you Arjan for this very instructive video on design patterns in Python using OO approach and functional approach. I learnt a bit about functional programming using TypeScript, and it helped me understand that you were using "Callable" to define a "function type". I believe that by convention you use a capital letter for the first letter in the name of that "function type". Functional programming is terse and comments would definitely help.
  • @horoshuhin
    love your videos on design patterns. 23 min flew by in a sec. I hope to see more
  • @Han-ve8uh
    18:53 says we get the same output as before (i assume OO version's output). However, the function version is missing a override of hook 2 that the OO version did. It also shows in the output, where the function version is missing 1 line about hook 2 compared to OO version
  • @adamgoldsmith310
    This is literally something I have unconsciously done, I think I've used all 3 of your examples purely with functions in js and C#, in the C# it was so that I could use OO to handle Managed Resources, and then used the function based strategy pattern to pass a predicate for use filtering things used in within the managed resource :) Mixing OO and functional programming, using the best of both worlds makes me happy
  • @anti-despot2887
    That's so interesting. I've been using some of these things without knowing it. I sometimes have an update method in my class that will rerun a series of methods when I assign a new value to a property. I also use a dictionary to navigate context by running different class methods or the same with different arguments based on the key that's used. You've taught me a lot and I really appreciate it! I always look forward to your videos
  • Decorators are a great example of use of functions as arguments and as return values. It can make the code look much better, but when used wrong it very hard to understand.
  • @darksuji
    You make a really good case for how functional programming has superseded the need for most of the design patterns. I still find objects a more useful holder of state than curried functions in a lot of cases, so which to use really depends on the details of the problem you are solving.
  • @pablostraub
    This is great material. While viewing it I was thinking this is basically another way of doing dependency injection. For example, the strategy pattern is injecting a dependency on a particular algorithm. Similarly, the template method is injecting dependencies on particular methods. Of course, the best explanation of dependency injection is also to be found in this channel.
  • @astronemir
    When returning functions I make extensive use of the typing system to make it easy to understand. Make types using TypeAlias, NewType, and NamedTuple and also make higher level functions to work with the types. Hook type, RequiredOperation type, and named tuples that contain them if limited, (if there are two operations there must be a reason or why, but for simplicity let’s call it first and second). So the returned function would take in a named tuple of Hooks, and the template function would take in a named tuple of RequiredOp, and returns callable that takes in Named tuple of hooks. Etc.
  • Using oo programming for a CAD system in the 1990ies was an eye opener. But the kind of religion that design patterns involved into never felt necessary. It is interesting that the programmer world is going back a little on patterns and I feel that the solutions have to be designed for the problem. I feel that patterns is a way to rewire the programmers brain and then when you analyze the problem you can reap from that knowledge for oo or functional as you fine best. It is interesting that PCs nowdays need 64GB of ram to do anything meaningful is in my opinion a result of patterns and there are OSs that run on 1,4mB whith graphics which is incredible. Programming now feels bloathed and we need to go back to the basics.