大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要介绍了.NET Framework中应用策略模式如何为List排序,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
公司专注于为企业提供成都网站设计、网站制作、微信公众号开发、成都做商城网站,微信小程序定制开发,软件专业公司等一站式互联网企业服务。凭借多年丰富的经验,我们会仔细了解各客户的需求而做出多方面的分析、设计、整合,为客户设计出具风格及创意性的商业解决方案,创新互联公司更提供一系列网站制作和网站推广的服务。简单类型排序
编程时遇到排序在平常不过,使用.Net最常见的就是对泛型List
复制代码 代码如下:
public List
{
list.Sort();
return list;
}
同样对string等简单类型List
复制代码 代码如下:
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);
}
}
问题
对于前两种情况固然可以实现排序,但是我们不可能要求所有待排序的对象都实现IComparable接口,就算能够保证每个对象都实现IComparable接口,如果想实现对象内多个字段排序,比如Student对象,有时候想按照姓名排序,有时候是成绩,有时候是年龄,这怎么破
按照面向对象的思想,要把变化独立出来,封装变化,对于我们排序List
编写通用的List
首先定义一个接口,里面有一个比较item大小的方法,在排序的时候作为参数传入,当然是传入它的实现类,有了这个想法,我们可以自己写个List
复制代码 代码如下:
public interface mparer_sly
int Compare(T x, T y);
}
然后为了测试,我们为List
复制代码 代码如下:
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);
}
}
}
}
比如现在我们有个Student 的实体
复制代码 代码如下:
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; }
}
如果想对这个实体组成的List
复制代码 代码如下:
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;
}
// 这里就偷懒调用系统方法,不自己实现了,其实就是比较两个任意相投类型数据大小,自己实现比较麻烦
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;
}
}
测试一下好不好使
复制代码 代码如下:
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("元数据");
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反编译可以看到在调用List
策略模式
看清楚了上面这个例子我们就可以进入正题,说说我们的策略模式了。策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。(原文: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.)
这个模式涉及到三个角色:
环境(Context)角色:持有一个Strategy类的引用。抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
相信大家可以分方便的把我们上面例子中的类对应上策略模式的角色,IComparer接口是我们的抽象策略角色, ListTest
使用场景
策略模式很容易理解,不过能够用它很好的理解封装变化和针对接口编程者两个面向对象设计原则,我们来看看什么时候我们会用策略模式
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),这些策略有统一接口。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
策略模式的优势和不足
优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 使用组合,避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
感谢你能够认真阅读完这篇文章,希望小编分享的“.NET Framework中应用策略模式如何为List排序”这篇文章对大家有帮助,同时也希望大家多多支持创新互联网站建设公司,,关注创新互联行业资讯频道,更多相关知识等着你来学习!