Observer Pattern
Observer mode: Also known as the Publish subscription mode, defines a one-to-many dependency, allowing multiple observer objects to listen to a Subject object at the same time, when the state of the subject changes, it notifies all observer objects that they can automatically update themselves.
Code structure
Class Topic (object): "" " theme classes. Save references to all observer instances, each subject can have many observers to add and remove the Observer "" " def __init__ (self): self.obs = [] def Attach (self, OB): self.obs.append (ob) def Detach (self, OB): self.obs.remove (ob) def Notify (self): for ob in Self.obs: ob. Update () class Observer (object): "" " abstract Observer class, updates itself" "" Def update (self) when receiving a change notification for the subject : raise Notimplementederror () class Concretetopic (object): "" " a specific Theme" "" def __init__ (self): self.state = None def changestate (self, newstate): self.state = newstate self . Notify () class Concreteobserver (object): "" " a specific listener class" "" def __init__ (self, topic): self.topic = Topic def Update (self): print Self.topic.statedef client (): topic = concretetopic () topic. Attach (Concreteobserver (topic)) topic. Changestate (' New state ')
Many MQ middleware are implemented with the idea of this model.
The observer pattern allows for decoupling between the subject and the observer, with as few dependencies as possible between them. However, there is still a coupling between abstract subjects and abstract observers.
Policy mode
Strategy mode: Defines the algorithm family, which is encapsulated separately so that they can be replaced by each other. This pattern allows the algorithm to change without affecting the customer using the algorithm.
Code Framework
Class strategy (object): "" " Abstract Algorithm Class" "" def Algorithminterface (self): raise Notimplementederror () class Concretestrategya (strategy): def algorithminterface (self): print ' algorithm a ' class CONCRETESTRATEGYB (strategy): def algorithminterface (self): print ' algorithm B ' class context (object): "" " context, which is the implementation details of the encapsulation policy, the user only need to know what policies are available" "" def __init__ (self, Strategy): # Incoming specific policy instance when initializing Self.strategy = Strategy def contextinterface ( Self): # Interface responsible for invoking specific policy instances Self.strategy.AlgorithmInterface () def client (cond): # Use Demo for policy mode # The user only need to according to different conditions, the specific algorithm implementation class passed to the context, # and then call the context exposed to the user interface on the line. if cond = = ' A ': context = context (Concretestrategya ()) elif cond = = ' B ': context = context ( Concretestrategyb ()) result = context. Contextinterface ()
Policy mode solves that kind of problem
Before answering this question, let's start with the feeling of how the strategy pattern is used. The client function above, how does it look like a factory function in a simple Factory mode? Indeed, the strategy pattern can be combined with the simple factory pattern to encapsulate more detail within the policy model, making it easier for users to use.
So what's the difference between a strategy model and a simple factory model? The algorithm in the strategy mode is used to solve the same problem, the specific details of the algorithm differ according to the time and condition, but the same problem is solved in the end. When you hear the need to apply different business rules at different times during the requirements analysis, you can consider the possibility of using a policy model to handle this change.
Disadvantages
The user needs to know the specific meaning of each strategy and is responsible for selecting the policy
Improved
Combining the simple factory model, the policy selection is encapsulated within the context, freeing the client:
Class Context (object): def __init__ (self, cond): if cond = = ' A ': self.strategy = Context (Concretestrategya ()) elif cond = = ' B ': self.strategy = Context (Concretestrategyb ()) def contextinterface (self): Self.strategy.AlgorithmInterface () def client (cond): context = context (cond) result = context. Contextinterface ()
Legacy issues after improvement
Each time you need to add a new strategy, you need to modify the context's constructor to add a new branch of judgment.