手机版

关于中的设计模式 NET框架-应用策略模式对列表进行排序

时间:2021-11-21 来源:互联网 编辑:宝哥软件园 浏览:

排序在简单类型排序编程中很常见,但却是最常见的使用方式。Net是对泛型列表进行排序。如果t是一个简单的数据类型排序,复制代码如下非常简单: Public Listint sort simplelist(Listint List){ List . sort();退货清单;}对于字符串等简单类型的列表也是如此。如果我们要排列的对象比较复杂,我们知道listsort()最后是通过quick sort实现的,这也不错。对于任何排序,我们都需要知道列表中项目之间的比较结果。如果是简单的int类型,我们可以直接判断。对于已经实现了IComparable接口的对象,可以调用它的CompareTo()来比较项的大小。以下是一种快速排序方法。复制代码如下: void sortt (t [] array,int left,int right,I comparer _ slytcomparer)其中t: I可比{ if(left right){ t middle=array[(left right)/2 }。int I=left-1;int j=右1;while (true){while (array[ i])。CompareTo(中间)0);while(数组[ - j]。CompareTo(中间)0);if(I=j)break;T temp=数组[I];数组[i]=数组[j];数组[j]=temp;}排序(数组,左,i - 1,比较器);排序(数组,j 1,右,比较器);}}问题对于前两种情况,排序是可以实现的,但是我们不能要求所有对象都要排序才能实现IComparable接口。即使我们可以确保每个对象都实现了IComparable接口,如果我们想对一个对象中的多个字段进行排序,比如Student对象,有时我们想按名字排序,有时按年级排序,有时按年龄排序。如何才能打破面向对象的思想?为了分离变化并封装变化,当我们对列表进行排序时,什么变化实际上是如何比较两个对象大小的算法。如果能把这个算法拿出来,排序会简单很多。无论是哪种,算法都是合理的。我们要封装的部分是如何比较两个项目大小的算法。为了实现可扩展性,我们应该遵循面向对象设计的另一个重要原则,为接口编程,而不是为实现编程。编写一个通用的ListT排序方法首先定义一个接口,其中有一个比较项大小的方法,排序时作为参数传入,当然还有它的实现类。有了这个想法,我们可以自己编写一个ListT排序方法,复制代码如下:公共接口mparer _ slyt {int compare (t x,t y);}然后,为了测试,我们为ListT添加了一个包装器,编写了自己的Sort方法,并用quick sort在内部实现。

一直困惑我们的变化部分——比较大小算法,我们把它封转起来,作为参数传入复制代码代码如下:使用系统;使用系统。集合。通用;命名空间测试. state gy { public class ListTest { public ListT list=new ListT();公共void Sort(IComparer _ Slyt comparer){ T[]数组=list .ToArray();int left=0;int right=数组。长度-1;快速排序(数组、左、右、比较器);列表=新列表(数组);}私人空间快速端口(S[]数组,int left,int right,IComparer _ Slys comparer){ if(left right){ S middle=数组[(左/右)/2];int I=left-1;int j=右1;while (true){while(比较器。比较(数组[ i],中间)0);而(比较器比较(数组[ - j],中间)0);if(I=j)断;s温度=数组[一];数组[i]=数组[j];数组[j]=温度;}QuickSort(array,left,i - 1,comparer);QuickSort(array,j 1,right,comparer);}}}} 比如现在我们有个学生的实体复制代码代码如下:公共类学生{公共学生(int id,字符串名称){this .ID=id这个名称=名称}公共整数标识{获取设置;}公共字符串名称{获取设置;}} 如果想对这个实体组成的列表进行排序,我们只需一个实现IComparer_slyStudent的类StudentComparer,并在内部实现其比较大小方法——Compare(),同时我们可以添加递增还是递减排序的控制复制代码代码如下:班级学生比较器: IComparer _ sly学生{私有字符串表达式;私有bool ISascending public StudentComparer(字符串表达式,bool Isascending){这个。表达式=表达式;this . isasceneding=isasceneding } public int Compare(Student x,Student y){object v1=GetValue(x),v2=GetValue(y);如果(v1是字符串|| v2是字符串){字符串s1=((v1==null)? v1 .ToString().trim());字符串s2=((v2==null)?”: v2 .ToString().trim());if (s1 .长度==0 s2 .长度==0)返回0;否则如果(s2 .长度==0)返回-1;否则如果(s1 .长度==0)返回1;}//这里就偷懒调用系统方法,不自己实现了,其实就是比较两个任意相投类型数据大小,自己实现比较麻烦if(!返回比较器。默认。比较(v2,v1);返回比较器.默认值。比较(v1,v2);}私有对象获取价值(学生)对象v=null开关(表达式){case 'id':v=stu .身份证;打破;case 'name':v=stu .名称;打破;default:v=null打破;}返回五;}} 测试一下好不好使复制代码代码如下:静态空隙主(字符串[]args){ listeststudent test=new listeststudent();for(int I=0;I 10I){ 0学生斯图=新学生(我,字符串。格式(' N _ '(9-I)));测试。名单。添加(stu);}控制台WriteLine(“”元数据');for(int I=0;我测试。列表。计数;I){控制台WriteLine(字符串。格式(' ID:{0},名称:{1},test.list[i].身份,测试.列表.姓名));}控制台。写线('名称递增');测试排序(新StudentComparer('name ',true));for(int I=0;我测试。列表。计数;I){控制台WriteLine(字符串。格式(' ID:{0},名称:{1},test.list[i].身份,测试.列表.姓名));}} 看看效果Capture

如何分类?通过用ILSpy反编译,我们可以看到这一点。排序(0,这个。当调用List的sort()方法时,在内部调用Count,null)。然后,经过一系列的异常处理,array.sortt(这。_ items,index,count,comparator)将被调用。这个。_items将列表的内容转换为数组,并在进行一些列异常处理后,调用arraysortelpert方法。default.sort(数组、索引、长度、比较器);在内部,它类似于我们上面写的方法,除了微软增加了很多异常处理和算法优化。看清楚上面的例子,我们就可以进入正题,谈谈我们的战略模式。该模式定义了一系列算法,封装了每个算法,并使它们可以互换。该模式允许算法独立于使用它的客户进行更改。(原文:策略模式定义了一系列算法,封装了每一个算法,并使它们可以互换。策略允许算法独立于使用它的客户端而变化。)9501.163.com

这个模式涉及三个角色:上下文角色:持有对策略类的引用。抽象策略角色:这是一个抽象角色,通常通过一个接口或者抽象类来实现。该角色提供所有特定策略类所需的接口。具体策略的作用:它封装了相关的算法或行为。我相信您可以很容易地将我们上面例子中的类分配给策略模式的角色。IComparer接口是我们的抽象策略角色,持有抽象策略的ListTestT类的引用是环境(在Sort方法中,实际上可以将接口定义为类的属性,并在构造函数中赋值,但不适合这种场景。毕竟,不是所有的列表都需要排序。不能强迫它接受一个可能不被使用的接口,当然每个实例使用一定的策略是合适的。)毫无疑问,我们实现IComparer抽象策略的类就是具体策略。使用场景Strategy模式很容易理解,但是对于界面程序员来说,它可以用来很好地理解包的变化和两个面向对象的设计原则。让我们看看何时使用策略模式。1.多个类只是在表达行为上有所不同,所以我们可以使用策略模式来动态选择要在运行时执行的特定行为。2.不同的环境下需要使用不同的策略(算法),这些策略有统一的接口。3.对客户隐藏具体策略(算法)的实现细节,完全相互独立。该策略的优缺点:1。它提供了一种替代继承的方法,既保留了继承(代码复用)的优点,又比继承更灵活(算法独立,可随意扩展)。2.使用组合避免了在程序中使用多个条件转移语句,使得系统更加灵活,易于扩展。3.符合大部分GRASP原则和通用设计原则,高内聚,低耦合。缺点:1。因为每个特定的策略类将生成一个新的类,它将增加系统需要维护的类的数量。

版权声明:关于中的设计模式 NET框架-应用策略模式对列表进行排序是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。