Getting your head around Software Design Patterns can be a bit tricky, for me it is anyway. There seems to be lots of overlap and similarities and if you search for definitions and tutorials you'll often get slightly different versions and different examples in code that can make the whole thing even more confusing.
I tend to understand things better when they're laid out in practical steps, so I'm going to try to do that with this post. Each design pattern will be a set of logical steps to achieve that pattern, rather than an abstract definition or a code example where a Cat implements an Animal interface...
If you spot an error or could explain something better please contact me and let me know, genuinely I'm interested to hear feedback and improve my understanding, just don't be too harsh.
*fyi the picture represents the Factory pattern, it's not just a random car picture.
The formal definition:
The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
How I see it...
You've created a base class for an object but you've noticed that some behaviours or methods will be used differently by sub classes...
- When you identify a method or behaviour that needs to be different for different sub classes of your object write an interface for that method/ behaviour. (eg log() - some implementations may need to log to different media, so create a CreatesLogs interface).
- Create separate behaviour classes that implement that interface and bring one of those into your object to perform that behaviour/algorithm. (LogsToFile implements CreatesLogs, so now you can use MyClass->setLogger(new LogsToFile) or MyClass->setLogger(new LogsToScreen) to implement a different Logging Strategy).
- The main object now is composed of a behaviour object that handles that behaviour, it can be changed at any point as the object is only dependent on theCreatesLogs interface. The object can call it's log() method without caring how that is being implemented.
The formal definition
defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically
How I see it...
You have an object that ideally needs to send a message to other objects to say that something has changed internally.
- Create an Observable and an Observer interface.
- Implement the Observable interface on the class - usually includes registerObserver(), removeObserver() and notifyObserver().
- Each object that has an interest in changes to the main class should implement the Observer interface, this will generally just have an update(), or notified() method.
- In the Observable object whenever a change happens in another method just call the notifyObserver() method to send a message to all the 'listening' objects.
- The Observer objects should now deal with the message from the Observable however they see fit.
From what I can tell this pattern would become cumbersome should the Observer object wish to observe multiple Observable objects. You'd then end up with all kinds of nasty code in the update() method on the Observer, I guess when you start to get code 'smells' like this you're probably heading towards an Event Dispatcher kind of pattern.
Published: May 29, 2017 (1 year ago)