23种设计模式完整教程
介绍
策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以互 相替换,此模式让算法的变化不会影响到使用算法的用户。
优点
1、策略模式符合开闭原则。
2、避免使用多重条件转移语句,如 if...else...语句、switch 语句
3、使用策略模式可以提高算法的保密性和安全性。
缺点
1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
2、代码中会产生非常多策略类,增加维护难度。
使用场景
1、假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。
2、一个系统需要动态地在几种算法中选择一种。
使用建议
实际的开发中使用的比较多,多重if...else...可以考虑使用这种方式。
具体实现
(实例一)选择不同的支付方式:
类图
代码
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class PayState {
private int code;
private Object data;
private String msg;
public PayState(int code, String msg,Object data ) {
this.code = code;
this.data = data;
this.msg = msg;
}
@Override
public String toString() {
return "支付状态:[" +code+"]" + "支付金额:" + data + "响应信息:" + msg ;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class Order {
private String uid;
private String orderId;
private double amount;
public Order(String uid, String orderId, double amount) {
this.uid = uid;
this.orderId = orderId;
this.amount = amount;
}
public PayState pay(){
return pay(PayStrategyFactory.PayTypeEnum.Default.getType());
}
public PayState pay(String payTypeKey){
Payment payment=PayStrategyFactory.getPayType(payTypeKey);
System.out.println("欢迎使用 " + payment.getName() + " 支付");
System.out.println("本次交易金额为:"+amount+",开始扣款...");
return payment.pay(uid,amount);
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
/**
* 支付渠道
*/
public abstract class Payment {
/**
* 支付方式
* @return
*/
public abstract String getName();
/**
* 查询余额
* @param uid
* @return
*/
public abstract double queryBalance(String uid);
public PayState pay(String uid,double amount){
if(queryBalance(uid)<amount){
return new PayState(500,"支付失败","余额不足");
}
return new PayState(200,"支付成功","支付金额:"+amount);
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class AliPay extends Payment {
@Override
public String getName() {
return "支付宝";
}
@Override
public double queryBalance(String uid) {
return 900;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class JDPay extends Payment {
@Override
public String getName() {
return "京东百度";
}
@Override
public double queryBalance(String uid) {
return 100;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class UnionPay extends Payment {
@Override
public String getName() {
return "银联支付";
}
@Override
public double queryBalance(String uid) {
return 120;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class WechatPay extends Payment{
@Override
public String getName() {
return "微信支付";
}
@Override
public double queryBalance(String uid) {
return 256;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
import java.util.HashMap;
import java.util.Map;
public class PayStrategyFactory {
private PayStrategyFactory() {}
private static Map <String, Payment> paymentMap=new HashMap <>();
static {
paymentMap.put(PayTypeKey.Default,new AliPay());
paymentMap.put(PayTypeKey.AliPay,new AliPay());
paymentMap.put(PayTypeKey.JDPay,new JDPay());
paymentMap.put(PayTypeKey.UnionPay,new UnionPay());
paymentMap.put(PayTypeKey.WechatPay,new WechatPay());
}
public static Payment getPayType(String payType){
Payment payment=paymentMap.get(payType);
return null==payment?paymentMap.get("Default"):payment;
}
//通过接口实现----工厂类外部不方便使用
private interface PayTypeKey{
String AliPay="AliPay";
String JDPay="JDPay";
String UnionPay="UnionPay";
String WechatPay="WechatPay";
String Default="Default";
}
//通过枚举实现----工厂类外部可方便的使用
public enum PayTypeEnum{
AliPay("AliPay"),
JDPay("JDPay"),
UnionPay("UnionPay"),
WechatPay("WechatPay"),
Default("Default"),
;
private String type;
PayTypeEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class Test {
public static void main(String[] args) {
Order order=new Order("11","3210000005679000009",10);
PayState state=order.pay(PayStrategyFactory.PayTypeEnum.JDPay.getType());
System.out.println(state.toString());
}
}
(实例二)不同的促销打折方式:
类图
代码
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 促销抽象类
*/
public interface PromotionStrategy {
void doPromotion();
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 优惠券
*/
public class CouponStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("领取优惠券,下单享受优惠券折扣");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 返现优惠
*/
public class CashBackStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("返现促销,返回的金额转到支付宝账户");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
public class EmptyStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("没有促销活动");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 团购优惠
*/
public class GroupBuyStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("拼团,满20人成团,全团享受团购价");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void execute(){
promotionStrategy.doPromotion();
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
import java.util.HashMap;
import java.util.Map;
public class PromotionStrategyFactory {
private PromotionStrategyFactory(){}
private static final PromotionStrategy defaultPromotion=new EmptyStrategy();
private static Map <String,PromotionStrategy> promotionStrategyMap=new HashMap<>();
static {
promotionStrategyMap.put(PromotionKey.CASHBACK,new CashBackStrategy());
promotionStrategyMap.put(PromotionKey.COUPON,new CouponStrategy());
promotionStrategyMap.put(PromotionKey.GROUTBUY,new GroupBuyStrategy());
}
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy =promotionStrategyMap.get(promotionKey);
return null==promotionStrategy?defaultPromotion:promotionStrategy;
}
private interface PromotionKey {
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String GROUTBUY = "GROUTBUY";
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
public class Test {
/*
1.替换 if...else switch...case
2.一个系统需要动态的在几种算法中选择一种
* */
public static void main(String[] args) {
System.out.println("策略模式测试");
//第一种,完全和实际脱轨
/*
PromotionActivity activity=new PromotionActivity(new GroupBuyStrategy());
PromotionActivity activity1=new PromotionActivity(new CashBackStrategy());
activity.execute();
activity1.execute();*/
//第二种,冗余了很多的if...else
/* PromotionActivity activity=null;
String promotionKey="COUPON";
if(promotionKey.equals("COUPON")) {
activity = new PromotionActivity(new CouponStrategy());
}
if(promotionKey.equals("CASHBACK")) {
activity = new PromotionActivity(new CashBackStrategy());
}
if(promotionKey.equals("GROUPBUY")) {
activity = new PromotionActivity(new GroupBuyStrategy());
}
activity.execute();*/
//为简化代码,引入单例模式与简单工厂,继续简化代码------史上最强策略模式
String promotionKey = "CASHBACK";
PromotionStrategy strategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey);
strategy.doPromotion();
}
}