栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式-策略工厂

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式-策略工厂

设计模式-策略工厂 概念

​ 根据输入条件来由工厂动态产生符合条件的策略类对象,并调用相应策略方法实现功能

这么说可能有点抽象举一个例子,比如我们在生活中的自动售货机一样,他的电子屏幕上面展示不同的商品,当我们选择具体的商品后支付,售货机就会给我们相应的商品。这里 选择商品=输入条件,售货机=策略工厂类,我们保证条件在策略工厂中有具体的实现即可,这样策略工厂就能根据具体的条件来保证能拿到不同的策略实现类,再调用方法

使用场景

因为设计模式更多偏向于编程上的设计理念,应用场景本人也是用的不多,主要是储备以防不时之需,如果有大神不吝赐教的话万分感激,我这里主要用于多层if…else逻辑方案判断执行的解耦,比如考虑到后期的业务拓展,逻辑判断就会再次增加,需要在代码上修改,不管从扩展性还是代码整洁上看都不合适

原代码:

if(status == 0){
    //.....条件执行逻辑A
}else if(status == 1){
    //.....B
}else if(status == 2){
    //.....C
}

思路:

1.定义接口,不同条件下的执行封装成具体的接口实现类

2.由工厂统一管理策略实现类,根据策略的不同返回具体的实现类

接口类

public interface RefundInterface {

    void refund(OmOrdersBO omOrdersBO);
}

策略实现类

public class RefundZero implements RefundInterface {

    @Override
    public void refund(OmOrdersBO omOrderSBO, RedisTemplate redisTemplate) {
        // ....A具体实现逻辑A
    }
}

public class RefundOne implements RefundInterface {

    @Override
    public void refund(OmOrdersBO omOrderSBO) {
        // ...具体实现逻辑B
    }
}

public class RefundTwo implements RefundInterface {

    @Override
    public void refund(OmOrdersBO omOrderSBO) {
        // ...具体实现逻辑C
    }
}

工厂类

public class RefundStrategyFactory {
    private static final Map map = new HashMap<>();
	//   使用map进行存储策略类,后期再有扩展只需要增加具体的键值对
    static {
        map.put(OrderType.ZERO.ordinal(), new RefundZero());
        map.put(OrderType.ONE.ordinal(), new RefundOne());
        map.put(OrderType.TWO.ordinal(), new RefundTwo());
    }
   	public static RefundInterface getRefundStrategy(Integer type) {
        return map.get(type);
    }

工厂类构建完成,原来代码用RefundStrategyFactory.getRefundStrategy(Integer type)方法获得具体实现类,接口接收实现类,调用接口方法=具体的实现类方法

优化

实现了策略工厂模式的设计,优化了if…else的冗余结构后,再回过头来看看是否有优化的地方。定位工厂类,这里我们是用map存放具体的策略实现类,没有具体的动态实现,后期添加也还要继续添加

采用反射+注解的方式来对工厂类进行优化

1.自定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Refund {
    int number() default 0;
}

2.给实现类加注解(附带相应条件)

@Component
@Refund(number = 0)
public class RefundZero implements RefundInterface {

    @Override
    public void refund(OmOrdersBO omOrderSBO, RedisTemplate redisTemplate) {
        // ....A具体实现逻辑A
    }
}

@Component
@Refund(number = 1)
public class RefundOne implements RefundInterface {

    @Override
    public void refund(OmOrdersBO omOrderSBO) {
        // ...具体实现逻辑B
    }
}

@Component
@Refund(number = 2)
public class RefundTwo implements RefundInterface {

    @Override
    public void refund(OmOrdersBO omOrderSBO) {
        // ...具体实现逻辑C
    }
}

3.工厂类

这里工厂类做的事情主要分为几部分:

1.构造方法-执行获取策略类集合方法(拿到所有被注解的策略类)

2.getStrategyRefund(Integer refundType)方法–for遍历策略类集合,判断策略类上的注解参数是否和输入条件一致,一致则获取类的实例对象

​ 此时就得到了具体的策略工厂实现类

ps:这里策略工厂类RefundStrategyFactory和具体的实现类放一个包下,自己也可以去修改扫描路径

public class RefundStrategyFactory {

    private static final String PACKAGE = RefundStrategyFactory.class.getPackage().getName();

    private List> refundList = new ArrayList<>();

    private ClassLoader classLoader = getClass().getClassLoader();

    public static RefundStrategyFactory getInstance() {
        return FactoryInstance.instance;
    }

    public static class FactoryInstance {
        private static RefundStrategyFactory instance = new RefundStrategyFactory();
    }

    public RefundStrategyFactory() {
        //构造方法-----获取策略类集合
        getRefundList();
    }

    
    private List> getRefundList() {
        Class refundClazz = null;
        File[] resources = getResources();
        try {
            refundClazz = (Class) classLoader.loadClass(RefundInterface.class.getName());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("未找到策略接口");
        }
        for (int i = 0; i < resources.length; i++) {
            Class clazz = null;
            try {
                clazz = classLoader.loadClass(PACKAGE + "." + resources[i].getName().replace(".class", ""));
                if (RefundInterface.class.isAssignableFrom(clazz) && clazz != refundClazz) {
                    refundList.add((Class) clazz);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    
    private File[] getResources() {
        try {
            String SCAN_PACKAGE = RefundStrategyFactory.class.getPackage().getName();
            File file = new File(classLoader.getResource(SCAN_PACKAGE.replace(".", "/")).toURI());
            return file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    if (pathname.getName().endsWith(".class")) {
                        return true;
                    }
                    return false;
                }
            });
        } catch (URISyntaxException e) {
            throw new RuntimeException("未找到策略资源");
        }
    }

    
    public RefundInterface getStrategyRefund(Integer refundType) {
        for (Class clazz : refundList) {
            Refund annotation = clazz.getAnnotation(Refund.class);
            if (annotation.number() == refundType) {
                try {
                    return clazz.newInstance();
                } catch (Exception e) {
                    throw new RuntimeException("策略类获取失败");
                }
            }
        }
        return null;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/860293.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号