<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        

      C#基礎(chǔ)系列——委托和設(shè)計(jì)模式(二)

      前言:前篇 C#基礎(chǔ)系列——委托實(shí)現(xiàn)簡單設(shè)計(jì)模式 簡單介紹了下委托的定義及簡單用法。這篇打算從設(shè)計(jì)模式的角度去解析下委托的使用。我們知道使用委托可以實(shí)現(xiàn)對象行為(方法)的動(dòng)態(tài)綁定,從而提高設(shè)計(jì)的靈活性。上次說過,方法可以理解為委托的實(shí)例,站在方法的層面,委托實(shí)例的一個(gè)非常有用的特性是它既不知道,也不關(guān)心其封裝方法所屬類的詳細(xì)信息,對它來說最重要的是這些方法與該委托的參數(shù)和返回值的兼容性。即只要方法的返回類型和參數(shù)表是相同的,則方法與委托類型兼容,方法的名稱及方法所屬類等信息委托是不關(guān)心的。有一定編程經(jīng)驗(yàn)的大俠們肯定都接觸過設(shè)計(jì)模式,其實(shí)設(shè)計(jì)模式大多數(shù)都是面向?qū)ο蠖鄳B(tài)特性的體現(xiàn),通過重寫子類方法去展現(xiàn)不同的設(shè)計(jì)需求,這樣看,既然是方法重寫,那么方法的參數(shù)類型和返回值類型肯定是一致的,這是不是和委托的實(shí)例十分相似,這樣說來,我們通過多態(tài)去實(shí)現(xiàn)的設(shè)計(jì)模式是否可以用委托的形式去代替。博主覺得,為了更好的理解委托,可以從這方面著手試試。。。

        時(shí)間過得真快,轉(zhuǎn)眼C#基礎(chǔ)系列已經(jīng)寫了8篇隨筆了,不管寫的好不好,博主都會(huì)繼續(xù),做事要有始有終嘛~~前天在園子看到一篇文章目錄的博文,這里將博主的系列文章也列一個(gè)目錄出來,這樣以后找起來也方便。

       

        此篇簡單抽取了幾個(gè)設(shè)計(jì)模式分別按照多態(tài)和委托的方式去實(shí)現(xiàn),當(dāng)然這里的重點(diǎn)并不是講設(shè)計(jì)模式,而是為了使讀者更好地理解委托。所以設(shè)計(jì)模式的很多細(xì)節(jié),本篇可能會(huì)略過。

      一、簡單工廠模式:本篇就借助計(jì)算器的例子加以說明。

      1、多態(tài)實(shí)現(xiàn)簡單工廠模式。

         class Program2
          {
              static void Main(string[] args)
              {
                  //1.使用多態(tài)實(shí)現(xiàn)簡單工廠模式
                  int x = 8, y = 2;
                  var iRes1 = GetObject("+").Compute(x, y);
                  var iRes2 = GetObject("-").Compute(x, y);
                  var iRes3 = GetObject("*").Compute(x, y);
                  var iRes4 = GetObject("/").Compute(x, y);
      
                  Console.WriteLine(iRes1);
                  Console.WriteLine(iRes2);
                  Console.WriteLine(iRes3);
                  Console.WriteLine(iRes4);
      
                  Console.ReadKey();
              }
      
              static Calculator GetObject(string type)
              {
                  Calculator oRes = null;
                  switch (type)
                  { 
                      case "+":
                          oRes = new Add();
                          break;
                      case "-":
                          oRes = new Subtract();
                          break;
                      case "*":
                          oRes = new Multiply();
                          break;
                      case "/":
                          oRes = new Divide();
                          break;
                  }
                  return oRes;
              }
          }
      
          public class Calculator
          {
              public virtual int Compute(int x, int y)
              {
                  return 0;
              }
          }
      
          public class Add : Calculator
          {
              public override int Compute(int x, int y)
              {
                  return x + y;
              }
          }
      
          public class Subtract : Calculator
          {
              public override int Compute(int x, int y)
              {
                  return x - y;
              }
          }
      
          public class Multiply : Calculator
          {
              public override int Compute(int x, int y)
              {
                  return x * y;
              }
          }
      
          public class Divide : Calculator
          {
              public override int Compute(int x, int y)
              {
                  if (y == 0)
                  {
                      return 0;
                  }
                  return x / y;
              }
          }

      代碼應(yīng)該很容易看懂,直接通過方法的重寫去實(shí)現(xiàn),在此就不過多講解。

       

      2、委托方式實(shí)現(xiàn)簡單工廠模式。

      class Program2
          {
              
              static void Main(string[] args)
              {
                  #region 2.委托實(shí)現(xiàn)簡單工廠模式
                  int x = 8, y = 2;
                  var oCalculator = new Calculator();
                  var iRes1 = oCalculator.Compute(x, y, oCalculator.Add);//將方法作為參數(shù)傳下去
                  var iRes2 = oCalculator.Compute(x, y, oCalculator.Subtract);
                  var iRes3 = oCalculator.Compute(x, y, oCalculator.Multiply);
                  var iRes4 = oCalculator.Compute(x, y, oCalculator.Divide);
      
                  Console.WriteLine(iRes1);
                  Console.WriteLine(iRes2);
                  Console.WriteLine(iRes3);
                  Console.WriteLine(iRes4); 
                  #endregion
      
                  Console.ReadKey();
              }
          }
      
          public delegate int DelegateCalculator(int x, int y);
      
          public class Calculator
          {
           //將方法的實(shí)例傳遞進(jìn)來,在Compute方法里面執(zhí)行
      public int Compute(int x, int y, DelegateCalculator calculator) { return calculator(x, y); } public int Add(int x, int y) { return x + y; } public int Subtract(int x, int y) { return x - y; } public int Multiply(int x, int y) { return x * y; } public int Divide(int x, int y) { if (y == 0) { return 0; } return x / y; } }

      這里需要定義四個(gè)實(shí)現(xiàn)方法Add、Subtract、Multiply、Divide,而不用在意這四個(gè)方法在哪個(gè)類下面,只要這四個(gè)方法的的參數(shù)和返回值和委托的定義保持一致即可。這也驗(yàn)證了上面說的 “站在方法的層面,委托實(shí)例的一個(gè)非常有用的特性是它既不知道,也不關(guān)心其封裝方法所屬類的詳細(xì)信息,對它來說最重要的是這些方法與該委托的參數(shù)和返回值的兼容性” 。兩種方式得到的結(jié)果是相同的:

       

      二、觀察者模式:觀察者模式最典型的場景就是訂閱者和訂閱號的場景

      1、純多態(tài)方式實(shí)現(xiàn)觀察者模式:這種代碼園子里面非常多。

      class Program3
          {
              static void Main(string[] args)
              {
                  // 具體主題角色通常用具體自來來實(shí)現(xiàn)
                  ConcreteSubject subject = new ConcreteSubject();
      
                  subject.Attach(new ConcreteObserver(subject, "Observer A"));
                  subject.Attach(new ConcreteObserver(subject, "Observer B"));
                  subject.Attach(new ConcreteObserver(subject, "Observer C"));
      
                  subject.SubjectState = "Ready";
                  subject.Notify();
      
                  Console.Read();
              }
          }
      
          //抽象主題類
          public abstract class Subject
          {
              private IList<Observer> observers = new List<Observer>();
      
              /// <summary>
              /// 增加觀察者
              /// </summary>
              /// <param name="observer"></param>
              public void Attach(Observer observer)
              {
                  observers.Add(observer);
              }
      
              /// <summary>
              /// 移除觀察者
              /// </summary>
              /// <param name="observer"></param>
              public void Detach(Observer observer)
              {
                  observers.Remove(observer);
              }
      
              /// <summary>
              /// 向觀察者(們)發(fā)出通知
              /// </summary>
              public void Notify()
              {
                  foreach (Observer o in observers)
                  {
                      o.Update();
                  }
              }
          }
      
          //具體主題類
          public class ConcreteSubject : Subject
          {
              private string subjectState;
      
              /// <summary>
              /// 具體觀察者的狀態(tài)
              /// </summary>
              public string SubjectState
              {
                  get { return subjectState; }
                  set { subjectState = value; }
              }
          }
      
          //抽象觀察者類
          public abstract class Observer
          {
              public abstract void Update();
          }
      
      
      
          //具體觀察者
          public class ConcreteObserver : Observer
          {
              private string observerState;
              private string name;
              private ConcreteSubject subject;
      
              /// <summary>
              /// 具體觀察者用一個(gè)具體主題來實(shí)現(xiàn)
              /// </summary>
              public ConcreteSubject Subject
              {
                  get { return subject; }
                  set { subject = value; }
              }
      
              public ConcreteObserver(ConcreteSubject subject, string name)
              {
                  this.subject = subject;
                  this.name = name;
              }
      
              /// <summary>
              /// 實(shí)現(xiàn)抽象觀察者中的更新操作
              /// </summary>
              public override void Update()
              {
                  observerState = subject.SubjectState;
                  Console.WriteLine("The observer's state of {0} is {1}", name, observerState);
              }
          }

      可以看到雖然已經(jīng)很好的實(shí)現(xiàn)了觀察者Observer 和主題Subject之間的分離。但是Subject的內(nèi)部還是有對觀察者的調(diào)用:

      public void Notify()
      {
           foreach (Observer o in observers)
           {
                o.Update();
           }
      }

       

      2、多態(tài)和委托實(shí)現(xiàn)觀察者模式。

         class Program3
          {
              static void Main(string[] args)
              {
                  // 具體主題角色通常用具體自來來實(shí)現(xiàn)
                  ConcreteSubject subject = new ConcreteSubject();
      
                  //傳入的只是觀察者的通過方法。
                  subject.Attach(new ConcreteObserver(subject, "Observer A").Update);
                  subject.Attach(new ConcreteObserver(subject, "Observer B").Update);
                  subject.Attach(new ConcreteObserver(subject, "Observer C").Update);
      
                  subject.SubjectState = "Ready";
                  subject.Notify();
      
                  Console.Read();
              }
          }
      
          public delegate void ObserverDelegate();
      
          //抽象主題類
          public abstract class Subject
          {
              public ObserverDelegate observedelegate;
      
              /// <summary>
              /// 增加觀察者
              /// </summary>
              /// <param name="observer"></param>
              public void Attach(ObserverDelegate observer)
              {
                  observedelegate += observer;
              }
      
              /// <summary>
              /// 移除觀察者
              /// </summary>
              /// <param name="observer"></param>
              public void Detach(ObserverDelegate observer)
              {
                  observedelegate -= observer;
              }
      
              /// <summary>
              /// 向觀察者(們)發(fā)出通知
              /// </summary>
              public void Notify()
              {
                  if (observedelegate != null)
                  {
                      observedelegate();
                  }
              }
          }
      
          //具體主題類
          public class ConcreteSubject : Subject
          {
              private string subjectState;
      
              /// <summary>
              /// 具體觀察者的狀態(tài)
              /// </summary>
              public string SubjectState
              {
                  get { return subjectState; }
                  set { subjectState = value; }
              }
          }
      
          //具體觀察者
          public class ConcreteObserver
          {
              private string observerState;
              private string name;
              private ConcreteSubject subject;
      
              /// <summary>
              /// 具體觀察者用一個(gè)具體主題來實(shí)現(xiàn)
              /// </summary>
              public ConcreteSubject Subject
              {
                  get { return subject; }
                  set { subject = value; }
              }
      
              public ConcreteObserver(ConcreteSubject subject, string name)
              {
                  this.subject = subject;
                  this.name = name;
              }
      
              /// <summary>
              /// 實(shí)現(xiàn)抽象觀察者中的更新操作
              /// </summary>
              public void Update()
              {
                  observerState = subject.SubjectState;
                  Console.WriteLine("The observer's state of {0} is {1}", name, observerState);
              }
          }

      得到結(jié)果:

      這樣設(shè)計(jì)的優(yōu)勢:

      (1)將通知的方法Update通過委托的形式傳入主題對象。這樣主題對象Subject就完全和觀察者隔離。更好地實(shí)現(xiàn)了低耦合。

      (2)減少了觀察者抽象類的定義。使整個(gè)設(shè)計(jì)更加精簡。

      (3)如果將設(shè)計(jì)更進(jìn)一步,觀察者這邊自定義delegate void ObserverDelegate()這種類型的方法。比如需要執(zhí)行Update()方法之后還要記錄一個(gè)日志的操作。如:

      //具體觀察者
          public class ConcreteObserver
          {
              private string observerState;
              private string name;
              private ConcreteSubject subject;
      
              /// <summary>
              /// 具體觀察者用一個(gè)具體主題來實(shí)現(xiàn)
              /// </summary>
              public ConcreteSubject Subject
              {
                  get { return subject; }
                  set { subject = value; }
              }
      
              public ConcreteObserver(ConcreteSubject subject, string name)
              {
                  this.subject = subject;
                  this.name = name;
              }
      
              /// <summary>
              /// 實(shí)現(xiàn)抽象觀察者中的更新操作
              /// </summary>
              public void Update()
              {
                  observerState = subject.SubjectState;
                  Console.WriteLine("The observer's state of {0} is {1}", name, observerState);
              }
      
              public void Log()
              {
                  Console.WriteLine("Log:Update方法執(zhí)行完成");
              }
          }

      那么在客戶端調(diào)用時(shí)只需要將Log方法以委托的形式傳入即可:

      static void Main(string[] args)
              {
                  // 具體主題角色通常用具體自來來實(shí)現(xiàn)
                  ConcreteSubject subject = new ConcreteSubject();
      
                  //傳入的只是觀察者的通過方法。
                  var obj = new ConcreteObserver(subject, "Observer A");
                  subject.Attach(obj.Update);
                  subject.Attach(obj.Log);
      
                  subject.SubjectState = "Ready";
                  subject.Notify();
      
                  Console.Read();
              }

      是不是顯得更靈活一點(diǎn)。如果是純多態(tài)的方式,由于Subject里面指定了調(diào)用Update()方法,所以當(dāng)需要增加Log方法的時(shí)候代碼的改變量要大。

       

      三、模板方法模式,這里就以設(shè)備采集為例來進(jìn)行說明:

      1、多態(tài)實(shí)現(xiàn)模板方法模式:

          class Program4
          {
              static void Main(string[] args)
              {
                  var oTem1 = new DeviceMML();
                  oTem1.Spider();
                  Console.WriteLine("");
                  var oTem2 = new DeviceTL2();
                  oTem2.Spider();
      
                  Console.ReadKey();
              }
          }
      
          public abstract class TempleteDevice
          {
              // 模板方法,不要把模版方法定義為Virtual或abstract方法,避免被子類重寫,防止更改流程的執(zhí)行順序
              public void Spider()
              {
                  Console.WriteLine("設(shè)備采集開始");
                  this.Login();
                  this.Validation();
                  this.SpiderByType1();
                  this.SpiderByType2();
                  this.LoginOut();
      
                  Console.WriteLine("設(shè)備采集結(jié)束");
              }
      
              // 登陸
              public void Login()
              {
                  Console.WriteLine("登陸");
              }
      
              // 驗(yàn)證
              public void Validation()
              {
                  Console.WriteLine("驗(yàn)證");
              }
      
              // 采集
              public abstract void SpiderByType1();
              public abstract void SpiderByType2();
      
              // 注銷
              public void LoginOut()
              {
                  Console.WriteLine("注銷");
              }
          }
      
          //MML類型的設(shè)備的采集
          public class DeviceMML : TempleteDevice
          {
              public override void SpiderByType1()
              {
                  Console.WriteLine("MML類型設(shè)備開始采集1");
                  //.......
              }
      
              public override void SpiderByType2()
              {
                  Console.WriteLine("MML類型設(shè)備開始采集2");
              }
          }
      
          //TL2類型設(shè)備的采集
          public class DeviceTL2 : TempleteDevice
          {
              public override void SpiderByType1()
              {
                  Console.WriteLine("TL2類型設(shè)備開始采集1");
                  //.......
              }
      
              public override void SpiderByType2()
              {
                  Console.WriteLine("TL2類型設(shè)備開始采集2");
              }
          }

      父類里面的非abstract方法都是模板方法,也就是子類公用并且不可以重寫的方法。SpiderType1和SpiderType2是需要子類重寫的方法。模板方法模式在抽象類中定義了算法的實(shí)現(xiàn)步驟,將這些步驟的實(shí)現(xiàn)延遲到具體子類中去實(shí)現(xiàn),從而使所有子類復(fù)用了父類的代碼,所以模板方法模式是基于繼承的一種實(shí)現(xiàn)代碼復(fù)用的技術(shù)。

       

      2、使用委托改寫后:

          class Program4
          {
              static void Main(string[] args)
              {
                  var oTem1 = new TempleteDevice(DeviceMML.SpiderByType1, DeviceMML.SpiderByType2);
                  oTem1.Spider();
      
                  Console.WriteLine("");
      
                  var oTem2 = new TempleteDevice(DeviceTL2.SpiderByType1, DeviceTL2.SpiderByType2);
                  oTem2.Spider();
                  Console.ReadLine();
              }
          }
      
          public delegate void DeviceDelegate();
      
          public class TempleteDevice
          {
              public DeviceDelegate oDelegate;
      
              public TempleteDevice(params DeviceDelegate[] lstFunc)
              {
                  foreach (var oFunc in lstFunc)
                  {
                      oDelegate += oFunc;
                  }
                  
              }
      
              // 模板方法,不要把模版方法定義為Virtual或abstract方法,避免被子類重寫,防止更改流程的執(zhí)行順序
              public void Spider()
              {
                  Console.WriteLine("設(shè)備采集開始");
                  this.Login();
                  this.Validation();
                  if (oDelegate != null)
                  {
                      oDelegate();
                  }
                  this.LoginOut();
      
                  Console.WriteLine("設(shè)備采集結(jié)束");
              }
      
              // 登陸
              public void Login()
              {
                  Console.WriteLine("登陸");
              }
      
              // 驗(yàn)證
              public void Validation()
              {
                  Console.WriteLine("驗(yàn)證");
              }
      
              // 注銷
              public void LoginOut()
              {
                  Console.WriteLine("注銷");
              }
          }
      
          //MML類型的設(shè)備的采集
          public class DeviceMML
          {
              public static void SpiderByType1()
              {
                  Console.WriteLine("MML類型設(shè)備開始采集1");
                  //.......
              }
      
              public static void SpiderByType2()
              {
                  Console.WriteLine("MML類型設(shè)備開始采集2");
              }
          }
      
          //TL2類型設(shè)備的采集
          public class DeviceTL2
          {
              public static void SpiderByType1()
              {
                  Console.WriteLine("TL2類型設(shè)備開始采集1");
                  //.......
              }
      
              public static void SpiderByType2()
              {
                  Console.WriteLine("TL2類型設(shè)備開始采集2");
              }
          }

      得到結(jié)果:

      優(yōu)化模板方法模式的意義:

      (1)解除了子類和父類之間的繼承關(guān)系,更好地實(shí)現(xiàn)了對象間的低耦合。

      (2)采用委托可以動(dòng)態(tài)實(shí)現(xiàn)方法的組合,這種方式更加靈活,子類可以更加靈活的設(shè)計(jì)不同部分的方法。然后方法的數(shù)量通過params來傳遞,方法的數(shù)量沒有什么嚴(yán)格的限制。

       

      當(dāng)然其他設(shè)計(jì)模式也可以使用委托去優(yōu)化設(shè)計(jì),博主在這里就暫時(shí)只分享這三種模式的異同。總的來說,委托不可能代替多態(tài)去實(shí)現(xiàn)各種模式,但是它和多態(tài)聯(lián)合起來使用可以實(shí)現(xiàn)更加靈活的設(shè)計(jì)。通過這兩篇下來,不知道你是否對委托有點(diǎn)感覺了呢,委托這東西,重在實(shí)戰(zhàn),就像游泳一樣,如果不用那么幾次,你永遠(yuǎn)也不可能學(xué)會(huì)。以上只是博主個(gè)人的理解,可能很多方便沒有考慮得那么全面,希望各位園友拍磚斧正~~

       

      posted @ 2015-08-10 08:59  懶得安分  閱讀(6864)  評論(13)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲欧洲无码av电影在线观看| 人人爽人人澡人人人妻| 一区二区三区一级黄色片| 亚洲成aⅴ人在线观看| 国产成人8X人网站视频| 国产精品国产三级国av| 亚洲中文精品久久久久久不卡| 在线观看视频一区二区三区| 男女一级国产片免费视频| 欧美日韩精品一区二区视频| 久久这里有精品国产电影网| 色偷偷久久一区二区三区| 国产精品成人午夜久久| 69天堂人成无码免费视频| 天天做天天爱夜夜夜爽毛片| 精品久久久久久无码中文字幕| 中文字幕人妻日韩精品| 小嫩模无套内谢第一次| 亚洲国产欧美在线人成| 国产亚洲一区二区三区av| 大陆熟妇丰满多毛xxxⅹ| 中国少妇人妻xxxxx| 九色综合久99久久精品| 色老头亚洲成人免费影院| 99久久成人亚洲精品观看| 亚洲精品美女久久久久9999| 人人爽人人爽人人片a免费| 久久精品国产久精国产| 最新精品国偷自产在线美女足| 日韩人妻无码一区二区三区综合部| 国产精品一码二码三码四码| 欧美成人精品手机在线| 亚洲AV国产福利精品在现观看| 日本九州不卡久久精品一区| 国产麻豆剧果冻传媒一区| 亚洲岛国成人免费av| 特级做a爰片毛片免费看无码| AV秘 无码一区二| 欧美大胆老熟妇乱子伦视频| 国产欧美亚洲精品第一页在线| 国产亚洲精品成人aa片新蒲金|