How to Implement the Strategy Design Pattern in Python

How to Implement the Strategy Design Pattern in Python

ArjanCodes

3 года назад

53,121 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

@XRay777
@XRay777 - 01.10.2021 20:13

Plot twist: functions in python are still just objects :D

Ответить
@no_hurry7000
@no_hurry7000 - 01.10.2021 20:47

There should be one -- and preferably only one -- obvious way to do it.

Ответить
@pacersgo
@pacersgo - 01.10.2021 23:21

I have the feeling that the classic way would be more readable since it has been introduced for a long time.

Ответить
- 01.10.2021 23:26

As far as I understand Callable with typed arguments is deprecated in favour of Protocol. You could have kept the Protocol class to type hint the functions.

Ответить
@PetrSUsername
@PetrSUsername - 01.10.2021 23:48

I think you should have mentioned that _call_ is only usable/executed after the class has been already instanced.

Ответить
@CrapE_DM
@CrapE_DM - 02.10.2021 00:03

I've always seen it as LIFO, not FILO, though both work just fine, I guess

Ответить
@jeancerrien3016
@jeancerrien3016 - 02.10.2021 00:17

Yet another wonderful video. Thank you. 🙏 Why do you insist on retyping the signature of create_ordering? It seems more efficient to copy and paste. 😊

Ответить
@Alche_mist
@Alche_mist - 02.10.2021 00:24

I'm glad you're finally deviating from the "write Python like Java" approach. That's my gripe with a lot of the patterns used meticulously "as conceived" - they are often overengineered due to too many classes everywhere and can be made far easier using constructs like closures or dictionary dispatch.

Ответить
@jeffersondperezmadrigal4917
@jeffersondperezmadrigal4917 - 02.10.2021 01:11

Amazing video! I’d love to see architecture patterns like clean architectures to understand how to structure web apps, where does the business logic goes, and stuff like that 👍🏼 - Great work @Arjan

Ответить
@BrockPalmer
@BrockPalmer - 02.10.2021 02:53

This is somehow the first time I've seen the acronym FILO (first in last out). At a previous job, we had a FILO inventory system, but call it "fish" for "first in still here."

Ответить
@superscatboy
@superscatboy - 02.10.2021 03:25

I hope I never have to request support from a support system that uses first in last out lol

Ответить
@ravenecho2410
@ravenecho2410 - 02.10.2021 04:42

ur videos are always so valuable, i super appreciate your work and effort u.u

Ответить
@talhaamir9023
@talhaamir9023 - 02.10.2021 05:19

It's been more than two years working as a Python Developer and nothing excites me more than getting a notification, Arjan Codes has uploaded a new video 🔥

Thanks for the premium quality content.

Ответить
@MarkWernsdorfer
@MarkWernsdorfer - 02.10.2021 07:11

Hey @Arjan ! Thanks a lot for your videos. They're really advanced and easy to follow at the same time. I noticed you make your type hints lower case. I'm importing from `typing` instead. I'd be interested in your reasons. Thanks a lot!

Ответить
@theyashbhutoria
@theyashbhutoria - 02.10.2021 09:26

Been binge watching your videos over the weekend. This is theraputic.

Ответить
@heinrichdj
@heinrichdj - 02.10.2021 10:18

Awesome, thanks!

Ответить
@merlonmerlon8722
@merlonmerlon8722 - 02.10.2021 14:50

Great video! But I don't understand the advantage of using Protocol instead of ABC. I see it as a loss of information which can create confusion in the future.

Ответить
@queueoverflow
@queueoverflow - 02.10.2021 14:51

In c#, we can also pass an actioin<> or a func<>. strategy pattern.

Ответить
@joningram
@joningram - 02.10.2021 18:36

Having got into programming before all these design patterns became the in thing, I'm enjoying your videos, and hope to see more!

Your option 4 (just using functions) seems so much more Pythonic than the Byzantine Java-derived 'class with a single function pretending to be a function' options. I wonder whether your insistance on defining the types of everything obscures what is quite a simple idea in option 5 -- calling a function which returns another function is not a particularly obscure thing to do in Python, but I can imagine is quite painful to think about in more formal languages.

Ответить
@tomtrask_YT
@tomtrask_YT - 02.10.2021 20:48

Am I missing something? It seems like in that last example of a function returning a closure, the closure is always returning the same shuffle (so if [a, b, c] comes back [b, c, a], then [d, e, f] will come back [e, f, d] - though admittedly different length lists would be shuffled differently). All iterables would be shuffled precisely the same in a single run. I would have expected only that the first shuffle of a sequence of calls is shuffled the same from run to run.

Thanks for the video. This answered a question in a side project that had been bugging me for a couple days now.

Ответить
@magnuscarlsson6785
@magnuscarlsson6785 - 03.10.2021 10:08

I like the closure way, but would have referred to it as a factory pattern... What is the distinction between what you call a "closure" and what you call a "factory", don't they both create and return a customised object?
Thanks for your great videos!

Ответить
@vasilijestosic8331
@vasilijestosic8331 - 03.10.2021 12:12

Excellent examples!!

Ответить
@anelm.5127
@anelm.5127 - 05.10.2021 04:09

I really think that a series on architectures would be amazing..
This is the senior stuff us noobs need to learn 😄

Ответить
@lemongraz7295
@lemongraz7295 - 05.10.2021 16:27

Great Video, thanks! What keyboard do you use? Doesn‘t sound like a standard mac one, right?:)

Ответить
@WesGann
@WesGann - 06.10.2021 20:53

@ArjanCodes, could you create or link to a video showing the keyboard shortcuts? I noticed you were deleting lines or data between parans with some keyboard shortcuts. I could probably take time to google these but hey, it's more content for you to make :)

Ответить
@nocodenoblunder6672
@nocodenoblunder6672 - 08.10.2021 10:56

I like the example overall but i dislike that you removed the selection of strategies. It might seem that the strategy pattern chooses the right strategy on its own which is not the case. Most of the time you still need to select a Strategie in the client.

The clients needs to know about the strategies and instantiate the appropriate one. This is where pythons new structural pattern matching in gone come in handy I think.

Nonetheless great video and very useful pattern that provides great extensibility, decoupling, switching of strategies at runtime.

Ответить
@dmytrokorbanytskyi1586
@dmytrokorbanytskyi1586 - 09.10.2021 22:57

great work! Could you make a video about typing in Python and cool features that can be used with them?

Ответить
@sirius7584
@sirius7584 - 12.10.2021 15:57

Strategy가 dynamic한 외부 데이터에 의존한다면 class를 쓰는 전통적인 방식이 낫지 않을까?

Function을 사용한다면 의존성을 주입한 partial function을 써야할 거 같음.

Ответить
@chikosan99
@chikosan99 - 13.10.2021 22:36

Great but difficult (:

Ответить
@Ryan-ww7un
@Ryan-ww7un - 24.10.2021 03:39

I love working alongside your videos on your examples. Thank you for all of your hard work!

Ответить
@Ryan-ww7un
@Ryan-ww7un - 24.10.2021 03:44

What extension were you using that automatically imported packages? I am using TabNine pro and it doesn't do this.

Ответить
@realplod
@realplod - 04.12.2021 14:33

Blows my mind how much I don’t know

Ответить
@jeffgruenbaum
@jeffgruenbaum - 07.01.2022 23:41

great ideas! I had never though about creating an "interface" for functions, using the callable to match the typing patterns is very clever.
Thanks for the videos!

Ответить
@jamiekydd1049
@jamiekydd1049 - 28.03.2022 09:48

To be honest all this does for me is confirm my preconception that nobody that thinks about design patterns should ever use them. I've never seen an example where a 'strategy' isn't just effectively just a closure/bound function object, and elevating this to being worthy of a named type just results in inexperienced developers wanting to define classes just so they can name them 'BlahBlahStrategy'.

Ответить
@imadetheuniverse4fun
@imadetheuniverse4fun - 28.05.2022 07:41

I really love the idea of using functions instead of classes if the class is just there to hold a single method and no state!

I also think it further reduces coupling because the function that is calling the strategy doesn't need to know what the method name is or anything. Might even be good to pass the strategy as a parameter to the calling function where you can provide the type alias as type hint as well.

Ответить
@multigladiator384
@multigladiator384 - 17.07.2022 10:48

Lets say we have a function which takes argument of type A and returns argument of type B ( A -> B)

Then I put them in a dict strategies: {string: A -> B } and thats it... for functions this works very well, if you want to map to classes you have to make an Interface and use it in strategies as the type instead of A -> B and of course your classes shall inherit the interface

Ответить
@fjonesjones2
@fjonesjones2 - 26.09.2022 09:58

Great video as always, many thanks mate. Also yes, I've been using Tabnine with VS Code for Linux for a while, it's just like 'Magic' and FREE!! ... ;-)

Ответить
@amingholizad
@amingholizad - 23.11.2022 12:06

@ArjanCodes Thanks for the rich content you produce here. Is there any performance advantages between these features?

Ответить
@zacharythatcher7328
@zacharythatcher7328 - 01.03.2023 00:14

I am in a bind right now where I want to enforce an interface on a number of object methods, all in the same class, all requiring access to self in order to continue the flow of the program. It would be easy to apply the functional implementation of the strategy pattern to them, but that doesn't enforce kwarg names and I like using the kwarg names wherever possible, especially with an interface in python.

One thought that I have is to inject these methods, but then I would have to pass the ingesting object to these methods so that they could call the method in the ingesting object. This feels messy.

My next thought is to take the method call to the next method out of the injected methods, and have necessary data bubble back up and then continue the flow.

aka it is currently

->originating method
-> injected method
-> next object method

and I would change it to

-> originating method
-> injected method
<- return result
-> originating method
-> next object method

I have ended up going with my final solution. I thought I should post this as a real life example, since it has helped me think and might help someone else.

Turns out I forget an old lesson to keep the stack as shallow as possible, and your life will get much easier.

Ответить
@ikopysitsky
@ikopysitsky - 14.03.2023 06:59

Is there a way to rewrite the last example with a decorator instead of an explicit closure?

Ответить
@italo.buitron
@italo.buitron - 20.05.2023 20:38

Question:
If i add in FIFO another func, still work protocol? or all the strategy tickets must have same funcs?

Ответить
@btonasse
@btonasse - 16.10.2023 16:49

Nice video. Am I the only one who thinks people are trying to shoehorn functional stuff into everything they do? Classes are still the most explicit, intuitive, readable and elegant way to achieve something like this.

Ответить
@edgeeffect
@edgeeffect - 20.10.2023 11:58

As a JavaScript fanboy, I always used to like to say "YES! but 'my language' has closures and 'yours' doesn't!".... This is becoming less and less valid all the time. ;)
I love how you keep your examples so minimal - your videos are never too complex to be able to follow and not everyone realises how important that is.

Ответить
@howeichin4103
@howeichin4103 - 30.11.2023 10:41

super cool and informative video! thank you for the great effort!

Ответить
@dank8981
@dank8981 - 04.01.2024 10:05

I watched this video a while ago then I didn't really have a use case for this so i just toss this info back of my mind somewhere. Today, I just realized that for the problem i was solving this is a great way to attach the problem. Here i am watching again and yes this will be a perfect way to solve my problem. Thanks Arjan!

Ответить
@fringefringe7282
@fringefringe7282 - 06.01.2024 17:49

I like your vids, but this background music is annoying.

Ответить