1.策略模式
- 好处:动态切换算法或行为
- 场景:实现同一功能用到不同的算法时
- 和简单工厂对比:简单工厂是通过参数创建对象,调用同一个方法(实现细节不同);策略模式是上下文切换对象,调用同一个方法(实现细节不同);前者着重创建出对象,后者着重灵活切换对象。
using System;// 01 定义通用接口
public interface IPaymentStrategy
{void Pay(decimal amount);
}// 02 写接口实现策略(这里写三个)
// 信用卡支付策略
public class CreditCardPayment : IPaymentStrategy
{public void Pay(decimal amount){Console.WriteLine($"Paid {amount:C} using Credit Card.");}
}// 支付宝支付策略
public class AlipayPayment : IPaymentStrategy
{public void Pay(decimal amount){Console.WriteLine($"Paid {amount:C} using Alipay.");}
}// 微信支付策略
public class WeChatPayment : IPaymentStrategy
{public void Pay(decimal amount){Console.WriteLine($"Paid {amount:C} using WeChat.");}
}// 03 写上下文类,用于切换策略(内置设置策略方法、执行策略方法)
public class PaymentContext
{private IPaymentStrategy _paymentStrategy;// 构造函数public PaymentContext(){}// 设置或更改支付策略public void SetPaymentStrategy(IPaymentStrategy paymentStrategy){_paymentStrategy = paymentStrategy;}// 执行支付public void ExecutePayment(decimal amount){_paymentStrategy.Pay(amount);}
}// 04 使用:构建上下文=>上下文设置策略=>上下文执行策略
class Program
{static void Main(string[] args){//构建上下文PaymentContext context = new PaymentContext();// 用户选择信用卡支付IPaymentStrategy creditCardPayment = new CreditCardPayment();context.SetPaymentStrategy(creditCardPayment);context.ExecutePayment(100.50m);// 用户更换为支付宝支付IPaymentStrategy alipayPayment = new AlipayPayment();context.SetPaymentStrategy(alipayPayment);context.ExecutePayment(200.75m);// 用户更换为微信支付IPaymentStrategy weChatPayment = new WeChatPayment();context.SetPaymentStrategy(weChatPayment);context.ExecutePayment(150.30m);}
}
2.模板方法模式
- 好处:制定灵活的算法结构,可重写某步算法实现多种算法不同实现效果(将共同的部分提取到父类中,避免了重复代码,维护简单)
- 场景:多种算法相似,相互有复用借鉴部分时
using System;namespace TemplateMethodPatternDemo
{// 01 定义一个算法框架抽象类// 抽象类,定义了制作饮料的模板方法public abstract class Beverage{// 模板方法,定义了制作饮料的固定步骤public void PrepareRecipe(){BoilWater();BrewOrSteep();PourInCup();AddCondiments();}// 固定步骤private void BoilWater(){Console.WriteLine("Boiling water...");}// 抽象方法,允许子类具体实现“冲泡”或“泡制”过程protected abstract void BrewOrSteep();private void PourInCup(){Console.WriteLine("Pouring into cup...");}// 抽象方法,允许子类实现“添加调味品”步骤protected abstract void AddCondiments();}// 02 写不同的算法,重写父类的非公共细节(这里举例两个)// 具体类:制作茶public class Tea : Beverage{// 茶的泡制过程protected override void BrewOrSteep(){Console.WriteLine("Steeping the tea...");}// 添加调味品:茶通常添加柠檬protected override void AddCondiments(){Console.WriteLine("Adding lemon...");}}// 具体类:制作咖啡public class Coffee : Beverage{// 咖啡的冲泡过程protected override void BrewOrSteep(){Console.WriteLine("Brewing the coffee...");}// 添加调味品:咖啡通常添加糖和牛奶protected override void AddCondiments(){Console.WriteLine("Adding sugar and milk...");}}// 03 根据不同对象调用,实现不一样的算法// 客户端代码class Program{static void Main(string[] args){Console.WriteLine("Making Tea...");Beverage tea = new Tea();tea.PrepareRecipe(); // 调用模板方法Console.WriteLine();Console.WriteLine("Making Coffee...");Beverage coffee = new Coffee();coffee.PrepareRecipe(); // 调用模板方法}}
}
3.责任链模式
- 好处:可动态调整处理链(增加或减少角色)、请求处理的责任分散(易维护)、可复用性强
- 用途:流程审批等(C#中switch不加break是不被允许的,因此这个设计模式很有意义)
using System;namespace ResponsibilityChainDemo
{// 审批任务类 (实体定义,是逐层传递的对象)public class Task{public double Amount { get; set; } // 金额,决定需要多少审批层级}// 01 写责任链基类(关系链设定方法、各角色职责抽象方法)// 审批人基类public abstract class Approver{protected Approver _NextApprover;public void SetNextApprover(Approver nextApprover){_NextApprover = nextApprover;}public abstract void Approve(Task task);}// 02 写各责任链角色类(继承责任链基类)的抽象方法的实现// 具体审批人:部门经理public class DepartmentManager : Approver{public override void Approve(Task task){if (task.Amount <= 5000){Console.WriteLine("部门经理审批通过: " + task.Amount);}else if (_NextApprover != null){Console.WriteLine("部门经理已审批,传递给下一层审批人.");_NextApprover.Approve(task);}}}// 具体审批人:总经理public class GeneralManager : Approver{public override void Approve(Task task){if (task.Amount <= 10000){Console.WriteLine("总经理审批通过: " + task.Amount);}else if (_NextApprover != null){Console.WriteLine("总经理已审批,传递给下一层审批人.");_NextApprover.Approve(task);}}}// 具体审批人:CEOpublic class CEO : Approver{public override void Approve(Task task){if (task.Amount > 10000){Console.WriteLine("CEO审批通过: " + task.Amount);}}}//03 责任链的使用class Program{static void Main(string[] args){// 创建角色Approver departmentManager = new DepartmentManager();Approver generalManager = new GeneralManager();Approver ceo = new CEO();// 设定角色位置(从底层到高层,依次设置)departmentManager.SetNextApprover(generalManager);generalManager.SetNextApprover(ceo);// 调用责任链方法Task task = new Task() { Amount = 12000 };departmentManager.Approve(task);}}
}
责任链的设定可以通过递归方式实现,写起来效果更好!这里展示的是最简单的demo。