我们先来看下述代码
/**
* @Author ChenJiahao(程序员五条)
* @Date 2021/8/23 20:22
*/
public class Main {
public static void main(String[] args) {
// String fruit = "apple";
// String fruit = "orange";
String fruit = "banana";
if ("apple".equals(fruit)){
System.out.println("吃到了 Apple ~~~~~~~");
}else if ("banana".equals(fruit)){
System.out.println("吃到了 Banana ~~~~~~");
}else {
System.out.println("吃到了 Orange ~~~~~~");
}
}
}
看似么得问题,if一判断,然后做出对应的输出。
缺点:如果还想吃西瓜的话,还得继续加if判断,同时也不方便水果的统一管理,并且这样做不符合OCP原则(对扩展开放,对修改关闭)。
核心思想:通过工厂获取对应的策略(具体的水果),通过策略接口去执行具体的方法
优点:代码简洁,方便管理,扩展性较好
/**
* @Author ChenJiahao(程序员五条)
* @Date 2021/8/23 20:42
*/
public interface FruitHandler extends InitializingBean {
void eatFruit();
}
说明:
继承InitializingBean的原因是它包含一个方法afterPropertiesSet,这个方法将在所有的属性被初始化后调用。在这里的作用是让实现类在初始化后就将自身自动注册到工厂中(工厂的Map中)。
/**
* @Author ChenJiahao(程序员五条)
* @Date 2021/8/23 20:44
*/
public class FruitStrategyFactory {
private static Map fruitStrategyMap = new HashMap<>();
public static FruitHandler getStrategyMap(String fruitName){
return fruitStrategyMap.get(fruitName);
}
public static void registerHandler(String handlerName, FruitHandler handler){
fruitStrategyMap.put(handlerName,handler);
}
}
说明:
transferStrategyMap:用来存储具体的水果策略,key为上述if中的判断条件,value为FruitHandler类型的实现类(相当于把原先的if判断交给了map)
getTransferStrategyMap():获取对应的FruitHandler(key通常为原先if中的判断条件,需要自己去规定)
registerHandler():在策略接口的实现类在afterPropertiesSet()方法中利用registerHandler()方法将当前实现类注册到fruitStrategyMap中
注意:需要加@Component(SpringBoot项目)
/**
* @Author ChenJiahao(程序员五条)
* @Date 2021/8/23 20:48
*/
@Component
public class AppleHandler implements FruitHandler {
@Override
public void eatFruit() {
System.out.println("吃到了 Apple ~~~~~~");
}
@Override
public void afterPropertiesSet() throws Exception {
FruitStrategyFactory.registerHandler("apple",this);
}
}
/**
* @Author ChenJiahao(程序员五条)
* @Date 2021/8/23 20:49
*/
@Component
public class BananaHandler implements FruitHandler {
@Override
public void eatFruit() {
System.out.println("吃到了 Banana ~~~~~~");
}
@Override
public void afterPropertiesSet() throws Exception {
FruitStrategyFactory.registerHandler("banana",this);
}
}
/**
* @Author ChenJiahao(程序员五条)
* @Date 2021/8/23 20:51
*/
@Component
public class OrangeHandler implements FruitHandler {
@Override
public void eatFruit() {
System.out.println("吃到了 Orange ~~~~~~");
}
@Override
public void afterPropertiesSet() throws Exception {
FruitStrategyFactory.registerHandler("orange",this);
}
}
说明:
1.在eatFruit()方法中进行原先的if中要执行的方法
2.在afterPropertiesSet()方法中将自身注册到工厂的Map中
FruitStrategyFactory.getStrategyMap(fruit).eatFruit();
步骤:
1.编写WatermelonHandler类,实现FruitHandler接口
2.在eatFruit()方法中编写:System.out.println(“吃到了 Watermelon ~~~~~~”);
3.在afterPropertiesSet()中将WatermelonHandler注册到工厂的Map中
以上三步即可,原先调用的代码不需要任何改变
// 使用设计模式之前
if ("apple".equals(fruit)){
System.out.println("吃到了 Apple ~~~~~~~");
}else if ("banana".equals(fruit)){
System.out.println("吃到了 Banana ~~~~~~");
}else {
System.out.println("吃到了 Orange ~~~~~~");
}
// 使用设计模式之后
FruitStrategyFactory.getStrategyMap(fruit).eatFruit();
1.工厂
2.策略接口
3.策略实现类
4.面向工厂Map中的策略去调用
注意:工厂Map中的key,需要自己根据实际情况去制定(这个key通常为原先if中的判断条件)
如果是普通的Java项目,策略接口就不用继承InitializingBean了(没意义了),也不需要@Component
在调用FruitStrategyFactory的getStrategyMap()方法之前手动将具体的实现类注册到工厂的Map中。
示例如下
// 将各个实现类手动注册到工厂的Map中
FruitStrategyFactory.registerHandler("apple",new AppleHandler());
FruitStrategyFactory.registerHandler("banana",new BananaHandler());
FruitStrategyFactory.registerHandler("orange",new OrangeHandler());
// 调用
FruitStrategyFactory.getStrategyMap(fruit).eatFruit();
想阅读更多设计模式相关文章,欢迎到我的专栏【学习笔记】、【设计模式】中去查看
感谢大家看到这里,文章如有不足,欢迎大家指出;如果你觉得写的还不错,那就给我一个赞吧,欢迎大家关注和转发文章!