Strategy Pattern – Design Patterns (ep 1)
Resumen
TLDRCette vidéo est une introduction au modèle de stratégie dans le cadre des modèles de conception. Elle explique pourquoi la composition est préférable à l'héritage, illustrant cela avec un exemple de canards. Le modèle de stratégie définit une famille d'algorithmes qui peuvent être échangés, ce qui permet aux algorithmes de varier indépendamment des clients qui les utilisent. Cela réduit les complexités liées aux changements dans les exigences tout en évitant la duplication de code. La vidéo encourage également à considérer une lecture du livre recommandé pour une meilleure compréhension des modèles de conception.
Para llevar
- 📘 Introduction aux modèles de conception
- 🔄 Préférer la composition à l'héritage
- ⚙️ Encapsulation d'algorithmes
- 💡 Variabilité des algorithmes
- 🐤 Exemple des classes de canards
- 📈 Meilleure évolutivité du code
- ⚠️ Éviter la duplication de code
- 📖 Recommandation de livre pour approfondir
- ✅ Méthode d'injection de dépendance
- 🔍 Analyse UML du modèle de stratégie
Cronología
- 00:00:00 - 00:05:00
Cette série sur les motifs de conception débute avec une introduction au livre de référence et une vue d'ensemble des 13 motifs qui seront traités. L'importance de comprendre que ce livre est plus pédagogique que technique est soulignée, avec un accent sur l'apprentissage des motifs de conception plutôt que sur des définitions sèches.
- 00:05:00 - 00:10:00
Le premier motif présenté est le motif strategy, qui est décrit comme un moyen d'utiliser la composition plutôt que l'héritage. La définition officielle stipule qu'il définit une famille d'algorithmes, chacun étant encapsulé et interchangeable, permettant aux algorithmes de varier indépendamment des clients qui les utilisent.
- 00:10:00 - 00:15:00
Le motif strategy permet de décoller les algorithmes de leurs clients, illustré par des exemples de classes de canards. L'idée est que les différentes sortes de canards peuvent afficher des comportements variés sans que les clients aient besoin de connaître leurs implémentations internes. C'est un moyen de rendre le code plus flexible et moins sujet aux erreurs lors de changements de comportement.
- 00:15:00 - 00:20:00
L'héritage est montré comme une solution potentiellement problématique lorsque l'on doit gérer des comportements partagés, entraînant une duplication de code. On voit comment des classes comme canard en caoutchouc nécessiteraient des modifications indésirables à cause d'un comportement hérité non pertinent comme 'voler'.
- 00:20:00 - 00:25:00
Le passage à la composition via le motif strategy est expliqué en démontrant la création d'interfaces pour les comportements des algorithmes spécifiques comme 'quacker' et 'fly', permettant à chaque canard d'adopter des comportements variés sans redéfinir la logique dans chaque classe de canard.
- 00:25:00 - 00:30:00
Une fois les interfaces en place, des comportements spécifiques sont créés, illustrant comment les différents types de canards peuvent se comporter différemment tout en partageant d'autres logiques au sein des classes. Par exemple, un canard peut avoir un comportement de 'quack' simple ou aucun comportement de 'quack' du tout.
- 00:30:00 - 00:35:11
Au fur et à mesure que la conception progresse, l'importance de l'injection de dépendances est examinée, soulignant que les comportements ne devraient pas être codés en dur dans les classes, afin de maintenir la capacité de modification sans impacts indésirables sur l'ensemble du code. Le diagramme UML est introduit pour résumer la structure du motif strategy et sa flexibilité, renforçant le besoin de cette approche en programmation orientée objet.
Mapa mental
Vídeo de preguntas y respuestas
Qu'est-ce qu'un modèle de stratégie ?
Un modèle de stratégie est un modèle de conception qui définit une famille d'algorithmes, les encapsule et les rend interchangeables.
Pourquoi privilégier la composition à l'héritage ?
La composition permet de changer de comportement sans altérer la classe cliente, contrairement à l'héritage.
Comment le modèle de stratégie aide-t-il lors des changements de spécifications ?
Il permet d'adapter les algorithmes sans devoir modifier les classes clientes, ce qui réduit le risque de bogues.
Quel est l'avantage de décorréler comportements et classes ?
Cela facilite l'évolutivité et la maintenabilité du code, permettant de gérer la complexité.
Quel est un exemple de mise en œuvre du modèle de stratégie ?
Utiliser des classes pour les comportements de vol et de canard, permettant différentes implémentations sans modification des classes de canard.
Ver más resúmenes de vídeos
L’apprentissage de la lecture et ses difficultés (1) - Agir pour l'éducation (2022-2023)
ILS TOMBENT POUR LA PATRIE, P. TALON GARDE LE SILENCE. L'ÉTAT A-T-IL CHOISI ABANDONNER SES HÉROS ?
01- Lo que nos hizo Músicos | PODCAST Lo Que Nos Hace Músicos #loquenoshace
TEVE AVC? Comece por aqui! 10 Orientações importantes - Dr. Rogério Souza
Formation complète OFM : ma méthode de Chatting OnlyFans (à copier dès maintenant)
Dream Kitchen Tour
- 00:00:01welcome to the series on design patterns
- 00:00:04in this series we're going to talk about
- 00:00:06the design patterns in this book head
- 00:00:09the first design patterns one by one so
- 00:00:14at least we're going to look at thirteen
- 00:00:16patterns before we get started if you're
- 00:00:18getting started with the design patterns
- 00:00:20I highly recommend this book if you
- 00:00:22already know a lot about design patterns
- 00:00:23and you're looking for maybe a reference
- 00:00:26book this is not really it this is more
- 00:00:28of a very talking Illustrated super
- 00:00:31pedagogical book for learning design
- 00:00:34patterns right it's there's tons of
- 00:00:36super silly jokes in this book so if
- 00:00:39you're just looking for the definitions
- 00:00:41and the UML diagrams like that don't get
- 00:00:44this book but if you want to learn
- 00:00:45design patterns and the rationale behind
- 00:00:47them get this book check the description
- 00:00:51but so let's get into it
- 00:00:53pattern number one strategy pattern
- 00:00:58strategy pattern is a super sensible way
- 00:01:00to start if you're just learning design
- 00:01:02patterns it's actually probably the
- 00:01:04simplest pattern if I were to think of
- 00:01:06it in only a few words I would say that
- 00:01:08it's about using composition rather than
- 00:01:11inheritance it's about understanding
- 00:01:12that inheritance is not intended for
- 00:01:16code reuse but let's check out the
- 00:01:18official definition from this book so
- 00:01:21they're saying the strategy pattern
- 00:01:23defines a family of algorithms
- 00:01:26encapsulate s' each one and makes them
- 00:01:29interchangeable strategy let's the
- 00:01:32algorithm vary independently from
- 00:01:36clients that use it at all so let's
- 00:01:39think about this strategy pattern
- 00:01:41defines a family of algorithms okay when
- 00:01:44you're using strategy pattern you have a
- 00:01:46family of algorithms yeah set of
- 00:01:49algorithms that you want to use it
- 00:01:50encapsulates each one of them and makes
- 00:01:52them interchangeable okay so you have
- 00:01:54this bunch of algorithms and each of
- 00:01:57them are interchangeable right so you
- 00:01:58have algorithm a you have algorithm B
- 00:02:00you have algorithm C and there they're
- 00:02:02claiming that the strategy pattern you
- 00:02:04can plug and play you can sometimes use
- 00:02:06algorithm a
- 00:02:07sometimes use algorithm B sometimes use
- 00:02:09algorithm C and so forth and then the
- 00:02:12second line I guess it's more like the
- 00:02:14rationale right then they're saying
- 00:02:16strategy let's the algorithm vary
- 00:02:18independently from the clients that use
- 00:02:20it so think about the word decoupling
- 00:02:22we've decoupled the algorithm from the
- 00:02:26one using the algorithm so we said that
- 00:02:28we can vary between algorithm a and
- 00:02:30algorithm B and algorithm C for example
- 00:02:32so whoever is using algorithm a or
- 00:02:35algorithm B your algorithm C that thing
- 00:02:37will usually refer to these things as
- 00:02:39clients in this book that client does
- 00:02:42not have to vary if one of the
- 00:02:44algorithms varies in other words when we
- 00:02:46say vary we mean if you want to change
- 00:02:49one of the algorithms the contents of
- 00:02:51the algorithms what the algorithm
- 00:02:52actually does then you don't necessarily
- 00:02:54have to change the client at the same
- 00:02:57time so whoever is using that algorithm
- 00:03:00is not forced to change when you are
- 00:03:02changing at one of the algorithms and
- 00:03:04that's super good this will make more
- 00:03:07sense in the end but if you think about
- 00:03:08an implementation of a collection for
- 00:03:10example an implementation of a list if
- 00:03:12the list had a sorting algorithm built
- 00:03:15into it you can never change the sorting
- 00:03:18algorithm but if you using strategy
- 00:03:20pattern inject a sorting strategy then
- 00:03:23the sorting strategy can vary
- 00:03:25independently from the list so you have
- 00:03:28the implementation of the list and
- 00:03:29that's stable but then you inject
- 00:03:32different sorting algorithms but that's
- 00:03:35far beyond let's now get into this so
- 00:03:37generally in this series I'll make heavy
- 00:03:40use of the examples from this book but I
- 00:03:42won't just give them one to one I'm
- 00:03:44slightly adapting them because I think
- 00:03:46some of them are just overly complicated
- 00:03:48and I'll try to go a bit faster but
- 00:03:51here's the gist of their example so in
- 00:03:54the example there's a duck class the
- 00:03:56duck class is a superclass so the
- 00:03:59intention is that other classes should
- 00:04:02inherit from the duck class so they have
- 00:04:04something like a mallard duck and some
- 00:04:06other duck and that's just confusing
- 00:04:07because I don't even know what a mallard
- 00:04:09duck
- 00:04:09is and I don't think it's relevant
- 00:04:11example so let's just say that we have a
- 00:04:14wild duck and a city duck so wild duck
- 00:04:17would be a duck out in the forest or
- 00:04:19wherever ducks hang out and a city duck
- 00:04:22would be a duck in the city
- 00:04:24now that hangs out in the palms in the
- 00:04:26city makes no sense but it doesn't
- 00:04:28really matter the point is that we have
- 00:04:29two types of ducks and notice how I make
- 00:04:32use of this kind of arrow and this kind
- 00:04:35of arrow so in in UML this is is a-- and
- 00:04:38and this is has a--
- 00:04:41so composition is this one inheritance
- 00:04:45is this one so in other words a wild
- 00:04:48duck is a duck ah city duck is a duck so
- 00:04:53this would mean that a duck has a wild
- 00:04:55duck right this would mean that a wild
- 00:05:00duck has a duck but now we're saying a
- 00:05:03wild duck is a duck because of this
- 00:05:06movie so the point in the example is
- 00:05:08that the sub classing ducks the
- 00:05:11subclasses are responsible for
- 00:05:13implementing their own version of the
- 00:05:16display method
- 00:05:17so while duck has its own display method
- 00:05:20city duck has its own display method and
- 00:05:24thus wild ducks can be displayed
- 00:05:26differently than city ducks and so forth
- 00:05:29if we would add another class this would
- 00:05:34have its own another duck type this
- 00:05:36would have its own display method so
- 00:05:38that could be displayed in a manner
- 00:05:40appropriate for that duck and then of
- 00:05:43course the kwok method the behavior of
- 00:05:46quark is shared amongst all of these
- 00:05:49subclasses and this is how they're using
- 00:05:51inheritance for code reviews now this
- 00:05:55seems fine and dandy right what's the
- 00:05:56problem the problem is of course that
- 00:05:58has oftentimes when we talk about design
- 00:05:59patterns it's change its that chain when
- 00:06:02requirements change when our system will
- 00:06:04have to change over time our current
- 00:06:06design may not necessarily be
- 00:06:08appropriate for the income
- 00:06:10requirements the example that they take
- 00:06:11is that let's say that we have another
- 00:06:13method which is fly right so ducks fly
- 00:06:16which makes sense because ducks do fly
- 00:06:18thus we've suddenly given city duck the
- 00:06:21ability to fly and we've given wild duck
- 00:06:23the ability to fly this example is of
- 00:06:25course completely fixtures then kind of
- 00:06:27silly but then they're saying that okay
- 00:06:28then some new requirements come in and
- 00:06:30they somebody some programmer forgets
- 00:06:33that they're doing this and we have
- 00:06:35another subclass which is a rubber duck
- 00:06:37sort rubber duck is a fake duck right
- 00:06:39you know these yellow plastic ducks
- 00:06:41rubber plants whatever it's a fake duck
- 00:06:43it's one of these yellow ducks and
- 00:06:45rubber dog has its own display method
- 00:06:48but the argument is that or the problem
- 00:06:51is that they're saying it well rubber
- 00:06:54ducks shouldn't be flying okay so so
- 00:06:58rubber ducks shouldn't be flying so that
- 00:07:00means we can't just blindly inherit that
- 00:07:03behavior so what if we then now I'm sort
- 00:07:05of trading off from where they're going
- 00:07:07but I think we're going to serve the
- 00:07:08same place so what if then we're saying
- 00:07:10that let's implement fly as well here
- 00:07:12let's implement fly here so we have some
- 00:07:16rubber duck has its own behavior and
- 00:07:18that behavior is essentially nothing
- 00:07:19right it's non flying so you could argue
- 00:07:23that not being able to fly is a kind of
- 00:07:26flying behavior we'll get more into that
- 00:07:28and this too actually works fine but you
- 00:07:31can maybe start to get this feeling that
- 00:07:33we're sort of heading down a slippery
- 00:07:35slope so let's say that we have another
- 00:07:38duck I'll just make up silly name so you
- 00:07:40know never mind the name is just thing
- 00:07:43we had lots of ducks so let's say that
- 00:07:44we have a mountain duck right names make
- 00:07:47no sense whatever and the mountain duck
- 00:07:50of course can be displayed but the point
- 00:07:52here is that that this duck also wants
- 00:07:55to have its own flying behavior so we
- 00:07:58override fly here but let's say that
- 00:08:01this flying behavior isn't necessarily
- 00:08:03not being able to fly let's say that it
- 00:08:05is a flying behavior but it's just some
- 00:08:07kind of different flying behavior and
- 00:08:09then let's say
- 00:08:10say that we have another duck so it's a
- 00:08:12cloud duck it's it it's another duck
- 00:08:15that has its own flying behavior but
- 00:08:18what's interesting is that this duck has
- 00:08:19this guy's flying behavior these two
- 00:08:23Ducks have the same flying behavior so
- 00:08:25we here also override and implement the
- 00:08:28fly behavior but because this fly
- 00:08:31behavior is the base class fly behavior
- 00:08:33right that's different from these two
- 00:08:35these two have their own right so the
- 00:08:39code here the copy in this fly game
- 00:08:41actually is the same as this one
- 00:08:44100% duplicated we just go copy paste so
- 00:08:48these have the same and then you could
- 00:08:50start to say okay well I need another
- 00:08:52class I need another flying like flying
- 00:08:57with style a and both of these inherit
- 00:09:00from flying with stylette but hopefully
- 00:09:03you're feeling that now really treading
- 00:09:06down a dangerous path right because yes
- 00:09:08okay that works for fly I'm running out
- 00:09:11of space here but what if we also have
- 00:09:13eat for example right so we have an eat
- 00:09:17method and this duck has a base classes
- 00:09:21eat method but this duck has its own eat
- 00:09:25method and then there's another duck
- 00:09:28let's say the rubber duck has the same
- 00:09:29eat method as the mountain duck you can
- 00:09:32start to feel however sort of it's
- 00:09:34getting kind of crazy so like let's
- 00:09:36let's try and draw this it works as long
- 00:09:38as the behavior is shared downwards so
- 00:09:41this is an inheritance hierarchy right
- 00:09:43as soon as you want to show me havior
- 00:09:45horizontally here there is no way unless
- 00:09:48you get into multiple inheritance but
- 00:09:50like I think Sammy met says it nicely
- 00:09:52when she says that the solution to
- 00:09:54problems with inheritance is not more
- 00:09:56inheritance but that's a topic for
- 00:09:58another discussion but I think this and
- 00:10:00now by analogy kind of makes sense you
- 00:10:03choose of course there are many ways of
- 00:10:05building these hierarchies there are
- 00:10:08many ways of building up this
- 00:10:10inheritance chain but essentially the
- 00:10:13point is that no matter how you do it
- 00:10:15there are some scenarios where you
- 00:10:18can't build it hierarchically because
- 00:10:20you will end up in a situation where
- 00:10:22some behavior here also once we wants to
- 00:10:26be used here
- 00:10:26so you either have to duplicate code or
- 00:10:29find another solution
- 00:10:30by the way Sandi Metz has a really great
- 00:10:33talk on amongst other things the null
- 00:10:35object pattern where she talks a bit
- 00:10:37about this I'll link that in the
- 00:10:38description it's super valuable and that
- 00:10:40gives more insight into why composition
- 00:10:42should often be favored over inheritance
- 00:10:44but let's move on I think you're seeing
- 00:10:46the problem so let me get rid of this
- 00:10:47stuff and let's just directly jump into
- 00:10:50the solution never mind all of those
- 00:10:52intermediate steps so what I'll do is
- 00:10:54that I'll remove everything and just
- 00:10:56keep the wild duck and a city duck but
- 00:10:59please generalize in your head and
- 00:11:00remember that there could be more ducks
- 00:11:02so the point with strategy let's think
- 00:11:04about the definition again the strategy
- 00:11:06pattern defines a family of algorithms
- 00:11:07encapsulate each one and makes them
- 00:11:09interchangeable strategy let's the
- 00:11:11algorithm vary independently from the
- 00:11:12clients that use it that's exactly our
- 00:11:14problem here we have an algorithm fork
- 00:11:17working we have an algorithm for flying
- 00:11:19and what we're realizing is that we
- 00:11:21can't create a hierarchical solution in
- 00:11:23order to share code between these
- 00:11:26different uses of the different
- 00:11:28algorithms so we have to extract the
- 00:11:29algorithms and say that these are
- 00:11:31clients right a duck is a client a city
- 00:11:34wild duck is a client a sticky duck is a
- 00:11:36client
- 00:11:37was that air duck cloud dark cloud duck
- 00:11:40is a client and they make use of
- 00:11:43different algorithms for flying and fork
- 00:11:46walking and these must be able to vary
- 00:11:50independently from from other aspects of
- 00:11:52the clients so what do we do well we say
- 00:11:55that ok or create strategies for
- 00:11:58quacking and strategies for flying so
- 00:12:01we'll create an interface i kwok
- 00:12:03behavior and what it does is that it
- 00:12:05says you need to have a kwok method and
- 00:12:08there are many ways of solving this that
- 00:12:11would still adhere to the strategy
- 00:12:12pattern but this is one way of
- 00:12:14approaching it and then we do the same
- 00:12:16for flying
- 00:12:17so I fly behavior the interface are
- 00:12:20flying i kwok behavior the interface for
- 00:12:22quacking sorry we need to have
- 00:12:24my method yourself and you'll probably
- 00:12:27see later that we could probably
- 00:12:28generalize so I'm not going to do that
- 00:12:30in this video but you could probably
- 00:12:31generalize as well as that instead of
- 00:12:33making these two separate interfaces you
- 00:12:35could probably make them to say one same
- 00:12:37one so you could have maybe a duck
- 00:12:39behavior and this would be something
- 00:12:41more generic such as executes but just
- 00:12:44bear that in mind as we go forward so
- 00:12:45notice that we're making use of has a
- 00:12:47rather than isn't so that means that
- 00:12:49every duck must have a quack behavior
- 00:12:53and every duck must have a fly behavior
- 00:12:57what are them flag behaviors ok let's
- 00:12:59start to think about them as algorithms
- 00:13:01previously we said that wild ducks and
- 00:13:04sticky ducks they have the same quoc
- 00:13:07behavior and they have the same fly
- 00:13:09behavior so these are the same here in
- 00:13:12terms of flying and in terms of quacking
- 00:13:15and previously we achieve that through
- 00:13:17inheritance but now we're saying okay if
- 00:13:21this is an interface an interface for
- 00:13:23quacking and every duck has a quat
- 00:13:27behavior has a concrete quoc behavior at
- 00:13:30remember this is an interface so it's
- 00:13:33not instantiate able so something needs
- 00:13:36to implement again this is inherits or
- 00:13:39implements in terms of an interface some
- 00:13:41kind of quoc behavior and if these
- 00:13:44previously were in the base class let's
- 00:13:46call them something like simple or
- 00:13:47default all right so that's a simple
- 00:13:49simple walk I should probably put simple
- 00:13:52quack behavior to increase semantics and
- 00:13:53make it easier for other developers and
- 00:13:55to indicate to them that we're making
- 00:13:57use of something like strategy pattern
- 00:13:59we want to be super clear look at the
- 00:14:01name is something like simple quacks
- 00:14:02strategy and this would be quark
- 00:14:04strategy for example these are naming
- 00:14:07discussions but never underestimate the
- 00:14:09power of naming your things in a way
- 00:14:12that makes it understandable for your
- 00:14:14code developers never underestimate so
- 00:14:17let's say that we have a simple quote
- 00:14:18behavior that that implements the
- 00:14:20interface I I quote behavior and then
- 00:14:22let's say that this quantum ESSID
- 00:14:24previously had an implementation we had
- 00:14:26implementation of quark in here let's
- 00:14:28now say that instead one of the
- 00:14:31method delegates to the quark behavior
- 00:14:34that this duck the instance of the duck
- 00:14:36happens to have so if this particular
- 00:14:39duck happens to have a simple kwok
- 00:14:41behavior then when we call Kwok we will
- 00:14:44run whatever is in here sorry of course
- 00:14:46this should be walk so we run the
- 00:14:48contents of this method if we've
- 00:14:51composed an instance if we create an
- 00:14:53instance of a duck that has the simple
- 00:14:55kwok behavior this is possible because
- 00:14:58this Kwok man this duck has an IKE walk
- 00:15:02behavior or I mean we could trivially we
- 00:15:05could of course do this it has a simple
- 00:15:07Kwok behavior but that's this is
- 00:15:09significantly less flexible this creates
- 00:15:12class explosions so what we're doing is
- 00:15:15that we're saying that all we need to
- 00:15:17know is that it has something which is
- 00:15:18quotable why because remember we have
- 00:15:22the rubber duck the rubber duck had no
- 00:15:24quacking behavior so then we simply
- 00:15:27implement another concrete class a no
- 00:15:29Kwok behavior that also of course
- 00:15:32implements the interface I quark
- 00:15:34behavior so we have now no Kwok
- 00:15:37behaviors and we have simple Kwok
- 00:15:39behaviors and suddenly we can take these
- 00:15:41two different algorithms these two
- 00:15:43different strategies these two in this
- 00:15:45case different behaviors and put them in
- 00:15:48places and use them to compose new
- 00:15:51things that behave differently depending
- 00:15:53on which one they have so a duck can now
- 00:15:56we can now say that the duck class it
- 00:15:58doesn't need to care about quacking its
- 00:16:00subclasses that doesn't need to don't
- 00:16:02need to care about quacking the duck
- 00:16:04class only needs to ensure that whenever
- 00:16:07it is an instance it has a Kwok behavior
- 00:16:10if it happens to have an O Kwok behavior
- 00:16:13it won't go on if it happens to have a
- 00:16:15simple walk behavior it will quacks
- 00:16:17simply whatever that simple quacking
- 00:16:20means and then we do exactly the same
- 00:16:22thing for fly behavior so we say let's
- 00:16:26let's use the same terminology let's say
- 00:16:27that we have simple fly behavior here as
- 00:16:29well so we have simple flying as a
- 00:16:32method fly and implements the interface
- 00:16:35flag behavior so those two other ducks
- 00:16:38that we talked about before the
- 00:16:39Mountain duck and the was that the cloud
- 00:16:43the duck silly name sorry the mounted
- 00:16:45like the clown duck these two if I
- 00:16:48remember correctly wasn't it so that we
- 00:16:50said they share the same flying behavior
- 00:16:53but the flying behavior that they share
- 00:16:56that flying behavior that both of them
- 00:16:58share is not the same as the flying
- 00:17:00behavior that we previously had in the
- 00:17:01base class which is now the simple
- 00:17:04flying behavior here because we've moved
- 00:17:06we've done exactly the same thing with
- 00:17:08fly that we did with kwok we said that
- 00:17:10okay actually ducks any duck must have a
- 00:17:14concrete fly behavior it has anything
- 00:17:17that is that implements I fly behavior
- 00:17:20right it must have a concrete fly
- 00:17:22behavior but instead of saying that we
- 00:17:24it has a concrete flying behavior any
- 00:17:26particular one we're saying anything
- 00:17:29that has that implements the interface
- 00:17:31fly behavior will suffice
- 00:17:33just as we move the logic here away from
- 00:17:37the quack behavior away from the kwok
- 00:17:39method into concrete quark behaviors
- 00:17:42here and here right in the same way and
- 00:17:45we did that have we taken a fly behavior
- 00:17:48we've taken a fly behavior from here and
- 00:17:50moved it into here which now means that
- 00:17:54in our previous example where we had the
- 00:17:57mountain duck and the cloud duck that
- 00:17:59both shared a fly behavior that was
- 00:18:01different from this particular fly
- 00:18:04behavior we can now trivially solve that
- 00:18:06problem by introducing another fly
- 00:18:09behavior that is I don't know what their
- 00:18:12fly behavior would be called but let's
- 00:18:13jet fly behavior right so so jet fly
- 00:18:18behavior ah again semantics link that's
- 00:18:21at least named them according to the
- 00:18:22same convention so jet flying I have
- 00:18:25some engine supported flying whatever
- 00:18:27and it has the fly method so again the
- 00:18:30names are silly but I think you can see
- 00:18:32sort of how we're stringing together the
- 00:18:33pieces so let's let's draw the same
- 00:18:35thing again
- 00:18:35so here the code that's in here is not
- 00:18:39what was previously in here but what was
- 00:18:41previously in when we had let's let's
- 00:18:45reintroduce let's say that we had the
- 00:18:46cloud duck we have the cloud duck before
- 00:18:50so
- 00:18:51there we had a fly method there we had a
- 00:18:54fly method and it had some logic and
- 00:18:56we've taken that logic and we've moved
- 00:18:58it here into the jet flying behavior and
- 00:19:02into the fly method of a jet flying
- 00:19:05class and sorry I forgot to draw this
- 00:19:07arrow we should of course had a jet
- 00:19:08flying implements fly behavior so simple
- 00:19:12flying implements fly behavior and jet
- 00:19:15flying implements fly behavior and a
- 00:19:18duck has a fly behavior which means that
- 00:19:21a duck can have jet flying behavior or
- 00:19:23it can have simple flying behavior if
- 00:19:26you start to think about this I've
- 00:19:27talked about this is in a previous video
- 00:19:29I really think that this is one of those
- 00:19:31four critical moments where you start to
- 00:19:33realize that we need inheritance much
- 00:19:35much less than some people make us
- 00:19:38believe it's I think very common to sort
- 00:19:40of go through schooling or or go through
- 00:19:43a common object-oriented examples and
- 00:19:45then think that inheritance is very very
- 00:19:47powerful and that it applies to very
- 00:19:49many scenarios but actually in this case
- 00:19:51where we have a very flexible system
- 00:19:53looking at these parts and we suddenly
- 00:19:55realize that we don't actually need
- 00:19:57these middle parts assuming of course
- 00:20:00that displaying would be the same in
- 00:20:03this in this in this example that they
- 00:20:05have I actually think the display the
- 00:20:07point is the display method is different
- 00:20:09so what we could do is of course we can
- 00:20:12do the same thing for display we could
- 00:20:14inject the display behavior or we could
- 00:20:16we could extract the display behavior to
- 00:20:19an interface and then saying that a duck
- 00:20:22has a display behavior let's actually do
- 00:20:24it just for the sake of X before the air
- 00:20:26for the sake of the example but let me
- 00:20:27just first remove this so we want to get
- 00:20:29rid of this display behavior and this
- 00:20:31display behavior so we do exactly the
- 00:20:33same thing I don't even know what this
- 00:20:34is what they do in the book but I mean
- 00:20:35it makes perfect sense and it's that
- 00:20:36strategy pattern so just hang high
- 00:20:38display actually I just realized that I
- 00:20:42was super inconsistent with the naming I
- 00:20:44mean the interface is our neighbor
- 00:20:46mmm-hmm behavior but on this side we've
- 00:20:50got simple quark and a simple quacking
- 00:20:53and here we've got simple flying and not
- 00:20:57simple fly so that was totally
- 00:20:59inconsistent
- 00:20:59apologies in order to save your time I
- 00:21:02won't change that
- 00:21:03but I would never check in I would never
- 00:21:05commit source code like this I would
- 00:21:06absolutely change it so that the naming
- 00:21:08is consistent to another developer this
- 00:21:10is super confusing right it would
- 00:21:12indicate if I would read code that was
- 00:21:15written like this I would it would
- 00:21:16indicate to me that this is a completely
- 00:21:19different concept that this concept
- 00:21:21because the grammar is different but the
- 00:21:23words are suffix differently so I would
- 00:21:25think that they are they're different
- 00:21:26concepts but yeah in order to save our
- 00:21:28time let's just now you know let's move
- 00:21:30on so let's say that we have an I
- 00:21:32display I display behavior so I display
- 00:21:36behavior same thing we have a display
- 00:21:38method display and now we can then say
- 00:21:41that okay if the city ducks display
- 00:21:43strategy is different from the display
- 00:21:46strategy of the wild duck then we at
- 00:21:48least need two concrete classes so now
- 00:21:51since we don't know what what these
- 00:21:53would be right I mean if if we I would
- 00:21:55if we would now end up in a scenario
- 00:21:56where we would say that okay I want the
- 00:21:58most sensible thing I can think of to
- 00:22:01name the display behavior would be city
- 00:22:03duck display and while the duck display
- 00:22:06then I mean then there's probably zero
- 00:22:09need for strategy pattern because as the
- 00:22:12name implies there is zero reuse in that
- 00:22:15code there is there's no intention of
- 00:22:18reusing that is display behavior for
- 00:22:20city ducks because we've renamed its
- 00:22:22safety duck display behavior but for the
- 00:22:25sake of the example and just to sort of
- 00:22:26show you this in absurdum let's say that
- 00:22:28we are intending some reuse of the
- 00:22:30display behavior so let's say that this
- 00:22:31would be I mean I am very hard time
- 00:22:34coming up with examples for well what
- 00:22:36the different display behaviors would be
- 00:22:37but let's just do something silly so
- 00:22:39let's say that this would be display
- 00:22:42graphically that's one display behavior
- 00:22:45and the other display behavior as you
- 00:22:47might guess is display just say as a
- 00:22:50string or as text as tanks so we have
- 00:22:53this place text behavior and we have
- 00:22:55displayed graphically behavior behind
- 00:22:57again naming I'm so sloppy so maybe this
- 00:23:00should be display as graphics and
- 00:23:02displays text and both these of course
- 00:23:04implement the eye display
- 00:23:07so a display display as graphics is an I
- 00:23:11display behavior and display as text is
- 00:23:14an I display behavior or rather they
- 00:23:17both implement I display behavior what
- 00:23:19does this mean
- 00:23:20okay if you start to now look at what we
- 00:23:22have that means that our specific
- 00:23:24overriding are are are the thing that
- 00:23:27was previously city ducks were
- 00:23:29responsible for displaying they were
- 00:23:31responsible for that's the only logic
- 00:23:33they're adding they are by definition
- 00:23:35because of inheritance they are ducks so
- 00:23:38they get all all the stuff that ducks
- 00:23:40have but they were saying that actually
- 00:23:42city ducks have special displaying
- 00:23:44behavior and that displaying behavior we
- 00:23:47put here but let's say that that
- 00:23:49displaying behavior most displays
- 00:23:51graphics and I'm trying to see the
- 00:23:52digger example makes no sense but I mean
- 00:23:54bear with me so assume that what does
- 00:23:56what was special about that once that we
- 00:23:58wanted to display its graphics if we now
- 00:24:01have the I display behavior and we say
- 00:24:04that the duck has an I display behavior
- 00:24:07so that's that's this is getting messy
- 00:24:09let's just reiterate the duck has a
- 00:24:11quack behavior a doc hasn't display
- 00:24:14behavior a duck has a flying behavior
- 00:24:17but that's on abstract level that's on a
- 00:24:19class level and then when you create
- 00:24:20instances you need to make sure that
- 00:24:22that duck has something that implements
- 00:24:24these three different interfaces so that
- 00:24:27could be a duck that has a simple quark
- 00:24:29behavior and a jet flying behavior or it
- 00:24:32could be a duck that has an O quark
- 00:24:34behavior and a jet flying behavior so if
- 00:24:36it had a simple flying behavior and it
- 00:24:39had no quack behavior I was going to say
- 00:24:41that that would have been the the rubber
- 00:24:43duck but maybe it wasn't bad maybe it
- 00:24:45was that the rubber duck couldn't fly
- 00:24:46but could quacks oh I've messed that up
- 00:24:48but I think you see what I'm saying by
- 00:24:50creating these classes you can create
- 00:24:52another one no flying behavior fly does
- 00:24:55nothing this one also implements the fly
- 00:24:58behavior which means that we can now
- 00:24:59have no flying behavior which means that
- 00:25:01we gotta duck there's no fly we a turn
- 00:25:03no quark behavior that would definitely
- 00:25:04be a rubber duck but back to the display
- 00:25:07behaviors so if the doc now also has
- 00:25:10display behaviors we have the display
- 00:25:12method here
- 00:25:13suddenly now the display method makes
- 00:25:15use of a display behavior so when we
- 00:25:19call the display method we invoke the
- 00:25:21display method in whichever display
- 00:25:24method which are a concrete display
- 00:25:26meant that we happen to have and we can
- 00:25:28do that because we know that we have
- 00:25:30something that is and I display behavior
- 00:25:32let me just as parenthesis also say that
- 00:25:34it seems like with this example that I'm
- 00:25:37somehow arguing that interfaces would be
- 00:25:39more appropriate than the subclass this
- 00:25:42whole thing with the behaviors could of
- 00:25:44course have be done using sub classing
- 00:25:46we could have said that I quad behavior
- 00:25:48is a class and so you can give ducks the
- 00:25:51kwok behavior but you can also give it
- 00:25:53something that inherits from the quark
- 00:25:54behavior entirely possible and but that
- 00:25:56mainly depends on your scenario and
- 00:25:57again as soon as you get into
- 00:25:59inheritance you you can have this
- 00:26:01problem that we started with so it's
- 00:26:03kind of interesting but I mean the
- 00:26:04problem that we started with could be
- 00:26:06exhibited within a single behavior
- 00:26:09hierarchy so you start to introduce
- 00:26:11quark behaviors and then you experience
- 00:26:13the same problem that we had in the
- 00:26:15beginning the same problem of wanting to
- 00:26:16reuse code horizontally within the
- 00:26:18behaviors so then maybe you would have
- 00:26:20strategies that make use of strategies
- 00:26:22so you know you can dig far into this
- 00:26:24but everything of course entirely
- 00:26:25depends on the requirements in your
- 00:26:28scenario that's more let's finish up
- 00:26:30this thing with the display behaviors
- 00:26:31where I wanted to go regarding
- 00:26:33introducing display behavior as well as
- 00:26:35a strategy right again remember these
- 00:26:37are strategies we call them behaviors
- 00:26:40but they are strategies in the strategy
- 00:26:41pattern sense for the there are abstract
- 00:26:44strategies whereas these are concrete
- 00:26:48these are concrete strategies now that
- 00:26:51we have these we realize that even
- 00:26:53displaying in these ducts is completely
- 00:26:56unnecessary there's no need to override
- 00:26:59display in these subclasses because we
- 00:27:01can simply give a duck a particular
- 00:27:04display behavior and thus compose a duck
- 00:27:07that behaves as a city duck so actually
- 00:27:09we remove these now and suddenly there's
- 00:27:12no need for any sunglasses we have cloud
- 00:27:16ducks and mouse
- 00:27:17ducks and the city ducks and wild ducks
- 00:27:20and rubber duck and all these ducks
- 00:27:22right now suddenly these are no longer
- 00:27:25named classes in the system they are a
- 00:27:27particular configuration of instances of
- 00:27:30behaviors so given a combination of
- 00:27:33different strategies given a combination
- 00:27:35of different algorithms we happen to
- 00:27:37call some of these combinations
- 00:27:39different things so if it flies in a
- 00:27:41particular when it quacks in a
- 00:27:42particular way and it's displayed in a
- 00:27:43particular way that we call that a wild
- 00:27:45duck if it flies in the same way and the
- 00:27:48quarks in a different way we call it
- 00:27:50some other documents so forth and so
- 00:27:51forth what I haven't talked about I sort
- 00:27:53of glanced over this is dependency
- 00:27:55injection right that is only possible if
- 00:27:58these behaviors are somehow injected
- 00:28:01into an instance of a duck and not
- 00:28:04hard-coded in the class if if the class
- 00:28:07actually hard holds these things then we
- 00:28:11can't do that anymore so let's just very
- 00:28:13very quickly look at what that would
- 00:28:15look like let me remove all of this
- 00:28:17stuff and we'll look at some cold very
- 00:28:19very very quickly
- 00:28:20okay sort of pseudo coding yeah a class
- 00:28:23it's called a duck as we sent this duck
- 00:28:25has fly behavior quat behavior and
- 00:28:28display behavior so let's let's make
- 00:28:30these members by the way I put eyes in
- 00:28:33the beginning just to denote that their
- 00:28:34interface is by convention it has no
- 00:28:36other meaning so we put these as
- 00:28:38properties in the class and I could of
- 00:28:40course say that this member equals a new
- 00:28:44some particular fly behavior but if I
- 00:28:47did that it wouldn't be as flexible we
- 00:28:50need to somehow inject the behavior
- 00:28:52right this would hard-code the
- 00:28:55dependency and put me back in a state
- 00:28:57where i need multiple classes to
- 00:28:59represent all of these different types
- 00:29:01of ducks and it's just think about it
- 00:29:04it's significantly less impossible so
- 00:29:07instead let me just say that i have that
- 00:29:09member and the key here is if we use
- 00:29:11constructor injection we look at the
- 00:29:13constructor so we say we
- 00:29:14constructor public duck and it takes
- 00:29:17some arguments the question is what
- 00:29:18arguments well we need a flying behavior
- 00:29:21we need a quant behavior and we need a
- 00:29:22display behavior so let's just take
- 00:29:24those so well take something off time
- 00:29:27fly behavior and let me just call it FB
- 00:29:31to save space and we'll take a quack
- 00:29:35behavior and again just QB to save space
- 00:29:38and a display behavior calling it DB and
- 00:29:44that's it that's the constructor the
- 00:29:46signature of the constructor so let's
- 00:29:49open this up and we'll close it here and
- 00:29:51what are the contents of the constructor
- 00:29:53right in the constructor we set these
- 00:29:55all those extremely silly I forgot the
- 00:29:58variable names here I'm sorry so just to
- 00:30:00save space again that's the same thing
- 00:30:01that's say that the flying behavior is
- 00:30:03called FB the coop behavior is called QB
- 00:30:05and the display behavior is called DB
- 00:30:08again please bear in mind never
- 00:30:11underestimate the power of semantics and
- 00:30:15underestimate the power of good naming
- 00:30:17so I'm just doing this here because I
- 00:30:19managed it in space in your program make
- 00:30:21use of proper variable names
- 00:30:23okay so then end the constructor we just
- 00:30:25take these arguments that we've been
- 00:30:26passed in and set these other variables
- 00:30:29we take the variables we get passed in
- 00:30:31through the constructor and set the
- 00:30:33values of them to our instance variables
- 00:30:36so we just say this not f b this.f b is
- 00:30:40to be super clear I should do this so
- 00:30:42here we have F b QB for kwok behavior DB
- 00:30:45for display behavior and then here we
- 00:30:48have F B for Kwok for fly behavior QB
- 00:30:51for quad behavior and DB for display
- 00:30:54behavior and then we set these variables
- 00:30:57so this don't FB for flag behavior is
- 00:31:00equal to the fly behavior that
- 00:31:02passing this dog Kwok behavior the
- 00:31:05instance variable quark behavior is the
- 00:31:07kwok behavior that we passed in as an
- 00:31:09argument to the constructor and finally
- 00:31:11the display behavior on an instance
- 00:31:14level is a display behavior that we
- 00:31:16passed in that's it right sorry of
- 00:31:19course that's not it fly behaviors for
- 00:31:21example of course have the fly method so
- 00:31:24when we when we call fly on a class duck
- 00:31:27we need to invoke the fly behavior here
- 00:31:29I don't really have space for that here
- 00:31:31but let's just say that
- 00:31:32let me put bolt here and then you just
- 00:31:35continue that over here wha
- 00:31:38again just continue that over here sorry
- 00:31:41public void fly takes no arguments and
- 00:31:45has some implementation what is that
- 00:31:47implementation what that implementation
- 00:31:49is just to invoke so what we do is we
- 00:31:52say this dot
- 00:31:54FB this fly behavior the instance level
- 00:31:57fly behavior that will have there will
- 00:32:00be a concrete instance I was passed in
- 00:32:02in the constructor this flag behavior
- 00:32:05adult fly because that was the the name
- 00:32:08of the method when we were designing a
- 00:32:09class diagram and then we do exactly the
- 00:32:12same thing so I won't do it here because
- 00:32:13I think you can Cesar the pattern we do
- 00:32:15exactly the same thing for a quat
- 00:32:16behavior and for display behavior so you
- 00:32:19pass in a behavior and then you execute
- 00:32:22that behavior within the class so now
- 00:32:26ducks very independently or how any
- 00:32:31particular concrete quark behaviors of
- 00:32:34fly behaviors actually vary and that's
- 00:32:37the key point before we wrap up let's
- 00:32:39quickly look at the generalized UML
- 00:32:42diagram for strategy pattern let me just
- 00:32:44clean this up so we would simply be
- 00:32:46something like this you have a client in
- 00:32:48our case a duck and that client has some
- 00:32:53eye behavior and that eye behavior can
- 00:32:57be implemented by it's an interface or
- 00:32:59an abstract class or class but it's an
- 00:33:01interface that
- 00:33:02it can be implemented by many concrete
- 00:33:05behaviors so complete behavior a common
- 00:33:08baby and so forth and of course this I
- 00:33:11was kind of sloppy with before but of
- 00:33:12course the client needs to have a
- 00:33:13reference to I behavior so it has an
- 00:33:17instance of an AI behavior I didn't draw
- 00:33:19this in the previous diagrams but I
- 00:33:21think you can figure out how that's
- 00:33:22drawn so that we can say execute for
- 00:33:25execute behavior and then the AI
- 00:33:27behavior has an execute method actually
- 00:33:30there my name is run to emphasize that
- 00:33:33this method is entirely different from
- 00:33:35this so the execute would execute the
- 00:33:37run method of the behavior I execute it
- 00:33:41takes the behavior that we have here and
- 00:33:43runs the run method here and these
- 00:33:46concrete behaviors have specialized run
- 00:33:49methods and that's it that's strategy
- 00:33:51pattern the only thing that made it
- 00:33:53complex before is that we had multiple
- 00:33:56kinds of strategies we have fly
- 00:33:57strategies and quark strategies and
- 00:33:59display strategies but if you only have
- 00:34:01one it's it's it's this simple
- 00:34:03so now if we read this again I'm sure it
- 00:34:04makes a lot of more sense so the
- 00:34:06strategy pattern defines a family of
- 00:34:08algorithms right encapsulate each one
- 00:34:12write it capsule it's the whole
- 00:34:14algorithm here the whole algorithm here
- 00:34:16and makes them interchangeable right
- 00:34:18because they are both eye behaviors I
- 00:34:20should of course have said strategy or
- 00:34:23to make it more sensible in terms of
- 00:34:24strategy pattern but makes them
- 00:34:26interchangeable because since they act
- 00:34:28as the same type whenever you have an ID
- 00:34:30havior you can take any of the concrete
- 00:34:31algorithms so it makes them
- 00:34:33interchangeable and thus strategy lets
- 00:34:36the algorithm vary independently from
- 00:34:38the clients that use it
- 00:34:39so these algorithm this can vary just as
- 00:34:42much as it wants
- 00:34:42this can vary just as much as it wants
- 00:34:44without having to change the code here
- 00:34:47that's the power of strategy pattern I
- 00:34:51highly recommend this book if you want
- 00:34:53to get a good introduction to design
- 00:34:54patterns that's it remember to subscribe
- 00:34:56so that you won't miss the next video on
- 00:34:59the next design pattern from this book
- 00:35:02remember we're going through 13 of them
- 00:35:05thanks for watching I hope that's useful
- 00:35:08and I'll see you in the next one
- modèle de stratégie
- composition
- héritage
- design patterns
- algorithmes
- canards
- exemples pratiques
- programmation orientée objet
- flexibilité
- réutilisation du code