策略模式改进多重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结构改进。
/**
* 支付方式
* @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;
}
}