這篇文章主要介紹了.NET Framework中應(yīng)用策略模式如何為List排序,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
公司專注于為企業(yè)提供成都網(wǎng)站設(shè)計、網(wǎng)站制作、微信公眾號開發(fā)、成都做商城網(wǎng)站,微信小程序定制開發(fā),軟件專業(yè)公司等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。憑借多年豐富的經(jīng)驗(yàn),我們會仔細(xì)了解各客戶的需求而做出多方面的分析、設(shè)計、整合,為客戶設(shè)計出具風(fēng)格及創(chuàng)意性的商業(yè)解決方案,創(chuàng)新互聯(lián)公司更提供一系列網(wǎng)站制作和網(wǎng)站推廣的服務(wù)。簡單類型排序
編程時遇到排序在平常不過,使用.Net最常見的就是對泛型List
復(fù)制代碼 代碼如下:
public List
{
list.Sort();
return list;
}
同樣對string等簡單類型List
復(fù)制代碼 代碼如下:
void Sort
{
if (left < right)
{
T middle = array[(left + right) / 2];
int i = left - 1;
int j = right + 1;
while (true)
{
while (array[++i].CompareTo(middle) < 0) ;
while (array[--j].CompareTo(middle) > 0) ;
if (i >= j)
break;
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
Sort(array, left, i - 1, comparer);
Sort(array, j + 1, right, comparer);
}
}
問題
對于前兩種情況固然可以實(shí)現(xiàn)排序,但是我們不可能要求所有待排序的對象都實(shí)現(xiàn)IComparable接口,就算能夠保證每個對象都實(shí)現(xiàn)IComparable接口,如果想實(shí)現(xiàn)對象內(nèi)多個字段排序,比如Student對象,有時候想按照姓名排序,有時候是成績,有時候是年齡,這怎么破
按照面向?qū)ο蟮乃枷?,要把變化?dú)立出來,封裝變化,對于我們排序List
編寫通用的List
首先定義一個接口,里面有一個比較item大小的方法,在排序的時候作為參數(shù)傳入,當(dāng)然是傳入它的實(shí)現(xiàn)類,有了這個想法,我們可以自己寫個List
復(fù)制代碼 代碼如下:
public interface mparer_sly
int Compare(T x, T y);
}
然后為了測試,我們?yōu)長ist
復(fù)制代碼 代碼如下:
using System;
using System.Collections.Generic;
namespace Test.Stategy
{public class ListTest
{
public List
public void Sort(IComparer_sly
{
T[] array = list.ToArray();
int left = 0;
int right = array.Length - 1;
QuickSort(array, left, right, comparer);
list = new List
}
private void QuickSort(S[] array, int left, int right, IComparer_sly comparer)
{
if (left < right)
{
S middle = array[(left + right) / 2];
int i = left - 1;
int j = right + 1;
while (true)
{
while (comparer.Compare(array[++i], middle) < 0) ;
while (comparer.Compare(array[--j], middle) > 0) ;
if (i >= j)
break;
S temp = array[i];
array[i] = array[j];
array[j] = temp;
}
QuickSort(array, left, i - 1, comparer);
QuickSort(array, j + 1, right, comparer);
}
}
}
}
比如現(xiàn)在我們有個Student 的實(shí)體
復(fù)制代碼 代碼如下:
public class Student
{
public Student(int id, string name)
{
this.ID = id;
this.Name = name;
}
public int ID { get; set; }
public string Name { get; set; }
}
如果想對這個實(shí)體組成的List
復(fù)制代碼 代碼如下:
class StudentComparer : IComparer_sly
{
private string expression;
private bool isAscending;
public StudentComparer(string expression, bool isAscending)
{
this.expression = expression;
this.isAscending = isAscending;
}
public int Compare(Student x, Student y)
{
object v1 = GetValue(x), v2 = GetValue(y);
if (v1 is string || v2 is string)
{
string s1 = ((v1 == null) ? "" : v1.ToString().Trim());
string s2 = ((v2 == null) ? "" : v2.ToString().Trim());
if (s1.Length == 0 && s2.Length == 0)
return 0;
else if (s2.Length == 0)
return -1;
else if (s1.Length == 0)
return 1;
}
// 這里就偷懶調(diào)用系統(tǒng)方法,不自己實(shí)現(xiàn)了,其實(shí)就是比較兩個任意相投類型數(shù)據(jù)大小,自己實(shí)現(xiàn)比較麻煩
if (!isAscending)
return Comparer.Default.Compare(v2, v1);
return Comparer.Default.Compare(v1, v2);
}
private object GetValue(Student stu)
{
object v = null;
switch (expression)
{
case "id":
v = stu.ID;
break;
case "name":
v = stu.Name;
break;
default:
v = null;
break;
}
return v;
}
}
測試一下好不好使
復(fù)制代碼 代碼如下:
static void Main(string[] args)
{
ListTest
for (int i = 0; i < 10; i++)
{
Student stu = new Student(i,string.Format("N_"+(9-i)));
test.list.Add(stu);
}
Console.WriteLine("元數(shù)據(jù)");
for (int i = 0; i < test.list.Count;i++ )
{
Console.WriteLine(string.Format("ID:{0} , Name:{1}", test.list[i].ID, test.list[i].Name));
}
Console.WriteLine("Name 遞增");
test.Sort(new StudentComparer("name", true));
for (int i = 0; i < test.list.Count; i++)
{
Console.WriteLine(string.Format("ID:{0} , Name:{1}", test.list[i].ID, test.list[i].Name));
}
}
看看效果
.NET List的sort如何為我們排序
用ILSpy反編譯可以看到在調(diào)用List
策略模式
看清楚了上面這個例子我們就可以進(jìn)入正題,說說我們的策略模式了。策略模式定義了一系列的算法,并將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)
這個模式涉及到三個角色:
環(huán)境(Context)角色:持有一個Strategy類的引用。抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實(shí)現(xiàn)。此角色給出所有的具體策略類所需的接口。具體策略(ConcreteStrategy)角色:包裝了相關(guān)的算法或行為。
相信大家可以分方便的把我們上面例子中的類對應(yīng)上策略模式的角色,IComparer接口是我們的抽象策略角色, ListTest
使用場景
策略模式很容易理解,不過能夠用它很好的理解封裝變化和針對接口編程者兩個面向?qū)ο笤O(shè)計原則,我們來看看什么時候我們會用策略模式
1、 多個類只區(qū)別在表現(xiàn)行為不同,可以使用Strategy模式,在運(yùn)行時動態(tài)選擇具體要執(zhí)行的行為。
2、 需要在不同情況下使用不同的策略(算法),這些策略有統(tǒng)一接口。
3、 對客戶隱藏具體策略(算法)的實(shí)現(xiàn)細(xì)節(jié),彼此完全獨(dú)立。
策略模式的優(yōu)勢和不足
優(yōu)點(diǎn):
1、 提供了一種替代繼承的方法,而且既保持了繼承的優(yōu)點(diǎn)(代碼重用)還比繼承更靈活(算法獨(dú)立,可以任意擴(kuò)展)。
2、 使用組合,避免程序中使用多重條件轉(zhuǎn)移語句,使系統(tǒng)更靈活,并易于擴(kuò)展。
3、 遵守大部分GRASP原則和常用設(shè)計原則,高內(nèi)聚、低偶合。
缺點(diǎn):
1、 因?yàn)槊總€具體策略類都會產(chǎn)生一個新類,所以會增加系統(tǒng)需要維護(hù)的類的數(shù)量。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“.NET Framework中應(yīng)用策略模式如何為List排序”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!