在订单支付的时候,常常会选择使用哪种支付方式进行支付?为了在客户端避免掉switch或if else语句来判断,可以采用策略模式+工厂来实现。
定义支付接口,和实现了该接口的两个类 AliPay 和 WechatPay
namespace StrategyPattern.pay { public interface Payment { PayState Pay(int userId, decimal amount); } }
namespace StrategyPattern.pay { public class AliPay : Payment { public PayState Pay(int userId, decimal amount) { Console.WriteLine("欢迎使用支付宝"); Console.WriteLine("查询账户余额,开始扣款"); return new PayState(200, "支付成功", amount); } } }
namespace StrategyPattern.pay { public class WechatPay : Payment { public PayState Pay(int userId, decimal amount) { Console.WriteLine("欢迎使用微信支付"); Console.WriteLine("查询账户余额,开始扣款"); return new PayState(200, "支付成功", amount); } } }
定义支付结果
namespace StrategyPattern { /// <summary> /// 支付状态 /// </summary> public class PayState { public int Code { get; set; } public string Msg { get; set; } public object Data { get; set; } public PayState(int code, string msg, object data) { this.Code = code; this.Data = data; this.Msg = msg; } public override string ToString() { return ("支付状态:[" + Code + "]," + Msg + ",交易详情:" + Data); } } }
定义一个订单类
namespace StrategyPattern { public class Order { public int UserId { get; set; } public string OrderId { get; set; } public decimal Amount { get; set; } public Order(int userId,string orderId,decimal amount) { this.UserId = userId; this.OrderId = orderId; this.Amount = amount; } public PayState Pay(Payment payment) { return payment.Pay(UserId, Amount); } } }
假设现在我们在客户端需要自己去new一个具体的支付方式,是这样做的
namespace StrategyPattern { class Program { static void Main(string[] args) { Order order = new Order(1, "2020040900100001", 200.99m); PayState payState = order.Pay(new AliPay()); Console.WriteLine(payState); Console.ReadLine(); } } }
但是为了在客户端不直接去new,定义了一个枚举和其扩展方法,该扩展方法相当于使用了工厂
namespace StrategyPattern.pay { public enum PayType { ALI_PAY, WECHAT_PAY, } }
namespace StrategyPattern.pay { public static class PayTypeExtension { public static Payment GetPayment(this PayType payType) { switch (payType) { case PayType.ALI_PAY: return new AliPay(); case PayType.WECHAT_PAY: return new WechatPay(); default: return null; } } } }
然后在客户端调用的时候就可以直接使用 PayType.WECHAT_PAY 来调用,所以前端只需要传入对应的枚举值就行了
namespace StrategyPattern { class Program { static void Main(string[] args) { Order order = new Order(1, "2020040900100001", 200.99m); PayState payState = order.Pay(PayType.WECHAT_PAY.GetPayment()); Console.WriteLine(payState); Console.ReadLine(); } } }