Original articles, reproduced please be sure to put the following paragraph at the beginning of the article.
This article is forwarded from Jason's Blog, the original link http://www.jasongj.com/design_pattern/strategy/ policy mode introduces the definition of the policy pattern
The policy model (strategy pattern) encapsulates various algorithms into a specific class as subclasses of an abstract policy class so that they can be interchanged. The client can decide which algorithm to use. policy Pattern class diagram
The policy mode class diagram is as follows
Strategic pattern Role Partitioning Strategy The Policy interface or (abstract policy Class), define the policy execution interface Concretestrategy the context class of the specific policy class, and hold an instance of the specific policy class, and is responsible for calling the relevant algorithm policy pattern Instance parsing
This article code can be downloaded from the author GitHub typical policy pattern implementation
Policy interface, defining policy execution interfaces
Package com.jasongj.strategy;
Public interface Strategy {
void Strategy (String input);
}
Specific policy classes, implement policy interfaces, provide specific algorithms
Package com.jasongj.strategy;
Import Org.slf4j.Logger;
Import org.slf4j.LoggerFactory;
@com. Jasongj.annotation.Strategy (name= "Strategya") Public
class Concretestrategya implements strategy {
private static final Logger LOG = Loggerfactory.getlogger (concretestrategyb.class);
@Override public
void strategy (String input) {
log.info ("Strategy A for Input: {}", input);
}
Package com.jasongj.strategy;
Import Org.slf4j.Logger;
Import org.slf4j.LoggerFactory;
@com. Jasongj.annotation.Strategy (name= "Strategyb") Public
class Concretestrategyb implements strategy {
private static final Logger LOG = Loggerfactory.getlogger (concretestrategyb.class);
@Override public
void strategy (String input) {
log.info ("Strategy B for Input: {}", input);
}
The context class, which holds instances of specific policy classes, is responsible for calling specific algorithms
Package com.jasongj.context;
Import Com.jasongj.strategy.Strategy;
public class SimpleContext {
private strategy strategy;
Public SimpleContext (Strategy strategy) {
this.strategy = strategy;
}
public void Action (String input) {
strategy.strategy (input);
}
}
The client can instantiate the specific policy class and pass it to the context class to call the specific algorithm
Package com.jasongj.client;
Import Com.jasongj.context.SimpleContext;
Import Com.jasongj.strategy.ConcreteStrategyA;
Import Com.jasongj.strategy.Strategy;
public class SimpleClient {public
static void Main (string[] args) {
strategy strategy = new Concretestrategya () ;
SimpleContext context = new SimpleContext (strategy);
Context.action ("Hellow, World");
}
using annotation and simple factory patterns to enhance policy patterns
In the above implementation, the client needs to show which policy to use and, if necessary, to change the client's code. A good way to solve this problem is to use a simple factory, so that the client does not need to know the policy class instantiation process, even does not need specific which strategy is used.
As described in the Java Design pattern (a) simple factory pattern, simple factories are implemented in more ways that can be combined with the Annotation method described in the Java Series (a) Annotation (annotations).
The context classes that use the annotation and simple factory patterns are as follows
Package com.jasongj.context;
Import java.util.Collections;
Import Java.util.Map;
Import Java.util.Set;
Import Java.util.concurrent.ConcurrentHashMap;
Import org.apache.commons.configuration.ConfigurationException;
Import org.apache.commons.configuration.XMLConfiguration;
Import org.reflections.Reflections;
Import Org.slf4j.Logger;
Import Org.slf4j.LoggerFactory;
Import Com.jasongj.strategy.Strategy; public class Simplefactorycontext {private static final Logger LOG = Loggerfactory.getlogger (simplefactorycontext.clas
s);
private static map<string, class> allstrategies;
static {Reflections Reflections = new Reflections ("Com.jasongj.strategy"); set<class<?>> annotatedclasses = Reflections.gettypesannotatedwith (com.jasongj.annotation.Strategy.cl
ASS);
Allstrategies = new concurrenthashmap<string, class> (); for (class<?> classobject:annotatedclasses) {com.jasongj.annotation.Strategy strategy = (Com.jasongj.annota tion.
Strategy) Classobject. Getannotation (Com.jasongj.annotation.Strategy.class);
Allstrategies.put (Strategy.name (), classobject);
} allstrategies = Collections.unmodifiablemap (allstrategies);
Private strategy strategy;
Public Simplefactorycontext () {String name = null;
try {xmlconfiguration config = new Xmlconfiguration ("Strategy.xml");
Name = Config.getstring ("Strategy.name");
Log.info ("strategy name is {}", name);
The catch (ConfigurationException ex) {Log.error ("Parsing XML configuration file failed", ex);
} if (Allstrategies.containskey (name)) {Log.info ("Created strategy name is {}", name);
try {strategy = (strategy) allstrategies.get (name). newinstance (); catch (Instantiationexception |
Illegalaccessexception ex) {log.error ("Instantiate strategy failed", ex);
} else {log.error ("Specified strategy name {} does not exist", name); }} publicvoid action (String input) {strategy.strategy (input); }
}
As can be seen from the above implementation, although there is no separate creation of a simple factory class, but it has been integrated into the simple factory model design ideas and implementation methods.
The client invokes the following method
Package com.jasongj.client;
Import Com.jasongj.context.SimpleFactoryContext;
public class Simplefactoryclient {public
static void Main (string[] args) {
Simplefactorycontext context = new Sim Plefactorycontext ();
Context.action ("Hellow, World");
}
From the above code, it can be seen that after the introduction of the simple factory pattern, the client no longer needs to instantiate the specific policy class directly, nor does it need to decide which policy to use, and it is convenient to switch the policy. Policy Mode Analysis The policy mode Benefits Policy pattern provides the perfect support for the open and closed principle, which allows users to select an algorithm (policy) without modifying the original system, and to flexibly add new algorithms (policies). The policy pattern provides a way to manage specific policy classes (algorithm families) through the context class. Combined with simple Factory mode and annotation, the policy model can easily switch the algorithm (policy) without modifying the client code. policy Pattern Disadvantage the traditional way of implementing a policy pattern is that the client must know all the specific policy classes and should show itself which policy class they decide to use. But through the introduction of this article and the combination of annotation and simple factory patterns, can effectively avoid this problem if used improperly, the policy pattern may create many instances of specific policy classes, but you can effectively reduce the number of objects by using the pattern of benefits described in the Java design mode (11) pattern above. the OOP principles that the policy mode has (not) followed OOP principles followed dependency inversion principle Dimitri Principle Interface Isolation Principle single duty principle open and closed principle not followed OOP principle NA Java design Pattern series Java Design pattern (i) Simple Factory mode not simple Java design pattern (ii) factory method pattern Java design Pattern (iii) abstract Factory mode Java design pattern (IV) Observer mode Java design pattern (v) Combinatorial mode Java design pattern (vi) proxy mode VS . Decorative mode Java design mode (vii) Spring AOP JDK dynamic proxy vs. Cglib Java design mode (eight) adapter mode Java design mode (ix) bridging mode Java design mode (10) You really use the single example mode? Java design mode (11) Enjoy meta mode Java design mode (12) Policy mode