concept
Strategy Pattern, also called Policy Pattern, in which the behavior of a class or its algorithm can be changed at runtime. This type of design pattern is a behavioral pattern.
The strategy mode generally mainly includes three roles:
- Context : The context environment used to operate the strategy, shielding the client's direct access to the strategy and algorithm, and encapsulating possible changes
- Abstract strategy (Strategy) : prescribes the behavior of a strategy or algorithm
- Concrete Strategy (ConcreteStrategy) : the concrete realization of strategy or algorithm
achieve
Next, take the payment method scenario as an example
1. Create an abstract strategy
public abstract class Payment {
abstract String getName();
}
2. Create a specific strategy
public class AliPay extends Payment {
@Override
String getName() {
return "欢迎使用支付宝支付";
}
}
public class WeChatPay extends Payment{
@Override
String getName() {
return "欢迎使用微信支付";
}
}
3. Create the context
public class PayStrategy {
public static final String ALI_PAY="AliPay";
public static final String WECHAT_PAY="WeChatPay";
public static final String DEFAULT="AliPay";
public static Map<String ,Payment> map=new HashMap<String ,Payment>();
static {
map.put(ALI_PAY,new AliPay());
map.put(WECHAT_PAY,new WeChatPay());
}
public static Payment get(String name){
if (!map.containsKey(name)){
return map.get(DEFAULT);
}
return map.get(name);
}
}
4. Test
public class StrategyTest {
public static void main(String[] args) {
Payment pay=PayStrategy.get(PayStrategy.ALI_PAY);
System.out.println(pay.getName());
}
}
operation result:
scenes to be used
- There are many ways to deal with the same type of problem, each of which can solve the problem independently
- A system needs to dynamically select one of several algorithms
Application in Spring Framework
In the Spring DI process, the strategy mode is adopted during initialization.
There is an InstantiationStrategy interface
public interface InstantiationStrategy {
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
throws BeansException;
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
Constructor<?> ctor, @Nullable Object... args) throws BeansException;
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, Method factoryMethod, @Nullable Object... args)
throws BeansException;
}
There are also two strategy implementation classes, CglibSubclassingInstantiationStrategy and SimpleInstantiationStrategy. The
UML class diagram is as follows:
We found that the CglibSubclassingInstantiationStrategy strategy class inherits the SimpleInstantiationStrategy class, indicating that in actual use, multiple strategies can also be inherited and used
to sum up
advantage
- Good scalability, compound opening and closing principle
- Avoid using multiple conditional judgments, such as if...else, switch...case
- Algorithm can be switched freely
Disadvantage
- All strategy classes need to be exposed
- Will generate many strategy classes