hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

战略形式和工场形式搭配运用

2019-11-18杂谈搜奇网21°c
A+ A-

战略形式和工场形式的搭配运用能够很好地消弭代码if-else的多层嵌套

需求

针对店下商店,有如许一个需求,对用户客户分为了一般客户、vip客户、超等vip用户、专属vip用户4个品级,每当用户购置商品时,针对差别的用户品级和消耗金额采纳差别的打折优惠战略。在寻常的开辟当中,必然会涌现多层的if-else嵌套推断,先推断用户的品级再推断用户购置商品的消耗金额。

弊病

以上的状况涌现了多层的if-else嵌套,除此之外,今后假如需求再有更改,须要再增添一个用户品级,那末又会再次增加if-else的嵌套推断,那末怎样处理上述的弊病呢,采纳战略形式和工场形式的搭配运用,能够很好地优化多层if-else的多层嵌套

完成

编写用户品级罗列类

package com.zbiti.ifelse.UserType;

/**
 * 用户范例罗列类
 */
public enum UserPayServiceEnum {

    VIP(1,"Vip"),

    SUPERVIP(2,"SuperVip"),

    PARTICULALYVIP(3,"ParticularlyVip"),

    NORMAL(4,"NormalPayService");



    /**
     * 状态值
     */
    private int code;

    /**
     * 范例形貌
     */
    private String value;

    private UserPayServiceEnum(int code, String value) {
        this.code = code;
        this.value = value;
    }
    public int getCode() {
        return code;
    }

    public String getValue() {
        return value;
    }

    public static UserPayServiceEnum valueOf(int code) {
        for (UserPayServiceEnum type : UserPayServiceEnum.values()) {
            if (type.getCode()==code) {
                return type;
            }
        }
        return null;
    }
    public static void main(String[] args) {
        System.out.println(UserPayServiceEnum.VIP.getValue());
    }

}

编写差别的用户品级战略类

以下须要注重的是每一个战略类完成了InitializingBean接口的作用是每当战略类被spring容器启动初始化后会挪用afterPropertiesSet要领,而在这个要领内里的作用是会往工场里针对差别用户品级保留其对应的用户战略援用

编写打折接口

差别的用户品级战略类完成该接口,该接口包含了打折要领

package com.zbiti.ifelse.UserType;

import java.math.BigDecimal;

public interface UserPayService {
    /**
     * 盘算敷衍价钱
     */
    public BigDecimal quote(BigDecimal orderPrice);
}

编写一般用户战略类

package com.zbiti.ifelse.UserType;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 一般会员不打折原价
 */

//完成InitializingBean接口,容器启动后会挪用afterPropertiesSet()要领,往工场里写入打折战略
@Service
public class NormalPayService implements UserPayService, InitializingBean {
    @Override
    public BigDecimal quote(BigDecimal orderPrice) {
        return new BigDecimal("10");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        UserPayServiceStrategyFactory.register(UserPayServiceEnum.NORMAL.getValue(), this);
    }

}

编写vip用户战略类

package com.zbiti.ifelse.UserType;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 一般会员打9折,消耗超100打8折
 */

//完成InitializingBean接口,容器启动后会挪用afterPropertiesSet()要领,往工场里写入打折战略
@Service
public class VipPayService implements UserPayService, InitializingBean {
    @Override
    public BigDecimal quote(BigDecimal orderPrice) {
        if (orderPrice.compareTo(new BigDecimal("100")) > 1) {
            return new BigDecimal("8");
        }
        return new BigDecimal("9");
    }

    public void myShow(){
        System.out.println("myShow method invoke----->");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        UserPayServiceStrategyFactory.register(UserPayServiceEnum.VIP.getValue(), this);
    }

}

编写超等vip用户战略类

package com.zbiti.ifelse.UserType;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 超等会员打8折
 */
@Service
public class SuperVipPayService implements UserPayService , InitializingBean {
    @Override
    public BigDecimal quote(BigDecimal orderPrice) {
        return new BigDecimal("8");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        UserPayServiceStrategyFactory.register(UserPayServiceEnum.SUPERVIP.getValue(),this);
    }
}

编写专属用户vip战略类

package com.zbiti.ifelse.UserType;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 专属会员 下单消耗超30打七折
 */
@Service
public class ParticularlyVipPayService implements UserPayService, InitializingBean {
    @Override
    public BigDecimal quote(BigDecimal orderPrice) {
        if (orderPrice.compareTo(new BigDecimal("30"))>0) {
            return new BigDecimal("7");
        }
        return new BigDecimal("8");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        UserPayServiceStrategyFactory.register(UserPayServiceEnum.PARTICULALYVIP.getValue(),this);
    }
}

编写工场类

注重这里工场的register要领,该要领会在spring容器启动初始化bean即各个差别品级的用户战略类完成后挪用afterPropertiesSet要领里挪用register要领,当容器启动完成后,我们的spring容器中即有了一个键为用户品级,值为用户品级战略类的map,在对差别用户举行优惠打折的时刻,能够依据用户品级来取得当前用户的战略类

package com.zbiti.ifelse.UserType;

import org.springframework.util.Assert;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 版本二:工场运用(高等版)
 */
//@Service
public class UserPayServiceStrategyFactory {

    private static Map<String,UserPayService> services = new ConcurrentHashMap<String,UserPayService>();

    public  static UserPayService getByUserType(String type){
        return services.get(type);
    }

    public static void register(String userType,UserPayService userPayService){
        Assert.notNull(userType,"userType can't be null");
        services.put(userType,userPayService);
    }
}

编写测试类

package com.zbiti.ifelse;

import com.zbiti.ifelse.UserType.UserPayService;
import com.zbiti.ifelse.UserType.UserPayServiceStrategyFactory;
import com.zbiti.ifelse.UserType.VipPayService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.math.BigDecimal;

@SpringBootTest
@Slf4j
class IfElseApplicationTests {

    @Test
    void contextLoads() {
        calPrice();
    }

    public  void calPrice() {
        BigDecimal orderPrice = new BigDecimal("100");
        String vipType = "Vip";
        //指定用户范例,取得相对应的战略
        UserPayService strategy = UserPayServiceStrategyFactory.getByUserType(vipType);
        
//        UserPayService strategy2 = UserPayServiceStrategyFactory2.getByUserType(vipType);

        System.out.println(strategy);
//        System.out.println(strategy2);
        BigDecimal quote = strategy.quote(orderPrice);
        if(strategy instanceof VipPayService){
           ((VipPayService) strategy).myShow();
        }
        System.out.println(quote);
    }

}

效果

能够看到vip用户打9折,在这个差别用户品级购置商品时采纳的差别打折战略里,我们没有涌现了多层的if-else的嵌套

tips

编写工场类的完成体式格局上面是个中一种完成(比较引荐),别的也有别的的体式格局,能够参考以下

提早将战略写入到map,然则这里须要手动new战略对象

package com.zbiti.ifelse.UserType;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 版本一:工场运用
 */
public class UserPayServiceStrategyFactory2 {

    private static Map<String,UserPayService> services = new ConcurrentHashMap<String,UserPayService>();

    public  static UserPayService getByUserType(String type){
        return services.get(type);
    }

    static{
        services.put(UserPayServiceEnum.VIP.getValue(), new VipPayService());
        services.put(UserPayServiceEnum.SUPERVIP.getValue(), new SuperVipPayService());
        services.put(UserPayServiceEnum.PARTICULALYVIP.getValue(), new ParticularlyVipPayService());
        services.put(UserPayServiceEnum.NORMAL.getValue(), new NormalPayService());
    }



}

也能够经由过程反射,编写工场类

package com.zbiti.ifelse.UserType;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 版本一:工场运用
 */
public class UserPayServiceStrategyFactory3 {

    private static Map<String, Class<? extends UserPayService>> services = new ConcurrentHashMap<>();

    //初始化map,寄存战略
    static {
        services.put(UserPayServiceEnum.VIP.getValue(), VipPayService.class);
        services.put(UserPayServiceEnum.SUPERVIP.getValue(), SuperVipPayService.class);
        services.put(UserPayServiceEnum.PARTICULALYVIP.getValue(), ParticularlyVipPayService.class);
        services.put(UserPayServiceEnum.NORMAL.getValue(), NormalPayService.class);
    }

    //猎取战略
    public static UserPayService getByUserType(String type) {
        try {
            Class<? extends UserPayService> userPayServiceClass = services.get(type);
            return userPayServiceClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return new NormalPayService();
        }

    }

}

实在也能够搭配注解的运用,自定义一个注解类,在战略类上标识上注解(值为差别的用户品级),容器启动的时刻经由过程扫描我们的自定义注解,写入map中也是能够的。

参考

if-else

if-else2

if-else3

本文由博客一文多发平台 OpenWrite 宣布!

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
战略形式和工场形式搭配运用

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282052.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>