|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
就安全性而言,Java已经远远低于VB.NET,更无法与安全性著称的C#相比。技能 泛型不但能用来做容器,还可以供应代码复用的手腕。在泛型的介入下,很多计划便可能更精巧,更具扩大性。明天我就来演示一个使用泛型加强的笼统工场形式。我们晓得,笼统工场(AbstractFactory)形式是将工场和产物全体笼统化,一个笼统工场天生一组笼统产物,而一个详细工场则天生详细产物的一个特定组合。它可以保持这类相干工具组合的分歧性,并使得用户不必要懂得工场和产物的详细完成。传统的AbstractFactory次要缺点是范例依附性强,可复用性弱。一个笼统工场一般是为一个特定必要而计划,一般不克不及被其他必要笼统工场的场所利用。并且只管笼统工场能够将实践临盆义务委派给特定范例的工场,但这类委派是必要经由过程本人纯代码完成的,没能使用言语所供应的笼统特征。我们明天的义务就是编写一个不针对特定产物范例和数量的泛型笼统工场,当你必要特定的笼统工场时,可随时复用无需再界说专门的笼统工场完成。
我们起首从只天生一个产物的工场办法入手下手,以这作为笼统工场的质料。很分明,能够计划如许一个接口作为工场办法的模板:
publicinterfaceIFactory<T>
{
TCreate();
}
这个工场临盆一个T范例的工具。当你完成此工场时,应当让T为笼统产物的范例――即产物通用的基类。好比我们能够完成一个接纳无参数机关函数来创立工具的OpNewFactory完成:
publicclassOpNewFactory<TAbstractProduct,TProduct>:IFactory<TAbstractProduct>
whereTProduct:TAbstractProduct,new()
{
publicTAbstractProductCreate()
{
returnnewTProduct();
}
}
今后例子能够看出,你应当仅完成笼统范例的IFactory接口,并天生详细范例。如今我们做完了单一产物的工场办法模板,就要入手下手界说临盆多个产物的笼统工场接口了。.NET泛型撑持按范例参数个数举行重载,就是说,我们能够界说临盆一个、两个、三个……等多种数量的笼统工场接口,而利用统一个名字。(汗吧,这就是所谓撑持“恣意数量”的伎俩)这里免不了要拷贝代码,不外别忧虑,纯拷贝罢了,利用的时分但是十分舒心的哦。我们以临盆两种产物范例的笼统工场为例先容。能不克不及界说成如许呢?
publicinterfaceIAbstractFactory<T1,T2>
{
T1Create();
T2Create();//编译毛病!!!
}
哦不!办法不克不及以前往范例辨别重载,只能靠参数范例重载。但是这里我们明显不克不及用T1和T2作为参数,由于这些办法就是为了临盆T1和T2筹办的,怎样能承受它们作为参数呢?岂非要定名为Create1和Create2吗?这很难承受,我们但愿临盆办法可以表现产物的范例,怎样能叫1和2呢。为懂得决这个成绩,我们引进了TypeToken<T>范例,它的界说以下:
publicsealedclassTypeToken<T>
{
staticprivateTypeToken<T>instanceValue=newTypeToken<T>();
staticpublicTypeToken<T>Instance
{
get{returninstanceValue;}
}
privateTypeToken(){}
}
这个类没有成员,而且每一个范例实参只能创立一个实例,因而价值极小。但就是这小小的实例上带有其范例实参的范例信息,因而能够作为判别函数重载的根据。我们用TypeToken<T>作为辨别临盆函数重载的根据,完成以下:
publicinterfaceIAbstractFactory<T1,T2>
{
T1Create(TypeToken<T1>token);
T2Create(TypeToken<T2>token);
}
如今我们针对笼统工场完成详细工场。详细工场就是使用临盆每种产物的单一工场来组合完成。因而你只需有每品种型的单一工场就能够间接组合天生笼统工场,而无需界说一个类来做这件事。注重,对每种数量的笼统工场接口都必要对应天生一个详细工场的完成,这里我仅针对天生两个产物的演示:
publicclassConcreteFactory<T1,T2>:IAbstractFactory<T1,T2>
{
privateIFactory<T1>factory1;
privateIFactory<T2>factory2;
publicConcreteFactory(IFactory<T1>f1,IFactory<T2>f2)
{
factory1=f1;
factory2=f2;
}
publicT1Create(TypeToken<T1>token)
{
returnfactory1.Create();
}
publicT2Create(TypeToken<T2>token)
{
returnfactory2.Create();
}
}
publicstaticclassConcretFactory
{
publicstaticConcreteFactory<T1,T2>NewFactory<T1,T2>(IFactory<T1>f1,IFactory<T2>f2)
{
returnnewConcreteFactory<T1,T2>(f1,f2);
}
}
注重,我又声了然一个没有范例参数的ConcretFactory类,用一个静态办法来天生泛型ConcretFactory的实例,这是由于利用泛型办法能够推想范例参数,使得我们能够不用输出尖括号或Of语句,而泛型类则没有这个功效。如今半途而废!我们用一个例子来演示这个泛型笼统工场的事情情形。如今假定我们必要一个临盆PC的笼统工场,必要临盆两种笼统产物:处置器和内存。处置器和内存的笼统和详细完成以下:
Processor和Ram
publicabstractclassProcessor
{
publicabstractstringModel{get;}
}
publicabstractclassRam
{
publicabstractintFrequency{get;}
}
publicclassPentiumProcessor:Processor
{
publicoverridestringModel
{
get{return"PentiumExtremeEdition955";}
}
}
publicclassAthlonProcessor:Processor
{
publicoverridestringModel
{
get{return"Athlon64X2FX-60";}
}
}
publicclassDDRRam:Ram
{
publicoverrideintFrequency
{
get{return400;}
}
}
publicclassDDR2Ram:Ram
{
publicoverrideintFrequency
{
get{return533;}
}
}
上面的代码演示了怎样为所欲为天生想要的笼统工场接口和疾速从现有单一产物工场组分解特定的详细工场完成。
classProgram
{
staticIAbstractFactory<Processor,Ram>ComputerFactory(stringtype)
{
if(type=="Intel")
{
returnConcretFactory.NewFactory(newOpNewFactory<Processor,PentiumProcessor>(),
newOpNewFactory<Ram,DDR2Ram>());
}
elseif(type=="AMD")
{
returnConcretFactory.NewFactory(newOpNewFactory<Processor,AthlonProcessor>(),
newOpNewFactory<Ram,DDRRam>());
}
//unknowntype
returnnull;
}
staticvoidMain(string[]args)
{
//YieldacomputerofIntel
IAbstractFactory<Processor,Ram>factory1=ComputerFactory("Intel");
Ramram1=factory1.Create(TypeToken<Ram>.Instance);
Processorcup1=factory1.Create(TypeToken<Processor>.Instance);
Console.WriteLine("AnIntelComputer");
Console.WriteLine("CPUModel:{0}",cup1.Model);
Console.WriteLine("MemoryFrequency:{0}MHz",ram1.Frequency);
Console.WriteLine();
//YieldacomputerofAMD
IAbstractFactory<Processor,Ram>factory2=ComputerFactory("AMD");
Ramram2=factory2.Create(TypeToken<Ram>.Instance);
Processorcup2=factory2.Create(TypeToken<Processor>.Instance);
Console.WriteLine("AnAMDComputer");
Console.WriteLine("CPUModel:{0}",cup2.Model);
Console.WriteLine("MemoryFrequency:{0}MHz",ram2.Frequency);
}
}
总结:
我们用泛型手艺乐成地加强了底本重用性较低的笼统工场,演示了泛型在进步笼统性和代码重用方面出色的代价。计算机发展到这个时候,很多技术日益成熟,想学好一种技术都是不容易的,当你学会用的时候你对它的很多原理可能很不了解) |
|