自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

值得收藏的 C# 設(shè)計(jì)模式套路之三

開發(fā) 后端
名稱起得很明顯, 就是一個(gè)鏈?zhǔn)降呢?zé)任或任務(wù)。為什么要鏈?zhǔn)侥兀渴且驗(yàn)檎埱笠刂鄠€(gè)處理程序往后傳遞。一個(gè)任務(wù),可能要分很多步,又不想把所有的步驟耦合到一個(gè)處理程序中處理,就會(huì)用到這個(gè)套路。

[[437728]]

本文轉(zhuǎn)載自微信公眾號「老王Plus」,作者老王Plus的老王。轉(zhuǎn)載本文請聯(lián)系計(jì)老王Plus公眾號。

行為設(shè)計(jì)模式跟前兩種模式從內(nèi)容上是有區(qū)別的。行為設(shè)計(jì)模式更關(guān)注對象之間的通信,以及職責(zé)和任務(wù)的交互。

一、責(zé)任鏈

名稱起得很明顯, 就是一個(gè)鏈?zhǔn)降呢?zé)任或任務(wù)。為什么要鏈?zhǔn)侥?是因?yàn)檎埱笠刂鄠€(gè)處理程序往后傳遞。一個(gè)任務(wù),可能要分很多步,又不想把所有的步驟耦合到一個(gè)處理程序中處理,就會(huì)用到這個(gè)套路。

看看代碼:

  1. public interface IHandler 
  2.     public IHandler SetNext(IHandler handler); 
  3.     public object Handle(object input); 
  4. public class Handler : IHandler 
  5.     private IHandler _handler; 
  6.     public IHandler SetNext(IHandler handler) 
  7.     { 
  8.         _handler = handler; 
  9.         return handler; 
  10.     } 
  11.     public virtual object Handle(object input) 
  12.     { 
  13.         return _handler?.Handle(input); 
  14.     } 
  15. public class HandlerA : Handler 
  16.     public override object Handle(object input) 
  17.     { 
  18.         if (input as string == "A"
  19.         { 
  20.             Console.WriteLine("HandlerA : just return"); 
  21.             return true
  22.         } 
  23.         Console.WriteLine("HandlerA : call next handler"); 
  24.         return base.Handle(input); 
  25.     } 
  26. public class HandlerB : Handler 
  27.     public override object Handle(object input) 
  28.     { 
  29.         if (input as string == "B"
  30.         { 
  31.             Console.WriteLine("HandlerB : just return"); 
  32.             return true
  33.         } 
  34.         Console.WriteLine("HandlerB : call next handler"); 
  35.         return base.Handle(input); 
  36.     } 
  37. public class HandlerC : Handler 
  38.     public override object Handle(object input) 
  39.     { 
  40.         if (input as string == "C"
  41.         { 
  42.             Console.WriteLine("HandlerC : just return"); 
  43.             return true
  44.         } 
  45.         Console.WriteLine("HandlerC : end"); 
  46.         return base.Handle(input); 
  47.     } 
  48. public static class Example 
  49.     public static void Test() 
  50.     { 
  51.         var handlerA = new HandlerA(); 
  52.         var handlerB = new HandlerB(); 
  53.         var handlerC = new HandlerC(); 
  54.         handlerA.SetNext(handlerB).SetNext(handlerC); 
  55.         var resultOne = handlerA.Handle("A"); 
  56.         var resultTwo = handlerA.Handle("B"); 
  57.         var resultThree = handlerA.Handle("C"); 
  58.         var resultFour = handlerA.Handle("D"); 
  59.     } 
  60.     // results A: 
  61.     // HandlerA : just return 
  62.     // results B: 
  63.     // HandlerA : call next handler 
  64.     // HandlerB : just return 
  65.     // results C: 
  66.     // HandlerA : call next handler 
  67.     // HandlerB : call next handler 
  68.     // HandlerC : just return 
  69.     // results D: 
  70.     // HandlerA : call next handler 
  71.     // HandlerB : call next handler 
  72.     // HandlerC : end 

這里面,重要的是 handlerA.SetNext(handlerB).SetNext(handlerC) 一句。這個(gè)在限定鏈的方向和內(nèi)容。能理解到這一層,就算是真懂了。

二、命令

這個(gè)網(wǎng)上內(nèi)容很多,Command,通常會(huì)跟 Delegate、Event 一起說。

咱們這兒單說這個(gè)命令模式。

命令模式是一個(gè)非常常用的模式。它的作用,是把請求轉(zhuǎn)換為對象,以便我們可以異步、延遲、隊(duì)列或者參數(shù)化請求,以及做一些可撤銷的工作。

代碼套路特別簡單:

  1. public interface ICommand 
  2.     public void Execute(); 
  3. public class DemoCommand : ICommand 
  4.     private readonly string _parameter; 
  5.     public DemoCommand(string parameter) 
  6.     { 
  7.         _parameter = parameter; 
  8.     } 
  9.     public void Execute() 
  10.     { 
  11.         Console.WriteLine(_parameter); 
  12.     } 
  13. public static class Invoker 
  14.     public static void SendAction(ICommand command) 
  15.     { 
  16.         command.Execute(); 
  17.     } 
  18. public static class Example 
  19.     public static void Test() 
  20.     { 
  21.         var command = new DemoCommand("Hello WangPlus"); 
  22.         Invoker.SendAction(command); 
  23.     } 
  24.     // results: 
  25.     // Hello WangPlus 

這個(gè) Command 的應(yīng)用場景特別多,建議大家理解透徹。我們在做 SDK 或 類庫的時(shí)候,會(huì)經(jīng)常有類庫內(nèi)實(shí)現(xiàn)業(yè)務(wù)邏輯,而調(diào)用端實(shí)現(xiàn)數(shù)據(jù)交互的情況,用的就是命令模式。舉個(gè)例子說:做個(gè)認(rèn)證授權(quán)的類庫,庫里面去實(shí)現(xiàn)鑒權(quán)和生成 Token 的工作,調(diào)用端去判斷登錄帳號密碼的驗(yàn)證。這樣做,這個(gè)庫才能是一個(gè)跟數(shù)據(jù)庫和帳號體系無關(guān)的通用庫。

三、迭代器

這也是一個(gè)用得很多的模式。

它最主要的作用,就是遍歷集合的元素;而最主要的特性,就是不會(huì)暴露數(shù)據(jù)本身。

看代碼:

  1. public abstract class IteratorBase 
  2.     public abstract bool EndOfDocument(); 
  3.     public abstract object Next(); 
  4.     public abstract object First(); 
  5.     public abstract object Current(); 
  6. public class Iterator : IteratorBase 
  7.     private readonly List<object> _customList; 
  8.     private int current = 0; 
  9.     public Iterator(List<object> customList) 
  10.     { 
  11.         _customList = customList; 
  12.     } 
  13.     public override bool EndOfDocument() 
  14.     { 
  15.         if (current >= _customList.Count - 1) return true
  16.         return false
  17.     } 
  18.     public override object Current() 
  19.     { 
  20.         return _customList[current]; 
  21.     } 
  22.     public override object Next() 
  23.     { 
  24.         if (current < _customList.Count - 1) return _customList[++current]; 
  25.         return null
  26.     } 
  27.     public override object First() 
  28.     { 
  29.         return _customList[0]; 
  30.     } 
  31. public static class Example 
  32.     public static void Test() 
  33.     { 
  34.         var demolist = new List<object>() { "a""b""c""d" }; 
  35.         var iterator = new Iterator(demolist); 
  36.  
  37.         var item = iterator.First(); 
  38.         while (item != null
  39.         { 
  40.             Console.WriteLine(item); 
  41.             item = iterator.Next(); 
  42.         } 
  43.         if (iterator.EndOfDocument()) Console.WriteLine("Iterate done"); 
  44.     } 
  45.     //results: 
  46.     // a 
  47.     // b 
  48.     // c 
  49.     // d 
  50.     // Iterate done 

如果想了解迭代器的原理、異步及更深的應(yīng)用,可以去看看我專門講迭代器的文章一文說通C#中的異步迭代器

四、解釋器

這也是行為模式中一個(gè)常用的模式,它主要是根據(jù)上下文來獲取不同的類型和行為。換句話說,相同的內(nèi)容,針對不同的類型,采取不同的行為。

通常這個(gè)模式,用得最多的是多語言的場景。

  1. public class Context 
  2.     public string Value 
  3.     { 
  4.         get; 
  5.         private set
  6.     } 
  7.     public Context(string value) 
  8.     { 
  9.         Value = value; 
  10.     } 
  11. public abstract class Interpreter 
  12.     public abstract void Interpret(Context context); 
  13. public class EnglishInterpreter : Interpreter 
  14.     public override void Interpret(Context context) 
  15.     { 
  16.         switch (context.Value) 
  17.         { 
  18.             case "1"
  19.                 Console.WriteLine("One"); 
  20.                 break; 
  21.             case "2"
  22.                 Console.WriteLine("Two"); 
  23.                 break; 
  24.         } 
  25.     } 
  26. public class ChineseInterpreter : Interpreter 
  27.     public override void Interpret(Context context) 
  28.     { 
  29.         switch (context.Value) 
  30.         { 
  31.             case "1"
  32.                 Console.WriteLine("一"); 
  33.                 break; 
  34.             case "2"
  35.                 Console.WriteLine("二"); 
  36.                 break; 
  37.         } 
  38.     } 
  39. public static class Example 
  40.     public static void Test() 
  41.     { 
  42.         var interpreters = new List<Interpreter>() { 
  43.             new EnglishInterpreter(), 
  44.             new ChineseInterpreter() 
  45.         }; 
  46.         var context = new Context("2"); 
  47.         interpreters.ForEach(c => c.Interpret(context)); 
  48.     } 
  49.     // results: 
  50.     // two 
  51.     // 二 

上面這個(gè)例子是解釋器的標(biāo)準(zhǔn)套路。通常我們用的時(shí)候,可以配合抽象工廠模式,根據(jù)上下文獨(dú)立加載單個(gè)的解釋器,這樣就能實(shí)現(xiàn)類似根據(jù)瀏覽器的設(shè)定語言來顯示界面語言的代碼。

如果用微軟的標(biāo)準(zhǔn)庫來實(shí)現(xiàn),那這個(gè)解釋器和抽象工廠已經(jīng)被包在了庫里,使用時(shí)只需定義語言對照表就成。但內(nèi)里的邏輯,還是這個(gè)。

五、中介

注意,是中介,不是中間件。這是兩個(gè)東西,別用混了。

不過,兩個(gè)原理上有一點(diǎn)相像。中介模式,目的是解耦對象之間的直接通信,并轉(zhuǎn)為從中介對象來傳遞消息。

也是看代碼:

  1. public interface IMediator 
  2.     public void Send(string message, Caller caller); 
  3. public class Mediator : IMediator 
  4.     public CallerA CallerA 
  5.     { 
  6.         get; 
  7.         set
  8.     } 
  9.     public CallerB CallerB 
  10.     { 
  11.         get; 
  12.         set
  13.     } 
  14.     public void Send(string message, Caller caller) 
  15.     { 
  16.         if (caller.GetType() == typeof(CallerA)) 
  17.         { 
  18.             CallerB.ReceiveRequest(message); 
  19.         } 
  20.         else 
  21.         { 
  22.             CallerA.ReceiveRequest(message); 
  23.         } 
  24.     } 
  25. public abstract class Caller 
  26.     protected readonly IMediator _mediator; 
  27.     public Caller(IMediator mediator) 
  28.     { 
  29.         _mediator = mediator; 
  30.     } 
  31. public class CallerA : Caller 
  32.     public void SendRequest(string msg) 
  33.     { 
  34.         _mediator.Send(msg, this); 
  35.     } 
  36.     public void ReceiveRequest(string msg) 
  37.     { 
  38.         Console.WriteLine("CallerA Received : " + msg); 
  39.     } 
  40.     public CallerA(IMediator mediator) : base(mediator) { } 
  41. public class CallerB : Caller 
  42.     public void SendRequest(string msg) 
  43.     { 
  44.         _mediator.Send(msg, this); 
  45.     } 
  46.     public void ReceiveRequest(string msg) 
  47.     { 
  48.         Console.WriteLine("CallerB Received : " + msg); 
  49.     } 
  50.     public CallerB(IMediator mediator) : base(mediator) { } 
  51. public static class Example 
  52.     public static void Test() 
  53.     { 
  54.         var mediator = new Mediator(); 
  55.         var callerA = new CallerA(mediator); 
  56.         var callerB = new CallerB(mediator); 
  57.         mediator.CallerA = callerA; 
  58.         mediator.CallerB = callerB; 
  59.         callerA.SendRequest("Hello"); 
  60.         callerB.SendRequest("WangPlus"); 
  61.     } 
  62.     // results: 
  63.     // CallerB Received : Hello 
  64.     // CallerA Received : WangPlus 

CallerA 和 CallerB 之間沒有直接通信,而是經(jīng)由中介 Mediator 進(jìn)行了消息傳遞。

這個(gè)模式,最常用的場景是兩個(gè)現(xiàn)成的類庫之間要實(shí)現(xiàn)通訊,而不想或沒辦法修改這兩個(gè)類庫的代碼,就可以做一個(gè)中介庫,來進(jìn)行數(shù)據(jù)傳遞。

六、備忘錄

跟名字一樣。備忘錄模式主要是用來保存對象的狀態(tài),并將狀態(tài)封裝,以便在需要時(shí),恢復(fù)到前邊的狀態(tài)。

套路是這樣的:

  1. public class Memento 
  2.     private readonly string _state; 
  3.     public Memento(string state) 
  4.     { 
  5.         _state = state; 
  6.     } 
  7.     public string GetState() 
  8.     { 
  9.         return _state; 
  10.     } 
  11. public class Originator 
  12.     public string State 
  13.     { 
  14.         get; 
  15.         set
  16.     } 
  17.     public Originator(string state) 
  18.     { 
  19.         State = state; 
  20.     } 
  21.     public Memento CreateMemento() 
  22.     { 
  23.         return new Memento(State); 
  24.     } 
  25.     public void RestoreState(Memento memento) 
  26.     { 
  27.         State = memento.GetState(); 
  28.     } 
  29. public class Taker 
  30.     private Memento _memento; 
  31.     public void SaveMemento(Originator originator) 
  32.     { 
  33.         _memento = originator.CreateMemento(); 
  34.     } 
  35.     public void RestoreMemento(Originator originator) 
  36.     { 
  37.         originator.RestoreState(_memento); 
  38.     } 
  39.  
  40. public static class Example 
  41.     public static void Test() 
  42.     { 
  43.         var originator = new Originator("First State"); 
  44.         var careTaker = new Taker(); 
  45.         careTaker.SaveMemento(originator); 
  46.         Console.WriteLine(originator.State); 
  47.         originator.State = "Second State"
  48.         Console.WriteLine(originator.State); 
  49.         careTaker.RestoreMemento(originator); 
  50.         Console.WriteLine(originator.State); 
  51.     } 
  52.     // results: 
  53.     // First State 
  54.     // Second State 
  55.     // First State 

這個(gè)代碼看著復(fù)雜,其實(shí)核心就一點(diǎn):在改變狀態(tài)前,先把狀態(tài)在對象之外保存下來。

你細(xì)品。

七、觀察者

觀察者模式主要處理的是對象間一對多的通信。如果一個(gè)對象的狀態(tài)發(fā)生了變化,依賴對象會(huì)發(fā)出通知并進(jìn)行更新。

  1. public class Updater 
  2.     public string NewState 
  3.     { 
  4.         get; 
  5.     } 
  6.     private readonly List<ObserverBase> _observers = new List<ObserverBase>(); 
  7.     public Updater(string newState) 
  8.     { 
  9.         NewState = newState; 
  10.     } 
  11.     public void AddObserver(ObserverBase observerBase) 
  12.     { 
  13.         _observers.Add(observerBase); 
  14.     } 
  15.     public void BroadCast() 
  16.     { 
  17.         foreach (var observer in _observers) 
  18.         { 
  19.             observer.Update(); 
  20.         } 
  21.     } 
  22. public abstract class ObserverBase 
  23.     public abstract void Update(); 
  24. public class Observer : ObserverBase 
  25.     private readonly string _name; 
  26.     public string State; 
  27.     private readonly Updater _updater; 
  28.     public Observer(string name, string state, Updater updater) 
  29.     { 
  30.         _name = name
  31.         State = state; 
  32.         _updater = updater; 
  33.     } 
  34.     public override void Update() 
  35.     { 
  36.         State = _updater.NewState; 
  37.         Console.WriteLine($"Observer {_name} State Changed to : " + State); 
  38.     } 
  39. public static class Example 
  40.     public static void Test() 
  41.     { 
  42.         var updater = new Updater("WangPlus"); 
  43.         updater.AddObserver(new Observer("1""WangPlus1", updater)); 
  44.         updater.AddObserver(new Observer("2""WangPlus2", updater)); 
  45.         updater.AddObserver(new Observer("3""WangPlus3", updater)); 
  46.         updater.BroadCast(); 
  47.     } 
  48.     // results: 
  49.     // Observer 1 State Changed to : WangPlus 
  50.     // Observer 2 State Changed to : WangPlus 
  51.     // Observer 3 State Changed to : WangPlus 

好吧,這個(gè)代碼各上面?zhèn)渫浤J降拇a有點(diǎn)像。事實(shí)上,這兩個(gè)模式的主要區(qū)別,一個(gè)是一對一,一個(gè)是一對多。

至于為什么兩個(gè)模式的名稱區(qū)別這么大,說實(shí)話,我也不知道。在我的概念中,這兩個(gè)模式是可以混著用的。經(jīng)驗(yàn)來說,備忘錄模式我用得更多些。

八、狀態(tài)

狀態(tài)模式也是一個(gè)常用的模式。

狀態(tài)模式,和最前面的責(zé)任鏈模式,兩個(gè)有點(diǎn)類似。狀態(tài)模式更直接,就是狀態(tài)改變時(shí),同步改變行為。

這兩個(gè)模式,在很多情況下,可以有效減少 if…else 的分支數(shù)量。所以,看上去就又高大上了:)

上套路:

  1. public interface IState 
  2.     public void Handle(Context context); 
  3. public class StateA : IState 
  4.     public void Handle(Context context) 
  5.     { 
  6.         context.State = new StateB(); 
  7.     } 
  8. public class StateB : IState 
  9.     public void Handle(Context context) 
  10.     { 
  11.         context.State = new StateA(); 
  12.     } 
  13. public class Context 
  14.     private IState _state; 
  15.     public IState State 
  16.     { 
  17.         get => _state; 
  18.         set 
  19.         { 
  20.             _state = value; 
  21.             Console.WriteLine("State: " + _state.GetType().Name); 
  22.         } 
  23.     } 
  24.     public Context(IState state) 
  25.     { 
  26.         State = state; 
  27.     } 
  28.     public void Action() 
  29.     { 
  30.         State.Handle(this); 
  31.     } 
  32. public static class Example 
  33.     public static void Test() 
  34.     { 
  35.         var context = new Context(new StateA()); 
  36.         context.Action(); 
  37.         context.Action(); 
  38.         context.Action(); 
  39.         context.Action(); 
  40.     } 
  41.     // results: 
  42.     // State: StateA 
  43.     // State: StateB 
  44.     // State: StateA 
  45.     // State: StateB 
  46.     // State: StateA 

看懂了嗎?

如果把里面的 IState 換成 IHandler,那就是一個(gè)責(zé)任鏈。區(qū)別就是一個(gè)是數(shù)據(jù),一個(gè)是方法,除此之外都一樣。

所以,還是我老說的那句話:不要關(guān)心名稱,要關(guān)心實(shí)質(zhì)。在現(xiàn)代開發(fā)中,數(shù)據(jù)、方法、對象,其實(shí)都在趨向大一統(tǒng)的。明白這個(gè)道理,你就通了。

九、策略

策略模式主要是用來封裝算法族并使它們可互換,所以它們可以獨(dú)立地進(jìn)行更改,而不需要任何緊密耦合。

對,又是一個(gè)以解耦為目的的架構(gòu)。

  1. public interface IStrategy 
  2.     public void AlgorithmAction(); 
  3. public class AlgorithmStrategyA : IStrategy 
  4.     public void AlgorithmAction() 
  5.     { 
  6.         Console.WriteLine("This is Algorithm A"); 
  7.     } 
  8. public class AlgorithmStrategyB : IStrategy 
  9.     public void AlgorithmAction() 
  10.     { 
  11.         Console.WriteLine("This is Algorithm B"); 
  12.     } 
  13. public class Context 
  14.     private readonly IStrategy _strategy; 
  15.     public Context(IStrategy strategy) 
  16.     { 
  17.         _strategy = strategy; 
  18.     } 
  19.     public void GeneralAction() 
  20.     { 
  21.         _strategy.AlgorithmAction(); 
  22.     } 
  23. public static class Example 
  24.     public static void Test() 
  25.     { 
  26.         var context = new Context(new AlgorithmStrategyA()); 
  27.         context.GeneralAction(); 
  28.         context = new Context(new AlgorithmStrategyB()); 
  29.         context.GeneralAction(); 
  30.     } 
  31.     // results: 
  32.     // This is Algorithm A 
  33.     // This is Algorithm A 

這個(gè)模式的核心是上下文中的 IStrategy,這本身是一個(gè)抽象,這個(gè)抽象對應(yīng)的實(shí)體里,才是算法的實(shí)現(xiàn)。

一個(gè)標(biāo)準(zhǔn)的模式。

十、模板

模板模式是面向?qū)ο蟮囊粋€(gè)基礎(chǔ)模式,應(yīng)用也非常廣。

這個(gè)模式類似于抽象工廠模式,在基類上建立整體的操作結(jié)構(gòu),并根據(jù)需求的變動(dòng),在子類中重寫一些操作。

聽著很復(fù)雜,其實(shí)代碼一看就明白:

  1. public abstract class TemplateBase 
  2.     public void Operate() 
  3.     { 
  4.         FirstAction(); 
  5.         SecondAction(); 
  6.     } 
  7.     private void FirstAction() 
  8.     { 
  9.         Console.WriteLine("First action from template base"); 
  10.     } 
  11.     protected virtual void SecondAction() 
  12.     { 
  13.         Console.WriteLine("Second action from template base"); 
  14.     } 
  15. public class TemplateA : TemplateBase { } 
  16. public class TemplateB : TemplateBase 
  17.     protected override void SecondAction() 
  18.     { 
  19.         Console.WriteLine("Second action from template B"); 
  20.     } 
  21. public class TemplateC : TemplateBase 
  22.     protected override void SecondAction() 
  23.     { 
  24.         Console.WriteLine("Second action from template B"); 
  25.     } 
  26. public static class Example 
  27.     public static void Test() 
  28.     { 
  29.         var templateMethodA = new TemplateA(); 
  30.         var templateMethodB = new TemplateB(); 
  31.         var templateMethodC = new TemplateC(); 
  32.         templateMethodA.Operate(); 
  33.         templateMethodB.Operate(); 
  34.         templateMethodC.Operate(); 
  35.     } 
  36.     // results: 
  37.     // First action from template base 
  38.     // Second action from template base 
  39.     // First action from template base 
  40.     // Second action from template B 
  41.     // First action from template base 
  42.     // Second action from template B 

很簡單,對吧?

十一、訪問者

訪問者模式,是上面模板模式的一個(gè)變形,目的一樣,在不修改基類代碼的情況下,向子類的層次結(jié)構(gòu)中添加新的方法和行為。

看代碼:

  1. public interface IVisitor 
  2.     public void VisitItem(ItemBase item); 
  3. public class VisitorA : IVisitor 
  4.     public void VisitItem(ItemBase item) 
  5.     { 
  6.         Console.WriteLine("{0} visited by {1}", item.GetType().Name, this.GetType().Name); 
  7.     } 
  8. public class VisitorB : IVisitor 
  9.     public void VisitItem(ItemBase item) 
  10.     { 
  11.         Console.WriteLine("{0} visited by {1}", item.GetType().Name, this.GetType().Name); 
  12.     } 
  13. public abstract class ItemBase 
  14.     public abstract void Accept(IVisitor visitor); 
  15. public class ItemA : ItemBase 
  16.     public override void Accept(IVisitor visitor) 
  17.     { 
  18.         visitor.VisitItem(this); 
  19.     } 
  20.     public void ExtraOperationA() { } 
  21. public class ItemB : ItemBase 
  22.     public override void Accept(IVisitor visitor) 
  23.     { 
  24.         visitor.VisitItem(this); 
  25.     } 
  26.     public void ExtraOperationB() { } 
  27. public class StructureBuilder 
  28.     readonly List<ItemBase> _items = new List<ItemBase>(); 
  29.     public void AddItem(ItemBase element) 
  30.     { 
  31.         _items.Add(element); 
  32.     } 
  33.     public void Accept(IVisitor visitor) 
  34.     { 
  35.         foreach (var item in _items) 
  36.         { 
  37.             item.Accept(visitor); 
  38.         } 
  39.     } 
  40. public static class Example 
  41.     public static void Test() 
  42.     { 
  43.         var structure = new StructureBuilder(); 
  44.         structure.AddItem(new ItemA()); 
  45.         structure.AddItem(new ItemB()); 
  46.         structure.Accept(new VisitorA()); 
  47.         structure.Accept(new VisitorB()); 
  48.     } 
  49.     //results: 
  50.     //ItemA visited by VisitorA 
  51.     //ItemB visited by VisitorA 
  52.     //ItemA visited by VisitorB 
  53.     //ItemB visited by VisitorB 

訪問者模式擴(kuò)展了模板模式,擴(kuò)展性、復(fù)用性、靈活性更好,而且非常體現(xiàn)單一職責(zé)原則。

十二、總結(jié)

模式套路這就算是寫完了,居然用了三篇文章才寫完。

有沒有感覺?所有的模式,都是為了解耦。解耦的目的,是為了把一個(gè)系統(tǒng)分成更細(xì)的組件。細(xì)分組件更適合大團(tuán)隊(duì)的開發(fā)。而大團(tuán)隊(duì)的技術(shù)架構(gòu),更容易在網(wǎng)上的各種文章中有所體現(xiàn)。

所以,也跟大家提個(gè)醒:所有的架構(gòu)都是需要熟悉和掌握的,這叫面試必備的知識。在實(shí)際應(yīng)用中,如果架構(gòu)熟悉,所有的程序看著會(huì)更富有邏輯,而如果不熟悉架構(gòu),那看使用架構(gòu)寫出來的代碼,會(huì)是一場惡夢。

 

 

 

成長在于一點(diǎn)點(diǎn)的積累,于大家,于我,都一樣。

 

責(zé)任編輯:武曉燕 來源: 老王Plus
相關(guān)推薦

2021-11-10 11:13:02

C#設(shè)計(jì)模式

2024-03-20 10:59:37

開源

2009-08-26 10:24:04

C# Observer

2009-09-02 16:23:27

C# Singleto

2009-04-29 09:06:18

C#設(shè)計(jì)模式Adapter

2024-07-22 08:09:28

C#模式架構(gòu)

2009-08-31 16:01:31

C#和設(shè)計(jì)模式

2014-01-03 14:05:26

手游用戶體驗(yàn)設(shè)計(jì)啟動(dòng)和停止

2024-07-31 10:41:16

C#設(shè)計(jì)模式

2009-08-21 15:06:27

C#網(wǎng)絡(luò)聊天程序

2013-02-26 10:55:47

C#適配器設(shè)計(jì)模式

2009-08-19 17:26:28

C# 操作符

2023-01-13 09:53:32

2009-08-04 09:22:26

C#工廠模式

2010-11-29 09:26:05

jQuery特效

2009-08-31 16:12:02

C#使用Singlet

2021-02-16 10:57:34

C++ C 語言windows

2013-06-08 11:10:36

虛擬化虛擬化存儲

2013-05-28 09:33:47

虛擬化虛擬化存儲

2021-10-29 09:44:50

C++指針變量
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號