23中设计模式--行为型模式
14.职责链模式
1 #region 14.职责链模式(Chain Of Responsibility)。把请求的发送者和接受者松耦合,让多个对象都有机会接受请求,将这些对象连成一条链,让请求沿着这条链进行传递,直到有对象处理它为止。 2 3 /// <summary> 4 /// 请求类 5 /// </summary> 6 public class PurchaseRequest 7 { 8 public double Amount { get; set; } 9 public string Number { get; set; } 10 public string Purpose { get; set; } 11 12 13 public PurchaseRequest(double amount, string number, string purpose) 14 { 15 this.Amount = amount; 16 this.Number= number; 17 this.Purpose = purpose; 18 } 19 } 20 21 /// <summary> 22 /// 抽象处理者 23 /// </summary> 24 public abstract class Approver 25 { 26 protected Approver successor; 27 protected string name; 28 29 public Approver(string name) 30 { 31 this.name = name; 32 } 33 public void SetSuccessor(Approver successor) 34 { 35 this.successor = successor; 36 } 37 38 public abstract void ProcessRequest(PurchaseRequest request); 39 } 40 41 /// <summary> 42 /// 总监,具体处理类 43 /// </summary> 44 public class Director : Approver 45 { 46 public Director(string name) : base(name) 47 { 48 } 49 50 public override void ProcessRequest(PurchaseRequest request) 51 { 52 if (request.Amount < 50000) 53 { 54 Console.WriteLine("主管 {0} 审批采购单: {1},金额: {2}元,采购目的: {3}。", this.name, request.Number, request.Amount, request.Purpose); 55 56 } 57 else 58 { 59 this.successor.ProcessRequest(request); 60 } 61 } 62 } 63 /// <summary> 64 /// 具体处理类 65 /// </summary> 66 public class VicePresident : Approver 67 { 68 public VicePresident(string name) : base(name) 69 { 70 } 71 72 public override void ProcessRequest(PurchaseRequest request) 73 { 74 if (request.Amount < 50000) 75 { 76 Console.WriteLine("主管 {0} 审批采购单: {1},金额: {2}元,采购目的: {3}。", this.name, request.Number, request.Amount, request.Purpose); 77 78 } 79 else 80 { 81 this.successor.ProcessRequest(request); 82 } 83 } 84 } 85 86 #endregion
15.观察者模式
1 #region 15.观察者模式(Observer)。定义对象之间的一种一对多的依赖关系,使得当每一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。 2 3 /// <summary> 4 /// 抽象观察者 5 /// </summary> 6 public interface IObserver 7 { 8 string Name { get; set; } 9 void Help(); 10 void BeAttacked(AllyCountrolCenter acc); 11 } 12 13 /// <summary> 14 /// 具体观察者 15 /// </summary> 16 public class Player : IObserver 17 { 18 public string Name { get ; set; } 19 20 public void BeAttacked(AllyCountrolCenter acc) 21 { 22 Console.WriteLine("{0}: 我正被攻击,速来援救!",this.Name); 23 acc.NotifyObserver(this.Name); 24 } 25 26 public void Help() 27 { 28 Console.WriteLine("{0} : 坚持住,立马来救你!",this.Name); 29 } 30 } 31 32 /// <summary> 33 /// 抽象目标 34 /// </summary> 35 public abstract class AllyCountrolCenter 36 { 37 public string AllyName { get; set; } 38 protected IList<IObserver> playerList = new List<IObserver>(); 39 40 public void Join(IObserver observer) 41 { 42 playerList.Add(observer); 43 Console.WriteLine("通知: {0} 加入 {1} 战队", observer.Name, this.AllyName); 44 } 45 public abstract void NotifyObserver(string name); 46 } 47 48 /// <summary> 49 /// 具体目标 50 /// </summary> 51 public class ConcreteAllyControlCenter : AllyCountrolCenter 52 { 53 public ConcreteAllyControlCenter(string allyCountrolName) 54 { 55 this.AllyName = allyCountrolName; 56 Console.WriteLine("系统通知: {0} 战队组建成功!",this.AllyName); 57 } 58 public override void NotifyObserver(string playerName) 59 { 60 61 foreach (var player in playerList) 62 { 63 Console.WriteLine("通知: 盟友们,{0}正遭受攻击,速去救援!", playerName); 64 } 65 } 66 } 67 68 #endregion
16.访问者模式
1 #region 16.访问者模式(Visitor)。提供一个作用于某对象结构中的各元素的操作表示,它使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 2 3 /// <summary> 4 /// 抽象元素 5 /// </summary> 6 public interface IEmployee 7 { 8 void Accept(Department department); 9 } 10 11 /// <summary> 12 /// 具体元素 13 /// </summary> 14 public class FullTimeEmployee : IEmployee 15 { 16 public string Name { get; set; } 17 public double WeeklyWage { get; set; } 18 public int WorkTime { get; set; } 19 public FullTimeEmployee(string name,double weeklyWage,int workTime) 20 { 21 this.Name = name; 22 this.WeeklyWage = weeklyWage; 23 this.WorkTime = workTime; 24 } 25 26 public void Accept(Department department) 27 { 28 department.Visit(this); 29 } 30 } 31 32 /// <summary> 33 /// 具体元素 34 /// </summary> 35 public class PartTimeEmployee : IEmployee 36 { 37 38 public string Name { get; set; } 39 public double HourWage { get; set; } 40 public int WorkTime { get; set; } 41 public PartTimeEmployee(string name, double HourWage, int workTime) 42 { 43 this.Name = name; 44 this.HourWage = HourWage; 45 this.WorkTime = workTime; 46 } 47 public void Accept(Department department) 48 { 49 department.Visit(this); 50 } 51 } 52 53 /// <summary> 54 /// 抽象访问者 55 /// </summary> 56 public abstract class Department 57 { 58 public abstract void Visit(FullTimeEmployee employee); 59 public abstract void Visit(PartTimeEmployee employee); 60 } 61 62 /// <summary> 63 /// 具体访问者 64 /// </summary> 65 public class HRDepartment : Department 66 { 67 // 实现人力资源部对兼职员工数据的访问 68 public override void Visit(PartTimeEmployee employee) 69 { 70 int workTime = employee.WorkTime; 71 Console.WriteLine("临时工 {0} 实际工作时间为:{1} 小时", employee.Name, workTime); 72 } 73 74 // 实现人力资源部对全职员工数据的访问 75 public override void Visit(FullTimeEmployee employee) 76 { 77 int workTime = employee.WorkTime; 78 Console.WriteLine("正式员工 {0} 实际工作时间为:{1} 小时", employee.Name, workTime); 79 80 if (workTime > 40) 81 { 82 Console.WriteLine("正式员工 {0} 加班时间为:{1} 小时", employee.Name, workTime - 40); 83 } 84 else if (workTime < 40) 85 { 86 Console.WriteLine("正式员工 {0} 请假时间为:{1} 小时", employee.Name, 40 - workTime); 87 } 88 } 89 } 90 91 /// <summary> 92 /// 具体访问者 93 /// </summary> 94 public class FinancialDepartment : Department 95 { 96 // 实现财务部对兼职员工数据的访问 97 public override void Visit(PartTimeEmployee employee) 98 { 99 int workTime = employee.WorkTime; 100 double hourWage = employee.HourWage; 101 Console.WriteLine("临时工 {0} 实际工资为:{1} 元", employee.Name, workTime * hourWage); 102 } 103 104 // 实现财务部对全职员工数据的访问 105 public override void Visit(FullTimeEmployee employee) 106 { 107 int workTime = employee.WorkTime; 108 double weekWage = employee.WeeklyWage; 109 110 if (workTime > 40) 111 { 112 weekWage = weekWage + (workTime - 40) * 50; 113 } 114 else if (workTime < 40) 115 { 116 weekWage = weekWage - (40 - workTime) * 80; 117 if (weekWage < 0) 118 { 119 weekWage = 0; 120 } 121 } 122 123 Console.WriteLine("正式员工 {0} 实际工资为:{1} 元", employee.Name, weekWage); 124 } 125 } 126 127 #endregion
17.模板方法
1 #region 17.模板方法(Template Method)模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的特定步骤。 2 3 4 /// <summary> 5 /// 父类 6 /// </summary> 7 public abstract class Account 8 { 9 public bool Validate(string account, string password) 10 { 11 Console.WriteLine("账号 : {0}",account); 12 Console.WriteLine("密码 : {0}",password); 13 if (account.Equals("张无忌") && password.Equals("123456")) 14 return true; 15 else 16 return false; 17 } 18 /// <summary> 19 /// 延迟到子类中的方法步骤 20 /// </summary> 21 public abstract double CalculateInterest(); 22 public void Display() 23 { 24 Console.WriteLine("显示利息"); 25 } 26 public virtual bool IsAllowDisplay() 27 { 28 return true; 29 } 30 public double GetInterest(string account, string password) 31 { 32 var result = 0d; 33 if (!Validate(account, password)) 34 { 35 Console.WriteLine("账号或密码错误,请重新输入!"); 36 return result; 37 } 38 result = CalculateInterest(); 39 if (IsAllowDisplay()) 40 { 41 Display(); 42 return result; 43 } 44 return 0d; 45 } 46 47 } 48 /// <summary> 49 /// 子类 50 /// </summary> 51 public class CurrentAccount : Account 52 { 53 public override double CalculateInterest() 54 { 55 Console.WriteLine("计算活期利息"); 56 return 10d; 57 } 58 public override bool IsAllowDisplay() 59 { 60 return base.IsAllowDisplay(); 61 } 62 } 63 64 #endregion
18.策略模式
1 #region 18. 策略模式(Strategy): 定义一系列算法类,将每一个算法封装起来,并让它们可以可以相互替换。策略模式让算法独立于使用它的客户而变化。 2 3 /// <summary> 4 /// 环境类 5 /// </summary> 6 public class MovieTicket 7 { 8 private double _price; 9 private IDiscount _discount; 10 public double Price 11 { 12 get { return _discount.Calculate(_price); } 13 set { _price = value; } 14 } 15 public IDiscount Discount 16 { 17 set { _discount = value; } 18 } 19 } 20 21 22 /// <summary> 23 /// 抽象策略类 24 /// </summary> 25 public interface IDiscount 26 { 27 double Calculate(double price); 28 } 29 30 /// <summary> 31 /// 具体策略 32 /// 学生折扣 33 /// </summary> 34 public class StudentDiscount : IDiscount 35 { 36 public double Calculate(double price) 37 { 38 Console.WriteLine("学生票: "); 39 return price * 0.8; 40 } 41 } 42 43 /// <summary> 44 /// 具体策略 45 /// VIP折扣 46 /// </summary> 47 public class VIPDiscount : IDiscount 48 { 49 public double Calculate(double price) 50 { 51 Console.WriteLine("VIP票: "); 52 Console.WriteLine("增加积分!"); 53 return price * 0.5; 54 } 55 } 56 57 /// <summary> 58 /// 具体策略 59 /// 儿童票 60 /// </summary> 61 public class ChildrenDiscount : IDiscount 62 { 63 public double Calculate(double price) 64 { 65 Console.WriteLine("儿童票: "); 66 return price - 10; 67 } 68 } 69 70 #endregion
19.命令模式
1 #region 19.命令模式(Command): 将请求封装成对象,从而可以用不同的请求对客户进行参数化。 2 3 /// <summary> 4 /// 请求发送者 5 /// </summary> 6 public class FunctionButton 7 { 8 public string Name { get; set; } 9 private Command command; 10 public FunctionButton(string name) 11 { 12 this.Name = name; 13 } 14 15 public void SetCommand(Command command) 16 { 17 this.command = command; 18 } 19 public void OnClick() 20 { 21 22 Console.WriteLine("点击功能键"); 23 if (command != null) 24 { 25 command.Execute(); 26 } 27 } 28 29 } 30 31 /// <summary> 32 /// 抽象请求者 33 /// </summary> 34 public abstract class Command 35 { 36 public abstract void Execute(); 37 } 38 39 /// <summary> 40 /// 具体命令 41 /// </summary> 42 public class HelpCommand : Command 43 { 44 private HelpHandler hander; 45 46 public HelpCommand() 47 { 48 hander = new HelpHandler(); 49 } 50 public override void Execute() 51 { 52 if (hander != null) 53 { 54 hander.Display(); 55 } 56 } 57 } 58 59 /// <summary> 60 /// 具体命令 61 /// </summary> 62 public class MinimizeCommand : Command 63 { 64 private WindowHandler handler; 65 public MinimizeCommand() 66 { 67 handler = new WindowHandler(); 68 } 69 public override void Execute() 70 { 71 if (handler != null) 72 { 73 handler.Minimize(); 74 } 75 } 76 } 77 78 /// <summary> 79 /// 请求的接受者. 80 /// </summary> 81 public class WindowHandler 82 { 83 public void Minimize() 84 { 85 Console.WriteLine("正在最小化窗口至托盘..."); 86 } 87 } 88 89 public class HelpHandler 90 { 91 public void Display() 92 { 93 Console.WriteLine("正在显示帮助文档..."); 94 } 95 } 96 #endregion
20.备忘录模式
1 #region 20.备忘录模式(Memento): 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。 2 3 ///原发器 4 public class Chessman 5 { 6 public string Label { get; set; } 7 public int X { get; set; } 8 public int Y { get; set; } 9 public Chessman(string label, int x, int y) 10 { 11 Label = label; 12 X = x; 13 Y = y; 14 } 15 16 17 } 18 /// <summary> 19 /// 备忘录 20 /// </summary> 21 public class ChessmanMemento 22 { 23 public string Label { get; set; } 24 public int X { get; set; } 25 public int Y { get; set; } 26 public ChessmanMemento(string label, int x, int y) 27 { 28 Label = label; 29 X = x; 30 Y = y; 31 } 32 } 33 /// <summary> 34 /// 负责人--单次备忘 35 /// </summary> 36 public class MementoCaretaker 37 { 38 public ChessmanMemento Memento { get; set; } 39 40 } 41 42 /// <summary> 43 /// 负责人--多次备忘 44 /// </summary> 45 public class NewMementoCaretoker 46 { 47 private IList<ChessmanMemento> mementoList = new List<ChessmanMemento>(); 48 49 public ChessmanMemento GetMemento(int i) 50 { 51 return mementoList[i]; 52 } 53 54 public void SetMemento(ChessmanMemento memento) 55 { 56 mementoList.Add(memento); 57 } 58 } 59 60 #endregion
21.迭代器模式
1 #region 21.迭代器模式(Iterator): 提供一种方法来访问聚合对象,而不用暴露这个对象的内部标识,其别名为游标(Cursor)。 2 3 /// <summary> 4 /// 抽象聚合类 5 /// </summary> 6 public abstract class AbstractObjecList 7 { 8 protected IList<object> objectList = new List<object>(); 9 10 public AbstractObjecList(IList<object> objectList) 11 { 12 this.objectList = objectList; 13 } 14 15 public void AddObject(object obj) 16 { 17 this.objectList.Add(obj); 18 } 19 20 public void RemoveObject(object obj) 21 { 22 this.objectList.Remove(obj); 23 } 24 25 public IList<object> GetObjectList() 26 { 27 return this.objectList; 28 } 29 30 /// <summary> 31 /// 声明创建迭代器对象的抽象工厂 32 /// </summary> 33 public abstract IAbstractIterator CreateIterator(); 34 } 35 36 /// <summary> 37 /// 具体聚合类 38 /// </summary> 39 public class ProductList : AbstractObjecList 40 { 41 public ProductList(IList<object> objectList) : base(objectList) 42 { 43 } 44 45 public override IAbstractIterator CreateIterator() 46 { 47 return new ProductIterator(this); 48 } 49 50 /// <summary> 51 /// 具体迭代器 52 /// </summary> 53 public class ProductIterator : IAbstractIterator 54 { 55 private ProductList productList; 56 private IList<object> products; 57 private int cursor1; 58 private int cursor2; 59 60 public ProductIterator(ProductList productList) 61 { 62 this.productList = productList; 63 this.products = productList.GetObjectList(); 64 this.cursor1 = 0; 65 this.cursor2 = this.products.Count - 1; 66 } 67 68 public object GetNextItem() 69 { 70 return products[cursor1]; 71 } 72 73 public object GetPreviousItem() 74 { 75 return products[cursor2]; 76 } 77 78 public bool IsFirst() 79 { 80 return cursor2 == -1; 81 } 82 83 public bool IsLast() 84 { 85 return cursor1 == products.Count; 86 } 87 88 public void Next() 89 { 90 if (cursor1 < products.Count) 91 { 92 cursor1++; 93 } 94 } 95 96 public void Previous() 97 { 98 if (cursor2 > -1) 99 { 100 cursor2--; 101 } 102 } 103 } 104 } 105 106 107 108 /// <summary> 109 /// 抽象迭代器 110 /// </summary> 111 public interface IAbstractIterator 112 { 113 void Next(); 114 bool IsLast(); 115 void Previous(); 116 bool IsFirst(); 117 object GetNextItem(); 118 object GetPreviousItem(); 119 } 120 121 122 #endregion
22.中介者模式
1 #region 22.中介者模式(Mediator): 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以相对独立地改变它们之间的交互。 2 3 /// <summary> 4 /// 抽象中介者. 5 /// </summary> 6 public abstract class Mediator 7 { 8 public abstract void ComponentChanged(MediatorComponent c); 9 } 10 11 public class ConcreteMediator : Mediator 12 { 13 public Button addButton; 14 public List list; 15 public MediatorTextBox userNameTextBox; 16 public ComboBox cb; 17 18 public override void ComponentChanged(MediatorComponent c) 19 { 20 if (c == addButton) 21 { 22 Console.WriteLine("-- 点击添加按钮 --"); 23 list.Update(); 24 cb.Update(); 25 userNameTextBox.Update(); 26 } 27 else if (c == list) 28 { 29 Console.WriteLine("-- 从列表框选择客户 --"); 30 cb.Select(); 31 userNameTextBox.SetText(); 32 } 33 else if (c == cb) 34 { 35 Console.WriteLine("-- 从组合框选择客户 --"); 36 cb.Select(); 37 userNameTextBox.SetText(); 38 } 39 } 40 } 41 42 /// <summary> 43 /// 抽象组件 44 /// </summary> 45 public abstract class MediatorComponent 46 { 47 protected Mediator mediator; 48 49 public void SetMediator(Mediator mediator) 50 { 51 this.mediator = mediator; 52 } 53 54 public void Changed() 55 { 56 mediator.ComponentChanged(this); 57 } 58 public abstract void Update(); 59 } 60 61 #region 具体组件 62 63 public class Button : MediatorComponent 64 { 65 66 public override void Update() 67 { 68 throw new NotImplementedException(); 69 } 70 } 71 72 public class List : MediatorComponent 73 { 74 public override void Update() 75 { 76 Console.WriteLine("列表框增加一项: 张无忌"); 77 } 78 public void Select() 79 { 80 Console.WriteLine("列表框选中项: 小龙女"); 81 } 82 } 83 84 public class ComboBox : MediatorComponent 85 { 86 public override void Update() 87 { 88 Console.WriteLine("组合框增加一项: 张无忌"); 89 } 90 public void Select() 91 { 92 Console.WriteLine("组合框选中项: 小龙女"); 93 } 94 } 95 96 public class MediatorTextBox : MediatorComponent 97 { 98 public override void Update() 99 { 100 Console.WriteLine("客户信息增加成功后文本框清空"); 101 } 102 public void SetText() 103 { 104 Console.WriteLine("文本框显示: 小龙女"); 105 } 106 } 107 108 public class Label : MediatorComponent 109 { 110 public override void Update() 111 { 112 Console.WriteLine("文本标签内容改变,客户信息总数量加1"); 113 } 114 } 115 116 117 #endregion 118 119 120 #endregion
23解释器模式
1 #region 23.解释器模式(Interpreter): 定义一个语言的文法,并且建立一个解释器来解释该语言中的句子。 2 3 /// <summary> 4 /// 环境类 5 /// </summary> 6 public class Context 7 { 8 private int index = -1; 9 private string[] tokens; 10 private string currentToken; 11 public Context(string text) 12 { 13 text = text.Replace(" ", " "); 14 tokens = text.Split(' '); 15 16 } 17 public string NextToken() 18 { 19 if (index < tokens.Length - 1) 20 { 21 currentToken = tokens[++index]; 22 } 23 else 24 { 25 currentToken = null; 26 } 27 return currentToken; 28 } 29 30 public string GetCurrentToken() 31 { 32 return currentToken; 33 } 34 35 public void SkipToken(string token) 36 { 37 if (!token.Equals(currentToken, StringComparison.OrdinalIgnoreCase)) 38 { 39 Console.WriteLine("错误提示:{0} 解释错误!", currentToken); 40 } 41 NextToken(); 42 } 43 44 public int GetCurrentNumber() 45 { 46 int number = 0; 47 try 48 { 49 number = Convert.ToInt32(currentToken); 50 } 51 catch (Exception ex) 52 { 53 Console.WriteLine("错误提示: {0}", ex.Message); 54 } 55 return number; 56 } 57 } 58 59 /// <summary> 60 /// 抽象表达式 61 /// </summary> 62 public abstract class Node 63 { 64 public abstract void Interpret(Context context); 65 public abstract void Execute(); 66 } 67 68 //public class ExpressionNode : Node 69 //{ 70 71 // private IList<Node> nodeList = new List<Node>(); 72 73 // public override void Execute() 74 // { 75 76 // } 77 78 // //public override void Interpret(Context context) 79 // //{ 80 // // while (true) 81 // // { 82 // // if (context.GetCurrentToken() == null) 83 // // { 84 // // break; 85 // // } 86 // // else if (context.GetCurrentToken().Equals("END", StringComparison.OrdinalIgnoreCase)) 87 // // { 88 // // context.SkipToken("END"); 89 // // break; 90 // // } 91 // // else 92 // // { 93 // // node.Interpret(context); 94 // // nodeList.Add(node); 95 // // } 96 // // } 97 // //} 98 //} 99 100 #endregion