|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
不可能天天有学习.net),我一同学说,你应该早就有作品啦。我惶惶然……封装|排序|算法 假想如许一个需求,我们必要为本人的框架供应一个卖力排序的组件。今朝必要完成的是冒泡排序算法和疾速排序算法,依据“面向接口编程”的头脑,我们能够为这些排序算法供应一个一致的接口ISort,在这个接口中有一个办法Sort(),它能承受一个object数组参数。对数组举行排序后,前往该数组。接口的界说以下:
publicinterfaceISort
{
voidSort(refobject[]beSorted);
}
其类图以下:
但是一样平常关于排序而言,分列是有按次之分的,比方升序,大概降序,前往的了局也不不异。最复杂的办法我们能够使用if语句来完成这一目标,比方在QuickSort类中:
publicclassQuickSort:ISort
{
privatestringm_SortType;
publicQuickSort(stringsortType)
{
m_SortType=sortType;
}
publicvoidSort(refobject[]beSorted)
{
if(m_SortType.ToUpper().Trim()==“ASCENDING”)
{
//实行升序的疾速排序;
}
else
{
//实行降序的疾速排序;
}
}
}
固然,我们也能够将string范例的SortType界说为列举范例,削减呈现毛病的大概性。但是细心浏览代码,我们能够发明如许的代码长短常僵化的,一旦必要扩大,假如请求我们增添新的排序按次,比方字典按次,那末我们面对的事情会十分沉重。也就是说,变更发生了。经由过程剖析,我们发明所谓排序的按次,恰好是排序算法中最关头的一环,它决意了谁分列在前,谁分列在后。但是它其实不属于排序算法,而是一种对照的战略,后者说是对照的举动。
假如细心剖析完成ISort接口的类,比方QuickSort类,它在完成排序算法的时分,必要对两个工具作对照。依照重构的做法,本色上我们能够在Sort办法中抽掏出一个公有办法Compare(),经由过程前往的布尔值,决意哪一个工具在前,哪一个工具在后。明显,大概产生变更的是这个对照举动,使用“封装笼统”的道理,就应当为该举动创建一个专有的接口ICompare,但是分离界说完成升序、降序大概字典排序的类工具。
我们在每个完成了ISort接口的类机关函数中,引进ICompare接口工具,从而创建起排序算法与对照算法的弱耦合干系(由于这个干系与笼统的ICompare接口相干),比方QuickSort类:
publicclassQuickSort:ISort
{
privateIComparem_Compare;
publicQuickSort(IComparecompare)
{
m_Compare=compare;
}
publicvoidSort(refobject[]beSorted)
{
//完成略
for(inti=0;i<beSorted.Length-1;i++)
{
if(m_Compare.Compare(beSorted,beSorted[i+1))
{
//略;
}
}
//完成略
}
}
最初的类图以下:
经由过程对照较战略的封装,以应对它的变更,明显是Stategy形式的计划。现实上,这里的排序算法也多是变更的,比方完成二叉树排序。因为我们已引进了“面向接口编程”的头脑,我们完整能够容易的增加一个新的类BinaryTreeSort,来完成ISort接口。关于挪用方而言,ISort接口的完成,一样是一个Strategy形式。此时的类布局,完整是一个对扩大开辟的形态,它完整可以顺应类库挪用者新需求的变更。
再以PetShop为例,在这个项目中触及到定单的办理,比方拔出定单。思索到会见量的干系,PetShop为定单办理供应了同步和异步的体例。明显,在实践使用中只能利用这两种体例的个中一种,并由详细的使用情况所决意。那末为了应对如许一种大概会很频仍的变更,我们仍旧必要使用“封装变更”的道理,创建笼统级其余工具,也就是IOrderStrategy接口:
publicinterfaceIOrderStrategy
{
voidInsert(PetShop.Model.OrderInfoorder);
}
然后界说两个类OrderSynchronous和OrderAsynchronous。类布局以下:
在PetShop中,因为用户随时都大概会改动拔出定单的战略,因而关于营业层的定单范畴工具而言,不克不及与详细的定单战略工具发生耦合干系。也就是说,在范畴工具Order类中,不克不及new一个详细的定单战略工具,以下面的代码:
IOrderStrategyorderInsertStrategy=newOrderSynchronous();
在MartinFowler的文章《IoC容器和DependencyInjection形式》中,提出懂得决这类成绩的举措,他称之为依附注进。不外因为PetShop并没有利用诸如Sping.Net等IoC容器,因而办理依附成绩,一般是使用设置文件分离反射来完成的。在范畴工具Order类中,是如许完成的:
publicclassOrder
{
privatestaticreadonlyIOrderStategyorderInsertStrategy=LoadInsertStrategy();
privatestaticIOrderStrategyLoadInsertStrategy()
{
//Lookupwhichstrategytousefromconfigfile
stringpath=ConfigurationManager.AppSettings["OrderStrategyAssembly"];
stringclassName=ConfigurationManager.AppSettings["OrderStrategyClass"];
//Loadtheappropriateassemblyandclass
return(IOrderStrategy)Assembly.Load(path).CreateInstance(className);
}
}
在设置文件web.config中,设置以下的Section:
<addkey="OrderStrategyAssembly"value="PetShop.BLL"/>
<addkey="OrderStrategyClass"value="PetShop.BLL.OrderSynchronous"/>
这实际上是一种折衷的ServiceLocator形式。将定位并创立依附工具的逻辑间接放到工具中,在PetShop的例子中,不掉为一种好办法。究竟在这个例子中,必要依附注进的工具其实不太多。但我们也能够以为是一种无法的让步的举措,一旦这类依附注进的逻辑增加,为给程序者带来必定的贫苦,这时候就必要一个专门的轻量级IoC容器了。
写到这里,仿佛已离开了“封装变更”的主题。但现实上我们必要分明,使用笼统的体例封装变更,当然是应对需求变更的霸道,但它也仅仅能排除挪用者与被挪用者绝对的耦合干系,只需还触及到详细工具的创立,即便引进了工场形式,但详细的工场工具的创立仍旧是必不成少的。那末,关于如许一些业已被封装变更的工具,我们还应当充实使用“依附注进”的体例来完全排除二者之间的耦合。一般的指的.net就是跟java相对的那种,主要是做企业级应用的。你如果想学这个,主要就是学C#和数据库。(ASP.NET好像很重要的,应该也要学的,ASP.NET上好像可以结合VB和C#等多种语言,但是微软主推C#) |
|