Articles
Software
Gallery
Other works
Contacts

#The strategy pattern is really bad.html



         For clarity, I would first like to state that I'm specifically referring to what OOP
        depicts as THE strategy pattern. If we restrict our selves to the definition of
        "behaviour as data", procedural function pointers and much of functional programming
        becomes examples to the strategy pattern. Those work pretty well, I take no offense
        to their existence.
         On the other hand, if we take a look at the OOP side, its not all so rosy suddenly.
        There seems to be multiple reasons to apply the strategy pattern:
    
            .=======================.
            I Reasons to strategize I
            `=======================`
               │
               │  .------------------.    
               ├──| Trivially needed |    
               │  |    new class     |    
               │  `------------------`    
               │
               │  .------------------.
               └──| Cope for lack of |
                  |  free functions  |
                  `------------------`

         So, as I was attempting to come up with a simpler example than HFDP's duck hierarchy,
        I kept coming up with concepts that scream "I AM MY OWN CLASS". For example ĐMagicwandĐs
        with engraved behaviour, but then there was no way to gaslight the reader that the
        concept we are arriving to is not a ĐSpellĐ. Then as I applied complexity, I realized
        the whole dilemma of this design arose from being unable to pinpoint the problem
        and not it being inherently harder than say prototyping a function.
         For the second part I wish you to refer to the previously mentioned duck example.
        However, assuming you are unable to reference the original or dont care enough,
        here is the quick rundown:
            > Your current design contains the following hierarchy
                          ┏━━━━━━━━━━━━━━━━━┓
                          ┃   class Duck    ┃
                          ┣━━━━━━━━━━━━━━━━━┫
                          │ var duckyness;  │
                          │ void quack();   │
                          └─────────────────┘
                           /                \
                          /                  \
                         /                    \
                        /                      \
                       /                        \
                      /                          \
            ┏━━━━━━━━━━━━━━━━━━━━┓    ┏━━━━━━━━━━━━━━━━━━━━┓
            ┃ class MallardDuck  ┃    ┃ class ReadHeadDuck ┃
            ┣━━━━━━━━━━━━━━━━━━━━┫    ┣━━━━━━━━━━━━━━━━━━━━┫
            │ var duckyness;     │    │ var duckyness;     │
            │ void quack();      │    │ void quack();      │
            └────────────────────┘    └────────────────────┘
            > You are asked to add a RubberDuck
            > Oh no! rubber ducks cannot quack! they squeak
            > After juggling terrible ideas such as a quackable interface implemented by the children,
               Strategies save the day
    
                                        ┏━━━━━━━━━━━━━━━━━┓                                            ┏━━━━━━━━━━━━━━━━━┓
                                        ┃   class Duck    ┃                                            ┃ interface Quack ┃
                                        ┣━━━━━━━━━━━━━━━━━┫                                            ┣━━━━━━━━━━━━━━━━━┫
                                        │ var duckyness;  │                                            │ void quack();   │
                                        │ var quack;      │                                            └─────────────────┘ 
                                        └─────────────────┘                                            |                 |
                                       /         |         \                                           |                 |
                                      /          |          \                                          |                 |
                                     /           |           \                                         |                 |
                                    /            |            \                                        |                 |
                                   /             |             \                                       |                 |
                                  /              |              \                                      |                 |
            ┏━━━━━━━━━━━━━━━━━━━━┓    ┏━━━━━━━━━━━━━━━━━━━━┓     ┏━━━━━━━━━━━━━━━━━━━━┓                |                 |
            ┃ class MallardDuck  ┃    ┃ class ReadHeadDuck ┃     ┃ class RubberDuck   ┃          .-----------.     .-------------.
            ┣━━━━━━━━━━━━━━━━━━━━┫    ┣━━━━━━━━━━━━━━━━━━━━┫     ┣━━━━━━━━━━━━━━━━━━━━┫         | class Quack |   | class Squeak |
            │ var duckyness;     │    │ var duckyness;     │     │ var duckyness;     │          `---,-------`     `-------------`
            │ var quack;         │    │ var quack;         │     │ var quack;         │-  -  -  -  -  -  -  -  -  -  -  -'
            └────────────────────┘    └────────────────────┘     └────────────────────┘              : 
                       :                         :                                                    
                       '-  -  -  -  -  -  -  -  -'-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  '
         Ok, now lets think about this critically. The quack interface describes a single behaviour
        that does not require internal state.
         We used to have those things actually, they were called functions.
         Seriously, 2 new classes and 1 additional interface is introduced to describe 2 behaviours.
        Our source got more complex, bloated, dependant -as there are new couplings, never mind how
        close they are-, and more verbose to extend. If thats not a work around I dont know what is.
         Digging a little further, does Quack look encapsulated to you? Because to me she seems like a
        free use whore pretending to be better than her ancestors under the banner of self-expression,
        but I digress.
         As a minor note, I would like to poke fun, how without optimizations the ABOVE will be
        oh-so-slightly slower than the procedural equivalent because now we have to instantiate
        quacks amongst other things.
                           
         "But Anon, you ignored rockets being strapped to ducks during the simulation,\
        which modifies their fly behaviour" - I hear you say. You are correct.
        This does mean that we will have to change behaviour at runtime.
        Which, again, leaves us with scenario 1. Procedurally speaking, having a strategy
        would be a pattern avoiding strangely placed and convoluted logical blocks, but
        to replicate the problem in OOP, you would need a hierarchy of strangely placed
        and convoluted logical blocks, at which point it should be obvious to anyone
        something ĐĐveryĐĐ wrong is going on.