亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#中的TemplateMethod模式問(wèn)題分析

 更新時(shí)間:2020年06月04日 09:08:32   作者:傷之哀霜  
這篇文章主要介紹了C#中的TemplateMethod模式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一個(gè)真實(shí)的故事

大學(xué)的時(shí)候就開(kāi)過(guò)一門(mén)課程,講設(shè)計(jì)模式,可是大學(xué)生沒(méi)什么編程實(shí)踐經(jīng)驗(yàn),在大學(xué)里面聽(tīng)設(shè)計(jì)模式的感覺(jué),就像聽(tīng)天書(shū)。聽(tīng)著都有道理,可是完全領(lǐng)會(huì)不到其中的奧妙,大抵原因就在于沒(méi)有走過(guò)彎路,沒(méi)有吃過(guò)設(shè)計(jì)不當(dāng)?shù)奶?。古人云,“操千曲而后曉聲,觀(guān)千劍而后識(shí)器”,誠(chéng)不欺我。

博主在之前的某個(gè)項(xiàng)目中,設(shè)計(jì)出了一些工具類(lèi),像屬性窗口,錯(cuò)誤提示窗口,還有一個(gè)窗口管理類(lèi)管理它們,當(dāng)時(shí)我實(shí)現(xiàn)工具保存時(shí)候的代碼是這樣的:

 class WindowManager
 {
  private List<ITool> _Tools = new List<ITool>();  

  public void AddTool(ITool tool)
  {
   _Tools.Add(tool);
  }

  public void SaveAllTools()
  {
   foreach(var tool in _Tools)
   {
    tool.Save();
   }
  }
 }

 interface ITool
 {
  bool BeforeSave();
  void Save();
  void AfterSave();
 }

 class PropertyWindow : ITool
 {
  public bool BeforeSave()
  {
   //do something specific here
   return true;
  }

  public void Save()
  {
   if (BeforeSave())
   {
    //do save
    AfterSave();
   }
  }

  public void AfterSave()
  {

  }
 }

 class ErrorLis : ITool
 {
  public bool BeforeSave()
  {
   //do something specific here
   return true;
  }

  public void Save()
  {
   if (BeforeSave())
   {
    //do save
    AfterSave();
   }
  }

  public void AfterSave()
  {

  }
 }

當(dāng)時(shí)博主對(duì)這段代碼還挺滿(mǎn)意,完全沒(méi)有看出這兒有什么問(wèn)題,覺(jué)得這簡(jiǎn)直寫(xiě)的太OO了,有類(lèi),有接口,有針對(duì)接口編程,至于新加的工具類(lèi),也不會(huì)影響原來(lái)的代碼,簡(jiǎn)直太符合開(kāi)閉原則了。老鐵,沒(méi)毛??!

好日子就這么繼續(xù)下去,每當(dāng)需要新添加一個(gè)工具,我就新加一個(gè)類(lèi),在類(lèi)里面實(shí)現(xiàn)Save的邏輯,直到有一天,添加了一個(gè)ResourceControl

 class ResourceControl : ITool
 {
  public bool BeforeSave()
  {
   //do something specific here
   return true;
  }

  public void Save()
  {
   if (!BeforeSave())
   {
    //do save
    AfterSave();
   }
  }

  public void AfterSave()
  {

  }
 }

在它的save里面,我把if(BeforeSave())寫(xiě)成了if(!BeforeSave())。。。
于是,我又額外花了一些時(shí)間來(lái)找到這個(gè)問(wèn)題,修改它并在下次添加新類(lèi)的時(shí)候戰(zhàn)戰(zhàn)兢兢提醒自己不要犯這種低級(jí)的錯(cuò)誤。那么,我們有沒(méi)有好的辦法來(lái)解決這個(gè)問(wèn)題呢?

問(wèn)題分析

其實(shí)就算每次添加新類(lèi)的時(shí)候我們都能仔細(xì)的小心避免維護(hù)相同的邏輯,這段代碼的設(shè)計(jì)也還是有可以改進(jìn)的地方,比如,BeforeSave和AfterSave在這里作為接口ITool的一部分而公開(kāi),意味著客戶(hù)代碼可以自由的調(diào)用BeforeSave和AfterSave,然而這很可能并不是代碼作者的本意,畢竟,不調(diào)用Save而單獨(dú)調(diào)用BeforeSave和AfterSave有什么意義呢?讓客戶(hù)能夠看到更多不必要的方法,增加了客戶(hù)錯(cuò)誤使用接口的可能性,不是么?

綜上所述,我們需要解決的問(wèn)題如下:

  • 抽象出Save, BeforeSave和AfterSave的邏輯關(guān)系,在一個(gè)地方固定下來(lái),確保新增加的類(lèi)所實(shí)現(xiàn)的這三個(gè)方法,都能自動(dòng)具有這種邏輯關(guān)系。
  • 對(duì)客戶(hù)代碼隱藏不必要的接口。 

這種場(chǎng)景下面,我們需要用到設(shè)計(jì)模式中的TemplateMethod(模版方法)模式。 

TemplateMethod模式

WIKI上面,TemplateMethod模式的定義如下,
In software engineering, the template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in an operation, deferring some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure.

大概意思就是,模版方法模式是一種行為類(lèi)設(shè)計(jì)模式,允許軟件在更高的層次定義程序骨架,但是可以在子類(lèi)推遲實(shí)現(xiàn)某些步驟。

類(lèi)圖如下:

這完全符合我們的需求,讓我們?cè)囍薷奈覀兊拇a。

使用TemplateMethod重新實(shí)現(xiàn)的代碼

 class WindowManager
 {
  private List<AbstractTool> _Tools = new List<AbstractTool>();  

  public void AddTool(AbstractTool tool)
  {
   _Tools.Add(tool);
  }

  public void SaveAllTools()
  {
   foreach(var tool in _Tools)
   {
    tool.Save();
   }
  }
 }

 abstract class AbstractTool
 {
  protected abstract bool BeforeSave();
  protected abstract void DoSave();
  protected abstract void AfterSave();
  public void Save()
  {
   if(!BeforeSave())
   {
    DoSave();
    AfterSave();
   }

  }  
 }

 class PropertyWindow : AbstractTool
 {
  protected override bool BeforeSave()
  {
   //do something specific here
   return true;
  }

  protected override void DoSave()
  {
   
  }

  protected override void AfterSave()
  {

  }
 }

 class ErrorLis : AbstractTool
 {
  protected override bool BeforeSave()
  {
   //do something specific here
   return true;
  }

  protected override void DoSave()
  {

  }

  protected override void AfterSave()
  {

  }
 }

從上面我們可以看到,我們用一個(gè)抽象類(lèi)AbstractTool代替之前的ITool接口,抽象類(lèi)和接口的一個(gè)區(qū)別就是,抽象類(lèi)可以在其中嵌入某些邏輯,所以我們?cè)赟ave這個(gè)公共的非虛方法中,完全實(shí)現(xiàn)了我們的BeforeSave和AfterSave邏輯,僅僅留下了BeforeSave,AfterSave和DoSave給子類(lèi)覆蓋。這樣我們得到的好處是:

  • 抽象類(lèi)只公開(kāi)了一個(gè)Save方法,所以客戶(hù)代碼不用擔(dān)心會(huì)調(diào)用其他錯(cuò)誤的方法。
  • 抽象類(lèi)完全固定了Save邏輯,先調(diào)用BeforeSave檢查,之后執(zhí)行DoSave進(jìn)行具體的Save事項(xiàng),最后進(jìn)行AfterSave行為。子類(lèi)只需要重新依據(jù)子類(lèi)的需求覆蓋這三個(gè)虛方法即可。新添加的工具類(lèi),只要覆蓋這三個(gè)虛方法,至于虛方法之間的邏輯,抽象類(lèi)已經(jīng)固定,不用擔(dān)心。

結(jié)論

“紙上得來(lái)終覺(jué)淺,絕知此事要躬行”,祖宗的話(huà),不會(huì)錯(cuò)的,如果沒(méi)有一定的編程實(shí)踐和總結(jié),是沒(méi)有辦法領(lǐng)悟設(shè)計(jì)模式的,博主也是通過(guò)之前那個(gè)例子才領(lǐng)悟到TemplateMethod模式的妙用。

到此這篇關(guān)于C#中的TemplateMethod模式問(wèn)題分析的文章就介紹到這了,更多相關(guān)C# TemplateMethod模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論