Head First 設計模式
[TOC]
完整源碼
設計模式入門
- 面向?qū)ο蠡A
- 抽象
- 封裝
- 繼承
- 多態(tài)
- 良好的面向?qū)ο笤O計
- 復用性
- 擴充性
- 可維護性
- 面向?qū)ο笤瓌t
- 封裝變化
- 多用組合焚廊,少用繼承
- 針對接口編程货邓,不針對實現(xiàn)編程
- 為交互對象之間的松耦合努力
- 開放閉合原則
- 一個類對擴展開放祠锣,對修改關閉
- 原先的main調(diào)用不受影響
- 依賴倒置原則
- 要依賴抽象口芍,不要依賴具體類
- 高層組件和底層組件都應該依賴于抽象
- 最少知識原則
- 類之間的交流越簡單越好
- 好萊塢原則
- 高層依賴底層
- 底層不依賴高層
- 單一職責原則
- 類的功能越單一越好
具體設計模式
策略模式
定義算法族叨叙,分別封裝起來重付,讓他們之間可以互相替換玄组。讓算法的變化獨立于使用算法的客戶。(將變化部分封裝為成員變量胧辽,借用成員變量的多態(tài)實現(xiàn)方法的互換)
-
具體實現(xiàn)
- 實現(xiàn)場景:不同的鴨子具有不同的行為
- 將行為抽象為接口
- 將接口作為成員變量峻仇,行為類繼承行為接口
- 實例鴨子類時指定特定行為類
- 行為相當于算法,算法變化獨立于使用算法的用戶(鴨子)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
///策略模式:封裝變化為接口
///把成員方法轉化為成員屬性
namespace StrategyPattern
{
public interface IFlyBehavior
{
void Fly();
}
public interface IQuackBehavior
{
void Quack();
}
public abstract class Duck
{
protected IFlyBehavior flyBehavior;
protected IQuackBehavior quackBehavior;
public Duck() { }
public void PerformFly()
{
flyBehavior.Fly();
}
public void PerformQuack()
{
quackBehavior.Quack();
}
public virtual void Display()
{
PerformFly();
PerformQuack();
Siwm();
}
public void Siwm()
{
Console.WriteLine("游泳");
}
public void SetFlyBehavior(IFlyBehavior fly)
{
flyBehavior = fly;
}
public void SetQuackBehavior(IQuackBehavior quack)
{
quackBehavior = quack;
}
}
public class FlyWithWings : IFlyBehavior
{
public void Fly()
{
Console.WriteLine("用翅膀飛");
}
}
public class FlyNoWay : IFlyBehavior
{
public void Fly()
{
Console.WriteLine("不能飛");
}
}
public class NormalQuack : IQuackBehavior
{
public void Quack()
{
Console.WriteLine("呱呱叫");
}
}
public class MuteQuack : IQuackBehavior
{
public void Quack()
{
Console.WriteLine("不能叫");
}
}
public class MallardDuck : Duck
{
public MallardDuck()
{
flyBehavior = new FlyWithWings();
quackBehavior = new NormalQuack();
}
public override void Display()
{
Console.WriteLine("我是一只綠頭鴨");
base.Display();
}
}
public class ModelDuck : Duck
{
public ModelDuck()
{
flyBehavior = new FlyNoWay();
quackBehavior = new MuteQuack();
}
public override void Display()
{
Console.WriteLine("我是一只模型鴨");
base.Display();
}
}
class StrategyPatternMain
{
public void Main()
{
MallardDuck mallardDuck = new MallardDuck();
ModelDuck modelDuck = new ModelDuck();
mallardDuck.Display();
modelDuck.Display();
Console.WriteLine("綠頭鴨摔斷了翅膀");
mallardDuck.SetFlyBehavior(new FlyNoWay());
mallardDuck.Display();
}
}
}
觀察者模式
在對象之間定義一對多的關系邑商,當主對象改變時摄咆,所有依賴其的對象收到通知凡蚜,自動更新
-
具體實現(xiàn)
- 主題接口維護一個觀察者列表
- 給所有觀察者發(fā)送消息(調(diào)用觀察者方法)
- 主題通過參數(shù)推數(shù)據(jù)
- 觀察者通過參數(shù)拉數(shù)據(jù)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PatternDesign;
namespace ObserverPattern
{
/// <summary>
/// 主題
/// 添加監(jiān)聽者
/// 刪除監(jiān)聽者
/// </summary>
public interface ISubject
{
bool isChange { get; set; }
List<IObserver> obervers { get; set; }
void AddObserver(IObserver oberver);
void RemoveObserver(IObserver oberver);
void SetChange(ISubject subject);
void NotifyObservers();
}
public interface IObserver
{
void Update(ISubject subject);
}
public class WeatherData : ISubject
{
public string Name { get; set; }
public string Description { get; set; }
public bool isChange { get; set; }
public WeatherData()
{
Name = "天氣數(shù)據(jù)";
Description = "今天氣溫25度";
isChange = false;
obervers = new List<IObserver>();
}
public List<IObserver> obervers { get; set; }
public void AddObserver(IObserver oberver)
{
obervers.Add(oberver);
}
public void RemoveObserver(IObserver oberver)
{
obervers.Remove(oberver);
}
public void SetChange(ISubject subject)
{
isChange = true;
NotifyObservers();
}
public void NotifyObservers()
{
if (isChange)
{
foreach (IObserver oberver in obervers)
{
oberver.Update(this);
}
isChange = false;
}
}
}
public class Display1 : IObserver
{
public void Update(ISubject subject)
{
WeatherData weatherData = (WeatherData)subject;
Console.WriteLine("展示牌一:");
Console.WriteLine(weatherData.Name);
Console.WriteLine(weatherData.Description);
}
}
public class Display2 : IObserver
{
public void Update(ISubject subject)
{
WeatherData weatherData = (WeatherData)subject;
Console.WriteLine("展示牌二:");
Console.WriteLine(weatherData.Name);
Console.WriteLine(weatherData.Description);
}
}
public class Display3 : IObserver
{
public void Update(ISubject subject)
{
WeatherData weatherData = (WeatherData)subject;
Console.WriteLine("展示牌三:");
Console.WriteLine(weatherData.Name);
Console.WriteLine(weatherData.Description);
}
}
public class WeatherDataByS : IObservable<WeatherDataByS>, IDisposable
{
List<IObserver<WeatherDataByS>> observers;
public WeatherDataByS()
{
observers = new List<IObserver<WeatherDataByS>>();
}
public IDisposable Subscribe(IObserver<WeatherDataByS> observer)
{
observers.Add(observer);
return this;
}
public void NotifyObservers()
{
foreach (IObserver<WeatherDataByS> observer in observers)
{
observer.OnNext(this);
observer.OnCompleted();
}
}
public void Dispose()
{
Console.WriteLine("通知公告板");
}
}
public class DisplayByS1 : IObserver<WeatherDataByS>
{
public void OnNext(WeatherDataByS value)
{
value.Dispose();
}
public void OnError(Exception error)
{
error.ToString();
}
public void OnCompleted()
{
Console.WriteLine("通知完成");
}
}
internal class ObserverPatternMain : IPattern
{
public void Main()
{
ISubject weatherData = new WeatherData();
IObserver display1 = new Display1();
IObserver display2 = new Display2();
IObserver display3 = new Display3();
weatherData.AddObserver(display1);
weatherData.AddObserver(display2);
weatherData.AddObserver(display3);
weatherData.SetChange(weatherData);
IObservable<WeatherDataByS> observable = new WeatherDataByS();
IObserver<WeatherDataByS> observer = new DisplayByS1();
observable.Subscribe(observer);
((WeatherDataByS)observable).NotifyObservers();
}
}
}
裝飾者模式
- 動態(tài)的將責任附加到對象上。有別于繼承的擴展功能吭从。
- 組件朝蜘,裝飾器
- 組件(被裝飾者)和裝飾器是同一類型
- 裝飾器可以以一定順序添加或替換組件方法(拓展/改變)
- 裝飾器內(nèi)部有組件變量
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PatternDesign;
namespace DecoratorPattern
{
/// <summary>
/// 裝飾器模式
/// 組件和裝飾器
/// </summary>
public interface IFood
{
string Name { get; }
string Description { get; set; }
string GetDescription();
double Cost();
}
/// <summary>
/// 被裝飾食物接口
/// </summary>
public abstract class AbstractFood : IFood
{
public string Name { get; }
public string Description { get; set; }
public virtual string GetDescription()
{
return Description;
}
abstract public double Cost();
}
/// <summary>
/// 抽象調(diào)料裝飾器
/// </summary>
public abstract class CondimentDecorator : AbstractFood
{
protected IFood food;
public abstract override string GetDescription();
}
public class Hamburger : AbstractFood
{
public Hamburger()
{
Description = "漢堡包";
}
public override double Cost()
{
return 1;
}
}
public class Salt : CondimentDecorator
{
public Salt(IFood food)
{
this.food = food;
}
public override string GetDescription()
{
return food.GetDescription() + "加鹽";
}
public override double Cost()
{
return food.Cost() + 0.1f;
}
}
public class Suger : CondimentDecorator
{
public Suger(IFood food)
{
this.food = food;
}
public override string GetDescription()
{
return food.GetDescription() + "加糖";
}
public override double Cost()
{
return food.Cost() + 0.2f;
}
}
internal class DecoratorPatternMain : IPattern
{
public void Main()
{
IFood hamburger = new Hamburger();
hamburger = new Salt(hamburger);
hamburger = new Suger(hamburger);
hamburger = new Salt(hamburger);
Console.WriteLine(hamburger.GetDescription());
}
}
}
工廠模式
- 定義
- 定義了一個創(chuàng)建對象的接口,但由子類決定要實例化的類是哪一個影锈。工廠方法讓類把實例化延遲到子類
- 解決問題
- 將客戶程序從具體類解耦
- 實現(xiàn)思路
- 抽象產(chǎn)品
- 具體產(chǎn)品繼承抽象產(chǎn)品接口
- 通過產(chǎn)品接口與具體類型產(chǎn)品解耦,從而生產(chǎn)不同類型產(chǎn)品
- 具體產(chǎn)品繼承抽象產(chǎn)品接口
- 創(chuàng)建者
- 創(chuàng)建抽象產(chǎn)品的接口
- 具體創(chuàng)建者實現(xiàn)創(chuàng)建接口
- 創(chuàng)建抽象產(chǎn)品的接口
- 抽象產(chǎn)品
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FactoryPattern
{
abstract class Creator
{
abstract public Product FactoryMethod(string type);
}
abstract class Product
{
protected string Name;
protected string Description;
public abstract void Display();
}
class LittelHamburger : Product
{
public LittelHamburger()
{
Name = "小漢堡";
Description = "這是一個小漢堡";
}
public override void Display()
{
Console.WriteLine(Name + " " + Description);
}
}
class BigHamburger : Product
{
public BigHamburger()
{
Name = "大漢堡";
Description = "這是一個大漢堡";
}
public override void Display()
{
Console.WriteLine(Name + " " + Description);
}
}
class HamburgerCreator : Creator
{
public override Product FactoryMethod(string type)
{
switch (type)
{
case "大漢堡":
return new BigHamburger();
case "小漢堡":
return new LittelHamburger();
default:
return null;
}
}
}
internal class FactoryPatternMain : IPattern
{
public void Main()
{
Creator creator = new HamburgerCreator();
Product product = creator.FactoryMethod("大漢堡");
Product product1 = creator.FactoryMethod("小漢堡");
product.Display();
product1.Display();
}
}
}
抽象工廠模式
- 提供一個接口蝉绷,用于創(chuàng)建相關或依賴對象家族鸭廷,而不需要明確指定具體類
- 客戶要一個產(chǎn)品,描述一個必要的概念即可或得一個復雜產(chǎn)品熔吗,復雜產(chǎn)品生產(chǎn)過程封裝在工廠中辆床,抽象工廠模式可以在不改變用戶點餐方式,給工廠加復雜度
- 工廠模式+策略模式
- 抽象工廠與工廠的區(qū)別
- 工廠模式使用繼承桅狠,將具體對象的創(chuàng)建延遲給子類實現(xiàn)
- 抽象工廠使用組合讼载,將具體對象的創(chuàng)建被組合的工廠子類實現(xiàn)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFactoryPattern
{
/// <summary>
/// 抽象工廠模式
/// 工廠模式+策略模式
/// </summary>
abstract class Creator
{
/// <summary>
/// 工廠方法
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
abstract public Product FactoryMethod(string type);
}
/// <summary>
/// 調(diào)料工廠采用組合方式
/// </summary>
abstract class IngredientCreator
{
/// <summary>
/// 工廠方法
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
abstract public string CreateSalt();
abstract public string CreateSuger();
}
/// <summary>
/// 加了調(diào)料的復雜產(chǎn)品
/// </summary>
abstract class Product
{
protected string Salt;
protected string Suger;
protected string Name;
protected string Description;
//組合一個調(diào)料工廠
protected IngredientCreator ingredientCreator;
public abstract void Display();
}
class SugerIngredient : IngredientCreator
{
public override string CreateSalt()
{
return "不加鹽";
}
public override string CreateSuger()
{
return "加糖";
}
}
class SaltIngredient : IngredientCreator
{
public override string CreateSalt()
{
return "加鹽";
}
public override string CreateSuger()
{
return "不加糖";
}
}
class LittelHamburger : Product
{
public LittelHamburger(IngredientCreator ingredient)
{
Name = "小漢堡";
Description = "這是一個小漢堡";
this.ingredientCreator = ingredient;
Salt = ingredientCreator.CreateSalt();
Suger = ingredientCreator.CreateSuger();
}
public LittelHamburger()
{
Name = "小漢堡";
Description = "這是一個小漢堡";
}
public override void Display()
{
Console.WriteLine(Name + " " + Description);
Console.WriteLine(Salt);
Console.WriteLine(Suger);
}
}
class BigHamburger : Product
{
public BigHamburger(IngredientCreator ingredient)
{
Name = "大漢堡";
Description = "這是一個大漢堡";
this.ingredientCreator = ingredient;
Salt = ingredientCreator.CreateSalt();
Suger = ingredientCreator.CreateSuger();
}
public BigHamburger()
{
Name = "大漢堡";
Description = "這是一個大漢堡";
}
public override void Display()
{
Console.WriteLine(Name + " " + Description);
Console.WriteLine(Salt);
Console.WriteLine(Suger);
}
}
class HamburgerCreator : Creator
{
public override Product FactoryMethod(string type)
{
switch (type)
{
case "大漢堡":
return new BigHamburger();
case "小漢堡":
return new LittelHamburger();
case "甜大漢堡":
return new BigHamburger(new SugerIngredient());
case "咸小漢堡":
return new LittelHamburger(new SaltIngredient());
case "咸大漢堡":
return new BigHamburger(new SaltIngredient());
case "甜小漢堡":
return new LittelHamburger(new SugerIngredient());
default:
return null;
}
}
}
internal class AbstractFactoryPatternMain : IPattern
{
public void Main()
{
Creator creator = new HamburgerCreator();
Product product = creator.FactoryMethod("大漢堡");
Product product1 = creator.FactoryMethod("小漢堡");
Product product2 = creator.FactoryMethod("甜大漢堡");
Product product3 = creator.FactoryMethod("甜小漢堡");
Product product4 = creator.FactoryMethod("咸大漢堡");
Product product5 = creator.FactoryMethod("咸小漢堡");
product.Display();
product1.Display();
product2.Display();
product3.Display();
product4.Display();
product5.Display();
}
}
}
單例模式
- 定義
- 確保一個類只有一個實例,并提供全局訪問點中跌,延遲實例化
- 解決問題
- 保證只有一個實例
- 提供全局訪問點咨堤,方便訪問
- 實現(xiàn)思路
- 簡單單例
* 私有靜態(tài)屬性
* 私有構造器
* 公有靜態(tài)全局訪問點
* 延遲實例化 - 線程安全單例
- 靜態(tài)構造器保證線程安全
- 簡單單例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SingletonPattern
{
public class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
public void Display()
{
Console.WriteLine("我是簡單單例");
}
}
/// <summary>
/// 完全懶漢多線程安全單例模式
/// </summary>
public sealed class SyncSingleton
{
private SyncSingleton() { }
public static SyncSingleton Instance { get { return Nested.instance; } }
private class Nested
{
//Explicit static constructor to tell C# compiler
//not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly SyncSingleton instance = new SyncSingleton();
}
public void Display()
{
Console.WriteLine("這是一個線程安全的單例模式");
}
}
internal class SingletonPatternMain : IPattern
{
public void Main()
{
Singleton.Instance.Display();
SyncSingleton.Instance.Display();
}
}
}
命令模式
- 定義
- 將請求封裝成對象,使用不同的請求來參數(shù)化其他對象的命令
- 解決的問題
- 將請求者與執(zhí)行者之間解耦(運行時靈活指定)
- 支持撤銷操作
- 支持宏命令
- 可實現(xiàn)日志和事物系統(tǒng)
- 實現(xiàn)思路
- 請求者
- 命令
- 設置命令方法
- 命令
- 執(zhí)行者
- 執(zhí)行方法漩符,撤銷方法...
- 執(zhí)行者
- 提供相關功能的接口
- 請求者
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CommandPattern
{
/// <summary>
/// 命令模式
/// 請求者
/// 命令
/// 執(zhí)行者
/// </summary>
interface IInvoker
{
void SetCommand(ICommand command);
void SetCommand(ICommand[] commands);
void ExecuteCommand();
void ExecuteCommands();
}
abstract class Invoker : IInvoker
{
protected ICommand command;
protected ICommand[] commands;
public abstract void SetCommand(ICommand command);
public abstract void SetCommand(ICommand[] commands);
public abstract void ExecuteCommand();
public abstract void ExecuteCommands();
}
interface ICommand
{
void Execute();
void Undo();
}
abstract class Command : ICommand
{
public IReceiver receiver { set; get; }
public Command(IReceiver receiver)
{
this.receiver = receiver;
}
public virtual void Execute()
{
receiver.DoSomething();
}
public virtual void Undo()
{
receiver.UndoSomething();
}
}
interface IReceiver
{
void DoSomething();
void UndoSomething();
}
class Ligtht : IReceiver
{
public void DoSomething()
{
Console.WriteLine("開燈");
}
public void UndoSomething()
{
Console.WriteLine("關燈");
}
}
class RemoteControl : Invoker
{
protected ICommand command;
protected ICommand[] commands;
public override void SetCommand(ICommand command)
{
this.command = command;
}
public override void SetCommand(ICommand[] commands)
{
this.commands = commands;
}
public override void ExecuteCommand()
{
command.Execute();
}
public override void ExecuteCommands()
{
foreach (var item in commands)
{
item.Execute();
}
}
}
class LightOnCommand : Command
{
public LightOnCommand(IReceiver receiver) : base(receiver)
{
}
}
class LitghtOffCommand : Command
{
public LitghtOffCommand(IReceiver receiver) : base(receiver)
{
}
}
internal class CommandPatternMain : IPattern
{
public void Main()
{
IInvoker remoteControl = new RemoteControl();
IReceiver light = new Ligtht();
LightOnCommand lightOnCommand = new LightOnCommand(light);
LitghtOffCommand litghtOffCommand = new LitghtOffCommand(light);
remoteControl.SetCommand(lightOnCommand);
remoteControl.ExecuteCommand();
remoteControl.SetCommand(litghtOffCommand);
remoteControl.ExecuteCommand();
}
}
}
適配器模式
- 定義
- 將一個類的接口一喘,轉換成客戶期望的另一個接口。
- 解決問題
- 讓客戶從實現(xiàn)的接口解耦
- 實現(xiàn)思路
- 適配器:實現(xiàn)目標接口
- 組合被適配者
- 使用被適配者方法實現(xiàn)目標接口方法
- 被適配者
- 適配器:實現(xiàn)目標接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AdapterPattern
{
/// <summary>
/// 適配器
/// 目標
/// 被適配器
/// </summary>
interface Target
{
void TDoSomething();
}
class Adaptee
{
public void ADoSomething()
{
Console.WriteLine("適配者再做");
}
}
class Adapter : Target
{
Adaptee adaptee;
public Adapter(Adaptee adaptee)
{
this.adaptee = adaptee;
}
public void TDoSomething()
{
adaptee.ADoSomething();
}
}
internal class AdapterPatternMain : IPattern
{
public void Main()
{
Adaptee adaptee = new Adaptee();
Adapter adapter = new Adapter(adaptee);
adapter.TDoSomething();
}
}
}
外觀模式
- 定義
- 提供一個統(tǒng)一的接口來訪問子系統(tǒng)中的一群接口嗜暴。定義了一個高層接口讓子系統(tǒng)更容易使用
- 解決問題
- 將客戶從一個復雜子系統(tǒng)中解耦
- 簡化接口
- 實現(xiàn)思路
- 外觀類(總系統(tǒng))
- 組合各種子系統(tǒng)
- 提供方便調(diào)用(簡化)的接口
- 具體功能由子系統(tǒng)實現(xiàn)
- 外觀類(總系統(tǒng))
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FacadePattern
{
class Facada
{
public Func1 func1;
public Func2 func2;
public Facada(Func1 func1, Func2 func2)
{
this.func1 = func1;
this.func2 = func2;
}
public void Do()
{
func1.Do();
func2.Do();
}
}
class Func1
{
public void Do()
{
Console.WriteLine("func1 do");
}
}
class Func2
{
public void Do()
{
Console.WriteLine("func2 do");
}
}
internal class FacadePatternMain : IPattern
{
public void Main()
{
Func1 func1 = new Func1(); ;
Func2 func2 = new Func2();
Facada facada = new Facada(func1, func2);
facada.Do();
}
}
}
模版方法模式
- 定義
- 在一個方法中定義一個算法的骨架凸克,而將一些步驟延遲到子類中。
- 解決問題
- 提高代碼復用的重要技巧
- 鉤子方法(超類固定調(diào)用的事件函數(shù))
- 影響模版方法的調(diào)用
- 實現(xiàn)思路
- 超類
- 定義算法模型
- 以實現(xiàn)的方法
- 可由子類重寫
- 未實現(xiàn)的方法(抽象方法)
- 由子類實現(xiàn)
- 以實現(xiàn)的方法
- 定義算法模型
- 超類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TemplatePattern
{
abstract class CaffeeineBeverageWithHook
{
/// <summary>
/// 模版方法
/// </summary>
public void PrepareRecipe()
{
BoilWater();
Brew();
PourInCup();
if (IsNeedAddCondiments())
{
AddCondiments();
}
}
protected void BoilWater()
{
Console.WriteLine("水煮開了");
}
abstract protected void Brew();
protected void PourInCup()
{
Console.WriteLine("倒進杯子里");
}
abstract protected void AddCondiments();
virtual protected bool IsNeedAddCondiments()
{
return true;
}
}
class Coffee : CaffeeineBeverageWithHook
{
protected override void Brew()
{
Console.WriteLine("泡咖啡");
}
protected override void AddCondiments()
{
Console.WriteLine("加奶");
}
}
class Tea : CaffeeineBeverageWithHook
{
protected override void Brew()
{
Console.WriteLine("泡茶");
}
protected override void AddCondiments()
{
Console.WriteLine("不加調(diào)料闷沥,你應該看不見這句");
}
protected override bool IsNeedAddCondiments()
{
return false;
}
}
internal class TemplatePatternMain : IPattern
{
public void Main()
{
CaffeeineBeverageWithHook coffee = new Coffee();
CaffeeineBeverageWithHook tea = new Tea();
coffee.PrepareRecipe();
tea.PrepareRecipe();
}
}
}
迭代器模式
- 定義
- 提供一種方法順序訪問一個聚合對象中的各個元素萎战,而不暴露其內(nèi)部的表示
- 遍歷方法的適配器模式
- 解決問題
- 解決具體集合與遍歷方法的耦合問題
- 實現(xiàn)思路
- 迭代器接口
- 迭代對象集合
- 索引值
- 實現(xiàn)迭代器接口方法
- 可被迭代器遍歷接口
- 創(chuàng)建對應的迭代器(工廠模式)
- 迭代器接口
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IteratorPattern
{
interface IIterator
{
bool HasNext();
object Next();
}
interface IAggregate
{
IIterator CreateIterator();
}
class ListIterator<T> : IIterator
{
List<T> list;
int index = 0;
public ListIterator(List<T> list)
{
this.list = list;
}
public bool HasNext()
{
if (list == null || index >= list.Count)
{
return false;
}
else
{
return true;
}
}
public object Next()
{
return list[index++];
}
}
class ArrayIterator<T> : IIterator
{
T[] list;
int index = 0;
public ArrayIterator(T[] list)
{
this.list = list;
}
public bool HasNext()
{
if (list == null || index >= list.Length)
{
return false;
}
else
{
return true;
}
}
public object Next()
{
return list[index++];
}
}
class ListMenu : IAggregate
{
List<int> list;
public ListMenu()
{
list = new List<int>();
list.Add(0);
list.Add(1);
list.Add(2);
list.Add(3);
}
public IIterator CreateIterator()
{
return new ListIterator<int>(list);
}
}
class ArrayMenu : IAggregate
{
int[] list;
public ArrayMenu()
{
list = new int[4];
list[0] = 0;
list[1] = 1;
list[2] = 2;
list[3] = 3;
}
public IIterator CreateIterator()
{
return new ArrayIterator<int>(list);
}
}
internal class IteratorPatternMain : IPattern
{
public void Main()
{
IAggregate a = new ListMenu();
IAggregate b = new ArrayMenu();
foreachByIterator(a);
foreachByIterator(b);
}
void foreachByIterator(IAggregate list)
{
IIterator aIterator = list.CreateIterator();
while (aIterator.HasNext())
{
Console.WriteLine(aIterator.Next());
}
}
}
}
組合模式
- 定義
- 允許將對象組成樹形結構來表現(xiàn)“整體/部分”的層次結構。組合能讓客戶以一致的方式處理個別對象和對象組合
- 樹形結構存儲葉子節(jié)點和根節(jié)點
- 葉子節(jié)點和根節(jié)點實現(xiàn)同一個接口
- 實現(xiàn)的方法不同
- 葉子節(jié)點和根節(jié)點實現(xiàn)同一個接口
- 解決問題
- 樹形結構舆逃,無視葉子節(jié)點與根節(jié)點區(qū)別蚂维,拓展性很強
- 實現(xiàn)思路
- 抽象組合類
- 根節(jié)點使用的方法
- 葉子節(jié)點使用的方法
- 遍歷方法
- 組合葉子節(jié)點繼承抽象組合
- 組合根節(jié)點繼承抽象組合
- 抽象組合類
- 拓展
- 組合迭代器
- 棧,遞歸混用
- 組合迭代器
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using IteratorPattern;
namespace CompositePattern
{
public abstract class Component
{
public virtual void Add(Component component)
{
throw new NotImplementedException();
}
public virtual void Remove(Component component)
{
throw new NotImplementedException();
}
public virtual Component GetChild(int i)
{
throw new NotImplementedException();
}
public virtual string GetName()
{
throw new NotImplementedException();
}
public virtual string GetDescription()
{
throw new NotImplementedException();
}
public virtual bool IsTarget()
{
throw new NotImplementedException();
}
public virtual void Print()
{
throw new NotImplementedException();
}
}
public class ComponentItem : Component
{
string name;
string description;
bool isTarget;
public ComponentItem(string name, string description, bool isTarget)
{
this.name = name;
this.description = description;
this.isTarget = isTarget;
}
public override string GetName()
{
return name;
}
public override string GetDescription()
{
return description;
}
public override bool IsTarget()
{
return isTarget;
}
public override void Print()
{
Console.WriteLine(GetName());
Console.WriteLine(GetDescription());
if (isTarget)
Console.WriteLine("我是目標");
}
}
public class ComponentMenu : Component, IAggregate
{
string name;
string description;
List<Component> components = new List<Component>();
public ComponentMenu(string name, string description)
{
this.name = name;
this.description = description;
}
public override void Add(Component component)
{
components.Add(component);
}
public override void Remove(Component component)
{
components.Remove(component);
}
public override Component GetChild(int i)
{
return components[i];
}
public override string GetName()
{
return name;
}
public override string GetDescription()
{
return description;
}
/// <summary>
/// 樹形后根遍歷路狮,遞歸打印所有子節(jié)點
/// </summary>
public override void Print()
{
//打印自己
Console.WriteLine(GetName());
Console.WriteLine(GetDescription());
//如果有子節(jié)點打印子節(jié)點
//for (int i = 0; i < components.Count; i++)
//{
// GetChild(i).Print();
//}
//使用迭代器遍歷
IIterator iterator = CreateIterator();
while (iterator.HasNext())
{
((Component)iterator.Next()).Print();
}
}
public void PrintTarget()
{
//使用迭代器遍歷
IIterator iterator = CreateIterator();
while (iterator.HasNext())
{
Component component = (Component)iterator.Next();
try
{
if (component.IsTarget())
component.Print();
}
catch (NotImplementedException)
{
//Console.WriteLine("遍歷到菜單");
//component.Print();
}
}
}
public IIterator CreateIterator()
{
return new CompositeIterator(new ListIterator<Component>(components));
}
}
/// <summary>
/// 組合迭代器
/// 組合一個數(shù)組迭代器鸟雏,利用棧,遍歷樹形結構
/// </summary>
public class CompositeIterator : IIterator
{
Stack stack = new Stack();
public CompositeIterator(IIterator iterator)
{
stack.Push(iterator);
}
public bool HasNext()
{
if (stack.Count == 0)
{
return false;
}
else
{
IIterator iterator = (IIterator)stack.Peek();
if (!iterator.HasNext())
{
stack.Pop();
return HasNext();
}
else
{
return true;
}
}
}
public object Next()
{
if (HasNext())
{
IIterator iterator = (IIterator)stack.Peek();
Component component = (Component)iterator.Next();
if (component is ComponentMenu)
{
stack.Push(((ComponentMenu)component).CreateIterator());
}
return component;
}
else
{
return null;
}
}
}
internal class CompositePatternMain : IPattern
{
public void Main()
{
Component mainComponent = new ComponentMenu("主組件", "所有組件根節(jié)點");
Component Component1 = new ComponentMenu("1組件", "主組件1號節(jié)點");
Component Component2 = new ComponentMenu("2組件", "主組件2號節(jié)點");
Component Component3 = new ComponentMenu("3組件", "主組件3號節(jié)點");
Component Component11 = new ComponentMenu("1.1組件", "1號組件1號節(jié)點組件");
mainComponent.Add(Component1);
mainComponent.Add(Component2);
mainComponent.Add(Component3);
Component1.Add(Component11);
Component item1 = new ComponentItem("1葉子", "一號組件的葉子1", true);
Component item2 = new ComponentItem("2葉子", "二號組件的葉子1", true);
Component item3 = new ComponentItem("3葉子", "三號組件的葉子1", true);
Component item4 = new ComponentItem("4葉子", "1號組件1號節(jié)點組件的葉子1", true);
Component item5 = new ComponentItem("5葉子", "1號組件1號節(jié)點組件的葉子2", true);
Component1.Add(item1);
Component2.Add(item2);
Component3.Add(item3);
Component11.Add(item4);
Component11.Add(item5);
//mainComponent.Print();
((ComponentMenu)mainComponent).PrintTarget();//二級菜單會被遍歷兩次
Console.ReadLine();
}
}
}
狀態(tài)模式
- 定義
- 允許對象在內(nèi)部狀改變時改變他的行為览祖,對象看起來好像修改了它的類
- 解決問題
- 封裝不同狀態(tài)的行為孝鹊,易于拓展新功能
- 實現(xiàn)
- 上下文類
- 內(nèi)部狀態(tài)類
- 自己的方法
- 委托給狀態(tài)類處理的方法
- 抽象狀態(tài)類
- 上下文類
- 被委托的方法
- 上下文類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StatePattern
{
abstract class State
{
public abstract void Start();
public abstract void End();
}
class Context
{
public State beginState;
public State endState;
State state;
public Context()
{
beginState = new BeginState(this);
endState = new EndState(this);
state = beginState;
}
public void SetState(State state)
{
this.state = state;
}
public void Start()
{
state.Start();
}
public void End()
{
state.End();
}
}
class BeginState : State
{
Context context;
public BeginState(Context context)
{
this.context = context;
}
public override void Start()
{
Console.WriteLine("開始了");
context.SetState(context.endState);
}
public override void End()
{
throw new NotImplementedException();
}
}
class EndState : State
{
Context context;
public EndState(Context context)
{
this.context = context;
}
public override void Start()
{
throw new NotImplementedException();
}
public override void End()
{
Console.WriteLine("結束了");
context.SetState(context.beginState);
}
}
internal class StatePatternMain : IPattern
{
public void Main()
{
Context context = new Context();
context.Start();
context.End();
}
}
}
代理模式
- 定義
- 為另一個對象提供一個替身或者占位符以訪問這個對象
- 解決問題
- 方便控制客戶對對象的訪問
- 遠程代理
- 控制和遠程對象的交互
- 虛擬代理
- 控制和實例化開銷大的對象的交互
- 保護代理
- 實現(xiàn)控制權限訪問對象
- 遠程代理
- 反射機制
- 方便控制客戶對對象的訪問
- 實現(xiàn)
- 類似裝飾者
- 語言內(nèi)置代理
復合模式(MVC為例)
- 定義
- 結合兩個或以上的模式,組成一個解決方案解決問題
- 解決問題
- 大部分軟件開發(fā)需求無非就是輸入輸出
- MVC模式將軟件開發(fā)分為三層
- Model層實現(xiàn)應用邏輯展蒂,響應動作
- Contoller層又活,將Model和View解耦苔咪,根據(jù)具體用戶需求訪問Model
- View層,用戶交互
- 實現(xiàn)思路
- View
- 組合模式
- 組合控件
- 策略模式
- 組合控制器(和MOdel)
- 組合模式
- 控制器
- 中介模式
- 策略模式
- 模型
- View
- Model
- 觀察者模式
- View
備忘錄模式
- 定義
- 在不破壞封裝性的前提下柳骄,捕獲一個對象的內(nèi)部狀態(tài)团赏,并在該對象之外保存這個狀態(tài)。
- 解決問題
- 所謂備忘錄模式就是在不破壞封裝的前提下耐薯,捕獲一個對象的內(nèi)部狀態(tài)舔清,并在該對象之外保存這個狀態(tài),這樣可以在以后將對象恢復到原先保存的狀態(tài)曲初。
- 情景
- 打游戲時的存檔体谒,版本管理
- 回退功能
- 實現(xiàn)思路
- 類設計
- 備忘錄類
- CareTaker存儲備忘錄類
- Originator管理備忘錄類
- 使用
- 通過CareTaker和Originator管理備忘錄類
- 類設計
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
namespace MementoPattern
{
/// <summary>
/// 備忘錄類
/// </summary>
public class Memento<T>
{
T state;
public Memento(T state)
{
this.state = state;
}
public T GetState()
{
return state;
}
}
public class Originator<T>
{
T state;
public void SetState(T memento)
{
this.state = memento;
}
public T GetState()
{
return state;
}
public Memento<T> SaveStateToMemento()
{
return new Memento<T>(state);
}
public void GetStateFromMemento(Memento<T> Memento)
{
state = Memento.GetState();
}
}
public class CareTaker<T>
{
List<Memento<T>> mementos = new List<Memento<T>>();
public void Add(Memento<T> memento)
{
mementos.Add(memento);
}
public Memento<T> GetMemento(int index)
{
return mementos[index];
}
}
internal class MementoPatternMain : IPattern
{
public void Main()
{
Originator<string> originator = new Originator<string>();
CareTaker<string> careTaker = new CareTaker<string>();
originator.SetState("State #1");
originator.SetState("State #2");
careTaker.Add(originator.SaveStateToMemento());
originator.SetState("State #3");
careTaker.Add(originator.SaveStateToMemento());
originator.SetState("State #4");
Console.WriteLine(("Current State: " + originator.GetState()));
originator.GetStateFromMemento(careTaker.GetMemento(0));
Console.WriteLine("First saved State: " + originator.GetState());
originator.GetStateFromMemento(careTaker.GetMemento(1));
Console.WriteLine("Second saved State: " + originator.GetState());
}
}
}