※1※VisualC#.NET的设计模式内容提要:“四人帮”(GOF)模式被认为是所有其他模式的基础,二十三种设计模式分为三类:创建型模式(CreationalPattern)、结构型模式(StructuralPattern)和行为型模式(BehavioralPattern)。本文对其中比较常用的模式进行了介绍。关键字:创建型模式、结构型模式、行为型模式引言:设计模式(DesignPatterns)是开发人员在实际应用程序开发中,对不断发现的软件设计问题的重复解决方案。设计模式是关于对象的设计和交互,这对经常出现的软件开发挑战的一些完美和重用的解决方案提供了一个交流平台。正文:实例1Singleton模式本实例演示Sigleton模式的应用。【编程要点】Singleton可以说是昀简单也昀实用的一个设计模式。顾名思义,Singleton就是确保一个类只有惟一的一个实例。Singleton主要用于对象的创建,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候都会需要Singleton模式,昀常见的比如整个应用程序中只有一个连接数据库的Connection实例;又比如要求一个应用程序中只存在某个用户数据结构的惟一实例,这都可以通过应用Singleton模式达到目的。如此,Singleton似乎有些像全局对象。但是实际上,并不能用全局对象代替Singleton模式,这是因为:其一,大量使用全局对象会使得程序质量降低,而且C#根本就不支持全局变量;其二,全局对象的方法并不能阻止人们将一个类实例化多次。除了类的全局实例外,开发人员仍然可以通过类的构造函数创建类的多个局部实例。而Singleton模式则通过从根本上控制类的创建,将“保证只有一个实例”这个任务交给了类本身,开发人员不可能再有其他途径得到类的多个实例。这一点是全局对象方法与Singleton模式的根本区别。Singleton模式的实现基于两个要点:(1)不直接用类的构造函数,而另外提供一个public的静态方法来构造类的实例。通常这个方法取名为Instance。public保证了它的全局可见性,静态方法保证了不会创建出多余的实例。(2)将类的构造函数设为private,即将构造函数“隐藏”起来,任何企图使用构造函数创建实例的方法都将报错。这样就阻止了开发人员绕过上面的Instance方法直接创建类的实例。通过以上两点就可以完全控制类的创建,无论有多少地方需要用到这个类,它们访问的都是类的惟一生成的那个实例。【程序实现】实现方式一:usingSystem;namespaceSingleton{usingSystem;classSingletonDemo1{privatestaticSingletonDemo1theSingleton=null;privateSingletonDemo1(){}publicstaticSingletonDemo1Instance(){if(null==theSingleton){※2※theSingleton=newSingletonDemo1();}returntheSingleton;}staticvoidMain(string[]args){SingletonDemo1s1=SingletonDemo1.Instance();SingletonDemo1s2=SingletonDemo1.Instance();if(s1.Equals(s2)){Console.WriteLine(see,onlyoneinstance!);}}}}实现方式二:usingSystem;namespaceSingleton{usingSystem;classSingletonDemo{privatestaticSingletonDemotheSingleton=newSingletonDemo();privateSingletonDemo(){}publicstaticSingletonDemoInstance(){returntheSingleton;}staticvoidMain(string[]args){SingletonDemos1=SingletonDemo.Instance();SingletonDemos2=SingletonDemo.Instance();if(s1.Equals(s2)){Console.WriteLine(see,onlyoneinstance!);}}}}【运行结果】控制台输出:see,onlyoneinstance!【分析与总结】因为Singleton模式具有很广的实用价值,在许多大型系统的实现上也都处处可见它的影子。在.NET框架中,同样也可以发现Singleton思想闪烁的光芒。举例来说,在.NET框架的重要组成部分Remoting中,远程对象(RemoteObject)有两种激活方式:服务器端激活方式和客户端激活方式。采用服务器端激活方式的对象又分为两种类型:Singleton对象和SingleCall对象。Singleton对象是这样的对象:无论该对象有多少个客户端调用,它总是只有一个实例,由这个实例来处理所有的客户端请求。相反地,若将远程对象声明为SingleCall,则系统会为每次客户端方法的调用创建一个新对象,即使这些方法调用来自同一个客户端,对象也只在方法调用持续期间存在,一旦方法调用结束,该对象就会被销毁。显而易见,这里※3※的Singleton对象就是设计模式Singleton思想在.NET中的应用。那么,如何在.NET的Remoting中利用Singleton?.NET提供了两种方式将一个远程对象注册为Singleton:直接调用RegisterWellKnownServiceType方法,在参数中指定对象类型为Singleton;或在配置文件web.config中设定远程对象的类型为Singleton。这两种方法的效果相同,所不同的是后一种方法显得更加简便,因为改变配置文件的内容后,不必重新编译应用程序。下列代码显示了如何使用RegisterWellKnownServiceType方法注册远程对象类型:RemotingConfiguration.RegisterWellKnownServiceType(Type.GetType(RemotingSamples.HelloServer,object),SayHello,WellKnownObjectMode.Singleton);参数“SayHello”是客户端访问远程对象(这里是HelloServer)时用来代表远程对象的URI,例如tcp://localhost:8085/SayHello(假设使用的是TCP通道)。昀后一个参数就指明了这个远程对象是Singleton类型。一旦将远程对象注册为Singleton,则在第一次客户端调用HelloServer的方法时创建这个远程对象,然后保持它直到客户端中断连接或对象超时被销毁为止。在此期间,无论有多少个客户端调用这个远程对象,所有的客户请求都将由那个已经存在的惟一实例接受处理。实例2简单工厂(SimpleFactory)模式本实例演示如何使用简单工厂模式编程。【编程要点】简单工厂模式根据提供给它的数据,返回几个可能类中的一个类的实例。通常它返回的类都有一个共同的父类和共同的方法,但每个方法执行的任务不同,而且根据不同的数据进行了优化。如图1所示,该类图中,X是一个基类,XY类和XZ类从它派生出来,Xfactory类根据给出的参数决定返回哪一个子类。在右边定义了一个getClass方法,传递给它某个值,然后返回X类的某个实例。返回哪一个类的实例与程序员无关,因为这些类有同样的方法,只是实现不同。返回哪一个类的实例完全取决于工厂,工厂功能可能很复杂,但通常都是相当简单的。图1【程序实现】usingSystem;namespaceSimpleFactoryPattern{///summary///SimpleFactoryPattern的摘要说明。////summarypublicclassSimpleFactoryPattern{//定义Food接口publicinterfaceFood{//烹饪voidCook();※4※//卖出voidSell();}publicclassNoodle:Food{privateintprice;publicNoodle(){Console.WriteLine(\nTheNoodleismade..);}//面条Noodle的Cook方法接口实现publicvoidCook(){Console.WriteLine(\nNoodleiscooking...);}//面条Noodle的Sell方法接口实现publicvoidSell(){Console.WriteLine(\nNoodlehasbeensold...);}publicintPrice{get{returnthis.price;}set{price=value;}}}publicclassRice:Food{privateintprice;publicRice(){Console.WriteLine(\nTheRiceismade..);}publicvoidCook(){Console.WriteLine(\nRiceiscooking...);}publicvoidSell(){Console.WriteLine(\nRicehasbeensold...);}publicintPrice{get{returnthis.price;}set{price=value;}}}publicclassBread:Food{privateintprice;publicBread(){Console.WriteLine(\nTheBreadismade....);}※5※publicvoidCook(){Console.WriteLine(\nBreadiscooking...);}publicvoidSell(){Console.WriteLine(\nBreadhasbeensold...);}publicintPrice{get{returnthis.price;}set{price=value;}}}//定义大厨,他包办这个快餐店里的所有Food,包括面条,面包和米饭classChef{publicstaticFoodMakeFood(stringfoodName){try{switch(foodName){casenoodle:returnnewNoodle();caserice:returnnewRice();casebread:returnnewBread();default:thrownewBadFoodException(Badfoodrequest!);}}catch(BadFoodExceptione){throwe;}}}//异常类,该餐馆没有的食品classBadFoodException:System.Exception{publicBadFoodException(stringstrMsg){Console.WriteLine(strMsg);}}///summary///应用程序的主入口点。////summary[STAThread]staticvoidMain(string[]args){//根据传入的参数创建Food类的实例Foodfood=Chef.MakeFood(rice);food.Cook();food.Sell();Console.ReadLine();※6※}}}【运行结果】TheRiceismade..Riceiscooking...Ricehasbeensold...【分析与总结】该实例演示的是一个快餐店,快餐店里提供很多食物,比如面条、米饭、面包。首先定义了一个Food