欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# 設(shè)計(jì)模式系列教程-策略模式

 更新時(shí)間:2016年06月01日 11:48:18   作者:Wang Juqiang  
策略模式是一種定義一系列算法的方法,從概念上來(lái)看,所有算法完成的都是相同的工作,只是實(shí)現(xiàn)不同,它可以以相同的方式調(diào)用所有的算法,減少了各種算法類(lèi)與使用算法類(lèi)之間的耦合。

  在講策略模式之前,我先給大家舉個(gè)日常生活中的例子,從首都國(guó)際機(jī)場(chǎng)到XXX酒店,怎么過(guò)去?1)酒店接機(jī)服務(wù),直接開(kāi)車(chē)來(lái)接。2)打車(chē)過(guò)去。3)機(jī)場(chǎng)快軌+地鐵 4)機(jī)場(chǎng)巴士 5)公交車(chē) 6)走路過(guò)去(不跑累死的話) 等等。使用方法,我們都可以達(dá)到從機(jī)場(chǎng)到XXX酒店的目的,對(duì)吧。那么我所列出的從機(jī)場(chǎng)到XXX酒店的的方法,就是我們可以選擇的策略。

  再舉個(gè)例子,就是我們使用WCF時(shí),往往避免不了對(duì)它進(jìn)行擴(kuò)展,例如授權(quán),我們可以通過(guò)自定義授權(quán)來(lái)擴(kuò)展WCF。這里我們可以通過(guò)自定義AuthorizationPolicy和ServiceAuthorizationManager來(lái)實(shí)現(xiàn)對(duì)它的擴(kuò)展,這是策略模式的一個(gè)真實(shí)應(yīng)用。

1. 概述

  它定義了算法家族,分別封裝起來(lái),讓它們之間可以互相替換,此模式讓算法的變化不會(huì)影響到使用算法的客戶(hù)端。

2. 模式中的角色

  2.1 策略類(lèi)(Stratege):定義所有支持的算法的公共接口。

  2.2 具體策略類(lèi)(Concrete Stratege):封裝了具體的算法或行為,繼承于Stratege類(lèi)。

  2.3 上下文類(lèi)(Context):用一個(gè)ConcreteStratege來(lái)配置,維護(hù)一個(gè)對(duì)Stratege對(duì)象的引用。

  對(duì)比開(kāi)篇例子分析一下這個(gè)模式中的角色:

  在從機(jī)場(chǎng)到XXX酒店的這個(gè)例子中,策略類(lèi)中必然要包括GoToHotel這個(gè)方法。而具體策略類(lèi)應(yīng)該實(shí)現(xiàn)或繼承策略類(lèi),它的實(shí)現(xiàn)就不用說(shuō)了。上下文類(lèi),這個(gè)類(lèi)很重要,也很有意思,因?yàn)樗枰ミx擇使用哪個(gè)策略,例如這個(gè)上下我是我,我要從機(jī)場(chǎng)到XXX酒店,1)我根本不差錢(qián),酒店也提供接機(jī)服務(wù),那我必然選擇酒店接機(jī)呀;2)如果酒店不提供接機(jī)我就選擇打的。3)如果我囊中羞澀,就可以選擇公共交通。4)如果我現(xiàn)在錢(qián)都花完了,連吃飯的錢(qián)都沒(méi)有了,那么我只能選擇走路過(guò)去了,沒(méi)準(zhǔn)半道上還得討飯呢!

3. 模式解讀

  3.1 策略模式的一般化類(lèi)圖

http://img.jbzj.com/file_images/article/201606/2016060111500833.png

  3.2 策略模式的代碼實(shí)現(xiàn)

 /// <summary>
 /// 策略類(lèi),定義了所有支持的算法的公共接口
 /// </summary>
 public abstract class Stratege
 {
  /// <summary>
  /// 策略類(lèi)中支持的算法,當(dāng)然還可以有更多,這里只定義了一個(gè)。
  /// </summary>
  public abstract void Algorithm();
 }

 /// <summary>
 /// 具體策略 A,實(shí)現(xiàn)了一種具體算法
 /// </summary>
 public class ConcreteStrategeA : Stratege
 {

  /// <summary>
  /// 具體算法
  /// </summary>
  public override void Algorithm()
  {
   // 策略A中實(shí)現(xiàn)的算法
  }
 }
 /// <summary>
 /// 具體策略 B,實(shí)現(xiàn)了一種具體算法
 /// </summary>
 public class ConcreteStrategeB : Stratege
 {

  /// <summary>
  /// 具體算法
  /// </summary>
  public override void Algorithm()
  {
   // 策略B中實(shí)現(xiàn)的算法
  }
 }


 /// <summary>
 /// Context 上下文,維護(hù)一個(gè)對(duì)Stratege對(duì)象的引用
 /// </summary>
 public class Context
 {
  private Stratege m_Stratege;

  /// <summary>
  /// 初始化上下文時(shí),將具體策略傳入
  /// </summary>
  /// <param name="stratege"></param>
  public Context(Stratege stratege)
  {
   m_Stratege = stratege;
  }

  /// <summary>
  /// 根據(jù)具體策略對(duì)象,調(diào)用其算法
  /// </summary>
  public void ExecuteAlgorithm()
  {
   m_Stratege.Algorithm();
  }
 }

4. 模式總結(jié)

  4.1 優(yōu)點(diǎn)

    4.1.1 策略模式是一種定義一系列算法的方法,從概念上來(lái)看,所有算法完成的都是相同的工作,只是實(shí)現(xiàn)不同,它可以以相同的方式調(diào)用所有的算法,減少了各種算法類(lèi)與使用算法類(lèi)之間的耦合。

    4.1.2 策略模式的Stratege類(lèi)為Context定義了一系列的可供重用的算法或行為。繼承有助于析取出這些算法的公共功能。

    4.1.3 策略模式每個(gè)算法都有自己的類(lèi),可以通過(guò)自己的接口單獨(dú)測(cè)試。因而簡(jiǎn)化了單元測(cè)試。

    4.1.4 策略模式將具體算法或行為封裝到Stratege類(lèi)中,可以在使用這些類(lèi)中消除條件分支(避免了不同行為堆砌到一個(gè)類(lèi)中)。

  4.2 缺點(diǎn)

    將選擇具體策略的職責(zé)交給了客戶(hù)端,并轉(zhuǎn)給Context對(duì)象

  4.3 適用場(chǎng)景

    4.3.1 當(dāng)實(shí)現(xiàn)某個(gè)功能需要有不同算法要求時(shí)

    4.3.2 不同時(shí)間應(yīng)用不同的業(yè)務(wù)規(guī)則時(shí)

5. 實(shí)例:排序是我們經(jīng)常接觸到的算法,實(shí)現(xiàn)對(duì)一個(gè)數(shù)組的排序有很多方法,即可以采用不同的策略。下面給出了排序功能的策略模式的解決方案。

  5.1 實(shí)現(xiàn)類(lèi)圖

http://img.jbzj.com/file_images/article/201606/2016060111500834.png

  5.2 代碼實(shí)現(xiàn)

 /// <summary>
 /// 排序算法策略
 /// </summary>
 public abstract class SortStratege
 {
  /// <summary>
  /// 排序
  /// </summary>
  /// <param name="array"></param>
  /// <returns></returns>
  public abstract int[] Sort(int[] array);
 }

 /// <summary>
 /// 冒泡排序
 /// </summary>
 public class BubbleSort : SortStratege
 {
  /// <summary>
  /// 冒泡排序算法(遞增排序)
  /// </summary>
  /// <param name="array"></param>
  /// <returns></returns>
  public override int[] Sort(int[] array)
  {
   // 實(shí)現(xiàn)冒泡排序算法
   for (int i = 0; i < array.Length; i++)
   {
    for (int j = i + 1; j < array.Length; j++)
    {
     if (array[i] > array[j])
     {
      int temp = array[j];
      array[j] = array[i];
      array[i] = temp;
     }
    }
   }

   return array;
  }
 }

 /// <summary>
 /// 插入排序
 /// </summary>
 public class InsertSort : SortStratege
 {

  /// <summary>
  /// 插入排序算法(遞增排序)
  /// </summary>
  /// <param name="array"></param>
  /// <returns></returns>
  public override int[] Sort(int[] array)
  {
   // 實(shí)現(xiàn)插入排序算法
   int temp;
   int i, j, n;
   n = array.Length;

   for (i = 1; i < n; i++)
   {
    temp = array[i];
    for (j = i; j > 0; j--)
    {
     if (temp < array[j - 1])
      array[j] = array[j - 1];
     else
      break;

     array[j] = temp;
    }
   }
   return null;
  }
 }

 public class SortContext
 {
  private int[] m_Array;
  private SortStratege m_Stratege;

  /// <summary>
  /// 初始化時(shí)將要排序的數(shù)組和排序策略傳入給Context
  /// </summary>
  /// <param name="array"></param>
  /// <param name="stratege"></param>
  public SortContext(int[] array, SortStratege stratege)
  {
   m_Array = array;
   m_Stratege = stratege;
  }

  /// <summary>
  /// 調(diào)用排序算法
  /// </summary>
  /// <returns></returns>
  public int[] Sort()
  {
   int[] result = m_Stratege.Sort(this.m_Array);

   return result;
  }
 }

  5.3 客戶(hù)端代碼

 public class Program
 {
  public static void Main(Object[] args)
  {
   int[] array = new int[] { 12, 8, 9, 18, 22 };

   //使用冒泡排序算法進(jìn)行排序
   SortStratege sortStratege = new BubbleSort();
   SortContext sorter = new SortContext(array, sortStratege);
   int[] result = sorter.Sort();

   //使用插入排序算法進(jìn)行排序
   SortStratege sortStratege2 = new InsertSort();
   SortContext sorter2 = new SortContext(array, sortStratege2);
   int[] result2 = sorter.Sort();
  }
 }

以上就是本文的全部?jī)?nèi)容,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#文件操作、讀取文件、Debug/Trace類(lèi)用法

    C#文件操作、讀取文件、Debug/Trace類(lèi)用法

    這篇文章介紹了C#文件操作、讀取文件、Debug/Trace類(lèi)的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解

    Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • C# WPF ListView控件的實(shí)例詳解

    C# WPF ListView控件的實(shí)例詳解

    這篇文章主要介紹了C# WPF ListView控件的實(shí)例詳解的相關(guān)資料,希望通過(guò)本能幫助到大家,讓大家掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • C#中獲取程序路徑的幾種方法及其區(qū)別說(shuō)明

    C#中獲取程序路徑的幾種方法及其區(qū)別說(shuō)明

    這篇文章主要介紹了C#中獲取程序路徑的幾種方法及其區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • C# 創(chuàng)建報(bào)表過(guò)程詳解

    C# 創(chuàng)建報(bào)表過(guò)程詳解

    本文給大家介紹的是使用vs2012 c#創(chuàng)建報(bào)表的全部過(guò)程的記錄,十分的詳細(xì),有需要的小伙伴可以參考下。
    2015-06-06
  • 基于WPF實(shí)現(xiàn)PDF的顯示與轉(zhuǎn)換

    基于WPF實(shí)現(xiàn)PDF的顯示與轉(zhuǎn)換

    這篇文章為大家詳細(xì)主要介紹了如何基于WPF實(shí)現(xiàn)PDF的顯示并轉(zhuǎn)換成圖片,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • 一文帶你了解C#操作MySql的方法

    一文帶你了解C#操作MySql的方法

    工作中大多數(shù)情況下用的都是 MySql 但一直沒(méi)有記錄,相關(guān)操作。這篇文章以便 MySql.Data 庫(kù)進(jìn)行MySql操作,使用 C# 執(zhí)行 SQL 語(yǔ)句,造個(gè)輪子
    2023-03-03
  • Unity3d 如何更改Button的背景色

    Unity3d 如何更改Button的背景色

    這篇文章主要介紹了unity3d GUI.Button 自定義字體大小及透明背景方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • C#使用DevExpress中的SplashScreenManager控件實(shí)現(xiàn)啟動(dòng)閃屏和等待信息窗口

    C#使用DevExpress中的SplashScreenManager控件實(shí)現(xiàn)啟動(dòng)閃屏和等待信息窗口

    這篇文章介紹了C#使用DevExpress中的SplashScreenManager控件實(shí)現(xiàn)啟動(dòng)閃屏和等待信息窗口的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C#實(shí)現(xiàn)向數(shù)組指定索引位置插入新的元素值

    C#實(shí)現(xiàn)向數(shù)組指定索引位置插入新的元素值

    這篇文章給大家介紹了利用C#實(shí)現(xiàn)向數(shù)組指定索引位置插入新的元素值,首先需要定義一個(gè)一維數(shù)組,然后修改數(shù)組的長(zhǎng)度,從而在其中增加一個(gè)元素,需要的朋友可以參考下
    2024-02-02

最新評(píng)論