[TOC]
The strategy pattern defines a family of algorithms, encapsulates each algorithm, and makes the algorithms interchangeable within that family. Strategy lets the algorithm vary independently from clients that use it. (Wikipedia)
see see Understanding the pitfalls of inheritance and interfaces
see Programming Foundations: Desin Patterns
see Programming Foundations: Desin Patterns
see Programming Foundations: Desin Patterns
Make the constructor private and create a public static method that returns the single private static instance of the class if it exists. Otherwise, lazily creates a new instance and returns it.
class Singleton {
private static Singleton instance;
private Singleton() {...}
public static Singleton getlnstance () {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
There are no private constructors in python, so we could make the whole singleton class "private" and wrap it in a another class of the same name that is responsible for controling creation of an instance and assigning it to a class property __instance.
class OnlyOne(object):
class __OnlyOne: ...
__instance = None
def __new__(cls): # __new__ always a classmethod
if not OnlyOne.__instance:
OnlyOne.instance = OnlyOne.__OnlyOne()
return OnlyOne.__instance
def __getattr__(self, name):
return getattr(self.instance, name)
def __setattr__(self, name):
return setattr(self.instance, name)
(based on The Singletone)
A more concise version simply checks whether a class instance already exists. If it doesn't, then create one before returning it. Otherwise just return it.
class Singleton(object):
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance
But, if we want lazy instantiation, then we must move object creation to a static getInstance() method as we did with the Java implementation.
class Singleton:
__instance = None
def __init__(self): pass
@classmethod
def getInstance(cls):
if not cls.__instance:
cls.__instance = Singleton()
return cls.__instance
(Giridhar 84)
[TOC]
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods... It is mainly used to implement distributed event handling systems, in "event driven" software... is also a key part in the familiar model–view–controller (MVC) architectural pattern.
see also The Advantages of loose coupling
use pub/sub for even looser coupling.
class Observable:
def __init__(self):
self.__observers = []
def register_observer(self, observer):
self.__observers.append(observer)
def notify_observers(self, *args, **kwargs):
for observer in self.__observers:
observer.notify(self, *args, **kwargs)
class Observer:
def __init__(self, observable):
observable.register_observer(self)
def notify(self, observable, *args, **kwargs):
print('Got', args, kwargs, 'From', observable)
subject = Observable()
observer = Observer(subject)
subject.notify_observers('test')
(adapted from Observer pattern)
Note, the absence of persistant state in this simple example. Observer pattern is being used to pass values to registered observers rather than notify state change!
With push, the subject notifies th observer that ists data is ready and includes the relevant info that the observer is subscribing to, whereas with the pull design, it is the observer's job to retrieve the info from the subject.
Pull places heavier load on the observers, allows observer to qu3ery only when data is actually needed, ie., on-demain access. This however, requires that observers have public access to subject, and risks pulling data in the middle of an update.
Push is more common b/c simpler and safer. Data and data transfer in subject's control and there is no need to worry about observer pulling data during update.
see EPI
Pub/Sub mediator, typically provided by third-party library, sits between publisher and subscribers and mediates communication, such that neither knows about the other: Publisher makes a broadcast and mediating logic routes to everyone listening. This, effects a decoupling. Conversely, Subjects are passed a reference to each observer that registers with it, maintains a list of registered observers, and notifies them directly of any state changes (in the case of push implementation), usually by calling one of their methods! In the case of a pull implementation, subject and observer are even more tightly coupled, as observers are granted public access to the subject's data!
https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Design-Patterns-Observer-and-Publish-Subscribe
See also Publisher/Subscriber pattern with Event/Delegate and EventAggregator. As far as I can tell, Event/Delegate is a C# implementation of observer pattern as we have defined it above (though they call it publisher/subscriber), and EventAggregator is an implementation of what we are calling pub/sub, where there is a mediating class (EventAggregator), that sits between publisher and subscribers.
http://python-3-patterns-idioms-test.readthedocs.io
Giridhar, Chetan. Learning Python Design Patterns: Leverage the Power of Python Design Patterns to Solve Real-World Problems in Software Architecture and Design. 2016.
(Giridhar xxx)