行為型模式
阿新 • • 發佈:2020-07-29
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 publicvoid 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提供一種方法來訪問聚合物件,而不用暴露這個物件的內部標識,其別名為遊標(Cursor)。
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定義一個語言的文法,並且建立一個直譯器來解釋該語言中的句子。