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

java策略模式+工厂模式+模板模式

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

java策略模式+工厂模式+模板模式

策略模式+工厂模式+模板模式彻底取代 if...else...

策略模式:一种解耦的方法,它对算法进行封装,使得算法的调用和算法本身分离。使用策略模式客户端代码不需要调整,算法之间可以互相替换,因为不同的算法实现的是同一个接口。策略模式是一种对象行为型模式。策略模式符合“开闭原则”。

策略模式包括如下角色:

Context :环境类

Strategy:抽象策略类

ConcreteStrategy:具体策略类

代码实现:

枚举类:

public enum SubCostTypeEnum {

    GREATER0_IN_0UP(7, "原始>0,入库后>0"),
    EQUAL0_OUT_0DOWN(8, "原始=0,出库后<0"),

    ;

    private Integer value;
    private String description;

    private SubCostTypeEnum(Integer value, String description) {
        this.value = value;
        this.description = description;
    }

    public Integer value() {
        return value;
    }

    public String description() {
        return description;
    }

    public static SubCostTypeEnum valueOf(Integer value) {
        for(SubCostTypeEnum type : SubCostTypeEnum.values()) {
            //if(type.value() == value) {
            if(type.value().equals(value)) {
                return type;
            }
        }
        return null;
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class KcBook {
    private BigDecimal beforeQty;
    private BigDecimal beforeAmount;
    private Integer direction;
    private BigDecimal qty;
    private BigDecimal price;
    private BigDecimal afterQty;
    private BigDecimal afterAmount;
}

定义策略接口:

org.springframework.beans.factory.InitializingBean#afterPropertiesSet内部实现工厂注册。用于实现环境的统一工厂。

public interface RechargeHandler extends InitializingBean {
    public BigDecimal getAvgPrice(KcBook kcBook) {
        System.out.println("getAvgPrice");
        return new BigDecimal("0");
    }

    public void getRechargeName(SubCostTypeEnum subCostType) {
        System.out.println("默认: " + subCostType);
    }
}

实现策略工厂:

public class StrategyHandlerFactory {
    private static Map strategyMap = new ConcurrentHashMap<>();

    
    public static CostHandler getInvokeStrategyMap(SubCostTypeEnum subCostType) {
        return strategyMap.get(subCostType);
    }

    
    public static void register(SubCostTypeEnum subCostType, CostHandler handler) {
        if (null == subCostType || null == handler) {
            return;
        }
        strategyMap.put(subCostType, handler);
    }
}

各成员实现各自的策略实现类:

@Component
public class SubCost1Handler implements CostHandler {
    @Override
    public void getRechargeName(SubCostTypeEnum subCostType) {
        System.out.println("1: " + subCostType);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        StrategyHandlerFactory.register(SubCostTypeEnum.GREATER0_IN_0UP, this);
    }

    @Override
    public BigDecimal getAvgPrice(KcBook kcBook) {
        System.out.println("getAvgPrice");
        BigDecimal tmp = kcBook.getBeforeAmount().add(kcBook.getQty().multiply(kcBook.getPrice())).divide(kcBook.getBeforeQty().add(kcBook.getQty()), 2, BigDecimal.ROUND_HALF_UP);
        System.out.println("getAvgPrice:" + tmp) ;
        return tmp;
    }
}

如有其它新类型业务,值需要实现对应的策略即可。

test

    @Test
    public void test01(){
        SubCostTypeEnum subCostType = null;
        CostHandler costHandler = null;

        subCostType = SubCostTypeEnum.GREATER0_IN_0UP;
        costHandler = StrategyHandlerFactory.getInvokeStrategyMap(costType, subCostType);
        System.out.println(costHandler);
        KcBook kcBook = new KcBook(new BigDecimal("100"), new BigDecimal("150"), 1, new BigDecimal("2"), new BigDecimal("20"), new BigDecimal("120"), new BigDecimal("190"));
        BigDecimal avg = costHandler.getAvgPrice(kcBook);
        System.out.println(avg);
    }

使用模板模式改造策略模式接口:

上述实现,若策略接口新增了方法,那么所有实现了改策略接口的实现类都要进行修改,对现有已完成的类改动较大,使用先将其改为模板模式。

将原有接口改造为抽象类

public abstract class CostHandler implements InitializingBean {
    public void getRechargeName(SubCostTypeEnum subCostType) {
        System.out.println("默认: " + subCostType);
    }

    public BigDecimal getAvgPrice(KcBook kcBook) {
        System.out.println("getAvgPrice");
        return new BigDecimal("0");
    }
}

子类重新继承改抽象类即可

@Component
public class SubCost1Handler extends CostHandler {
    @Override
    public void getRechargeName(SubCostTypeEnum subCostType) {
        System.out.println("1: " + subCostType);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        StrategyHandlerFactory.register(SubCostTypeEnum.GREATER0_IN_0UP, this);
    }

    @Override
    public BigDecimal getAvgPrice(KcBook kcBook) {
        System.out.println("getAvgPrice");
        BigDecimal tmp = kcBook.getBeforeAmount().add(kcBook.getQty().multiply(kcBook.getPrice())).divide(kcBook.getBeforeQty().add(kcBook.getQty()), 2, BigDecimal.ROUND_HALF_UP);
        System.out.println("getAvgPrice:" + tmp) ;
        return tmp;
    }
}

这样,抽象类中增加了新的方法后,已有的子类在不需要新增方法时,可以不用调整。

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

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

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