设计模式-多重if的应用

设计模式-多重if的应用

文章目录

    • 设计模式-多重if的应用
        • 多重if代码示例
        • 改进
        • 代码
        • 参考资料

策略模式改进多重if结构

多重if代码示例

/**
 * 支付方式
 *
 * @author admin
 */
enum PayEnum {

    /**
     * 支付宝
     */
    ALI_PAY("ali", "支付宝支付"),
    /**
     * 微信
     */
    WECHAT_PAY("wechat", "微信支付"),
    /**
     * 银联
     */
    UNION_PAY("union", "银联支付");

    private String channel;
    private String desc;

    PayEnum(String channel, String desc) {
        this.channel = channel;
        this.desc = desc;
    }

    public static PayEnum getPayEnumByChannel(String channel) {
        PayEnum[] enums = PayEnum.values();
        for (PayEnum payEnum : enums) {
            if (payEnum.getChannel().equals(channel)) {
                return payEnum;
            }
        }
        return null;
    }

    public String getChannel() {
        return channel;
    }

    public String getDesc() {
        return desc;
    }

}

/**
 * @author admin
 */
public interface PayService {

    /**
     * 付款
     * @param channel
     * @param amount
     * @return
     * @throws Exception
     */
    String pay(String channel, String amount) throws Exception;
}
/**
 * @author admin
 */
class PayServiceImpl implements PayService {

    @Override
    public String pay(String channel, String amount) throws Exception {
        String payMsg = "您使用 %s ,消费了 %s 元";

        // 方式一
        if (PayEnum.ALI_PAY.getChannel().equals(channel)) {
            // 业务代码...
            return String.format(payMsg, PayEnum.ALI_PAY.getDesc(), amount);
        } else if (PayEnum.WECHAT_PAY.getChannel().equals(channel)) {
            // 业务代码...
            return String.format(payMsg, PayEnum.WECHAT_PAY.getDesc(), amount);
        } else if (PayEnum.UNION_PAY.getChannel().equals(channel)) {
            // 业务代码...
            return String.format(payMsg, PayEnum.UNION_PAY.getDesc(), amount);
        }

        // 如果没有业务代码...也可以用方式二
        // 方式二
        PayEnum payEnumByChannel = PayEnum.getPayEnumByChannel(channel);
        if (payEnumByChannel == null) {
            return "支付渠道码有误";
        }
        String payDesc = payEnumByChannel.getDesc();
        return String.format(payMsg, payDesc, amount);
    }
}

/**
 * @author admin
 */
public class App {

    public static void main(String[] args) throws Exception {
        PayService payService = new PayServiceImpl();
        String payResult = payService.pay("wechat", "100.58");
        System.out.println(payResult);
        String payResult2 = payService.pay("ali", "99.98");
        System.out.println(payResult2);
    }
}

改进

PayServiceImpl中存在多重if,支付方式可能还会变化,我们用策略模式对if结构改进。

  • PayEnum中添加beanName,用于反射创建对象
  • 各if分支转换为各个不同的策略

代码

/**
 * 支付方式
 * @author admin
 */
public enum PayEnum {

    /**
     * 支付宝
     */
    ALI_PAY("ali", "支付宝支付", "com.xxx.design.ifelse.AliPayStrategy"),
    /**
     * 微信
     */
    WECHAT_PAY("wechat", "微信支付", "com.xxx.design.ifelse.WechatPayStrategy"),
    /**
     * 银联
     */
    UNION_PAY("union", "银联支付", "com.xxx.design.ifelse.UnionPayStrategy");

    private String channel;
    private String desc;
    private String beanName;

    PayEnum(String channel, String desc, String beanName) {
        this.channel = channel;
        this.desc = desc;
        this.beanName = beanName;
    }

    public static PayEnum getPayEnumByChannel(String channel) {
        PayEnum[] enums = PayEnum.values();
        for (PayEnum payEnum : enums) {
            if (payEnum.getChannel().equals(channel)) {
                return payEnum;
            }
        }
        return null;
    }

    public String getChannel() {
        return channel;
    }

    public String getDesc() {
        return desc;
    }

    public String getBeanName() {
        return beanName;
    }
}

/**
 * @author admin
 */
public interface PayStrategy {

    String PAY_MSG = "您使用 【%s】 ,消费了 [%s] 元";

    /**
     * 支付
     * @param channel
     * @param amount
     * @return
     * @throws Exception
     */
    String pay(String channel, String amount) throws Exception;
}
/**
 * @author admin
 */
class AliPayStrategy implements PayStrategy {

    @Override
    public String pay(String channel, String amount) throws Exception {
        // 业务代码...
        return String.format(PAY_MSG, PayEnum.ALI_PAY.getDesc(), amount);
    }
}
/**
 * @author admin
 */
class WechatPayStrategy implements PayStrategy {

    @Override
    public String pay(String channel, String amount) throws Exception {
        // 业务代码...
        return String.format(PAY_MSG, PayEnum.WECHAT_PAY.getDesc(), amount);
    }
}
/**
 * @author admin
 */
class UnionPayStrategy implements PayStrategy {

    @Override
    public String pay(String channel, String amount) throws Exception {
        // 业务代码...
        return String.format(PAY_MSG, PayEnum.UNION_PAY.getDesc(), amount);
    }
}

工厂类

/**
 * @author admin
 */
public class PayFactory {

    private static Map<String, PayStrategy> beanMap = new HashMap<>();
    private static Object lock = new Object();

    public static PayStrategy getPayStrategy(String channel) {
        PayEnum payEnumByChannel = PayEnum.getPayEnumByChannel(channel);
        if (payEnumByChannel == null) {
            return null;
        }
		
        String beanName = payEnumByChannel.getBeanName();
        try {
            if (!beanMap.containsKey(beanName)) {
                synchronized (lock) {
                    if (!beanMap.containsKey(beanName)) {
                        PayStrategy instance = (PayStrategy)Class.forName(beanName).getDeclaredConstructor().newInstance();
                        beanMap.put(beanName, instance);
                        return instance;
                    } else {
                        return beanMap.get(beanName);
                    }
                }
            } else {
                return beanMap.get(beanName);
            }
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

/**
 * @author admin
 */
class PayServiceImpl implements PayService {

    @Override
    public String pay(String channel, String amount) throws Exception {
        PayStrategy payStrategy = PayFactory.getPayStrategy(channel);
        String paidResult = payStrategy.pay(channel, amount);
        return paidResult;
    }
}
package com.kornzhou.design.ifelse;

import com.kornzhou.design.ifelse.before.PayService;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @author admin
 */
public class App {

    public static void main(String[] args) throws Exception {
        PayService payService = new PayServiceImpl();
        for (int i = 0; i < 5; i++) {
            // 随机待支付金额
            String money = random(0, 1000);
            System.out.format("to pay amount: %s 元\n", money);

            // 随机选择支付方式支付
            int random = randomInt(0, PayEnum.values().length);
            PayEnum payEnum = PayEnum.values()[random];
            String payResult = payService.pay(payEnum.getChannel(), money);
            System.out.println(payResult);
        }
    }

    public static String random(int start, int end) {
        double random = Math.random();
        BigDecimal bigDecimal = new BigDecimal(random * (end - start) + start).setScale(2, RoundingMode.HALF_UP);
        return bigDecimal.toString();
    }

    public static int randomInt(int start, int end) {
        double random = Math.random();
        double v = random * (end - start);
        return (int)v;
    }
}

参考资料

你可能感兴趣的:(设计模式)