C#设计模式中细节总结-持续更新中

来源:互联网 发布:java抓取数据的代码 编辑:程序博客网 时间:2024/05/29 09:06

C#设计模式细节问题总结-持续更新

                                                                              在这里不光是程序中的细节问题,更多的是学习设计模式

   1、工厂模式

         1.1简单工厂模式

                 学习工厂模式,首先学习的肯定是简单工厂模式,它虽然不属于GoF23中设计模式,但是应用较为频繁,同时它也是学习其他创建型模式的基础

      简单工厂中包含这样三个角色:工厂-具体产品-抽象产品(这里的抽象产品是为了实现抽象编程而定义的)

         对简单工厂模式通俗易懂的理解:我(实现)想吃苹果(具体产品),我会去超市(工厂)买,而不是自己去种

        实例:女娲造人,分别是Man、Woman、Robot

下面再看具体代码:

抽象产品-Nvawa

using System;public interface Nvwa{   void Person();}

 

具体产品-Robot(另两个具体产品类就不在此一一贴出.)

using System;public class Robot : Nvwa{   public void Person()   {       Console.WriteLine("Robot人");   }}


 工厂-Factory

using System;public class Factory{   public static Nvwa ProducePerson(string brand)   {      if(brand.ToString()=="man")      {          Console.WriteLine("女娲造人Man人");          return new Man();      }      else if (brand.ToString()=="robot")      {          Console.WriteLine("女娲造人Robot人");          return new Robot();      }      else if (brand.ToString() == "woman")      {          Console.WriteLine("女娲造人Woman人");          return new Woman();      }      else      {          throw new Exception("对不起,不能生产");      }   }}

 

App.config:

<?xml version="1.0" encoding="utf-8" ?><configuration>  <appSettings>    <add key="brand" value="robot"/>  </appSettings></configuration>


Program(测试类):

using System;using System.Collections.Generic;using System.Text;using System.Configuration;namespace P743{    class Program    {        static void Main(string[] args)        {            string brand = ConfigurationManager.AppSettings["brand"];            try            {                Nvwa nvwa;                nvwa = Factory.ProducePerson(brand);                nvwa.Person();                Console.ReadLine();            }            catch (Exception ex)            {                Console.WriteLine(ex.Message);                Console.ReadLine();            }        }    }}


运行结果:

女娲造人Robot人
Robot人

--------------------------------------------------------------------------------------------------------

-->在配置文件App.config中更改Value值则更改造人对象.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

下面开始说编程中出现的细节问题及解决办法,首先,请读者看到工厂类.

    因为是实现接口编程,所以,在工厂类应该是实现所有类的的方法,及三个类的方法,

    现在提出问题:如果将这样一段语句注释,程序会报错吗?

 

//else      //{      //    throw new Exception("对不起,不能生产");      //}


答案是会报错:

             错误 1 “Factory.ProducePerson(string)”: 并非所有的代码路径都返回值

为什么会出现这样一个错误,问题在于我们的if语句

             在if 语句中 , 如果出现return关键字,并且程序中又用到多重判断,及else if语句.那么,在多重判断中,一定是以else结尾,而不是以else if语句结尾.否则,程序将报上叙错误

 

  1.2 工厂方法模式

                             上面说了简单工厂模式中,只提供了一个工厂类,所以简单工厂的最大缺点是当有新产品要加入到系统中时,必须修改工厂类,这违背了"开闭原则".下面说的工厂方法模式,保持简单工厂的优点,而且克服了他的缺点.下面看UML图就一目了然.

            工厂方法类的核心是一个抽象工厂类,具体工厂根据具体产品生产,这样,就很好的符合了"开闭原则",当需要添加新产品时,只需要增加相印的工厂和产品类即可,正如上图,当我需要增加一个大众汽车时,只需要增加一个生产大众汽车的具体工厂和具体产品.实现接口编程即可.

             下面贴出代码:

 

抽象工厂类 Factory

public interface Factory{   Car Yield();}

 
具体工厂类(BMW宝马) BMWFactory

public class BMWFactory : Factory{   public Car Yield()   {       Console.WriteLine("BMW工厂生产BMW汽车");       return new Bwm();   }}


 具体工厂类(Benz奔驰) BenzFactory

public class BenzFactory : Factory{   public Car Yield()   {       Console.WriteLine("Benz工厂生产Benz汽车");       return new Benz();   }}

 

抽象产品类 Car

public interface Car{   void Start();}


具体产品类  BWM

public class Bwm : Car{   public void Start()   {       Console.WriteLine("BWM汽车启动");   }}


具体产品类 Benz

public class Benz : Car{   public void Start()   {       Console.WriteLine("Benz汽车启动");   }}


App.config配置文件

<?xml version="1.0" encoding="utf-8" ?><configuration>  <appSettings>    <add key="factory" value="BMWFactory"/>  </appSettings></configuration>


测试类 Program

namespace P913{    class Program    {        static void Main(string[] args)        {            Car car;            Factory factory;            string carFactory = ConfigurationManager.AppSettings["factory"];            factory = (Factory)Assembly.Load("P913").CreateInstance(carFactory);            car = factory.Yield();            car.Start();            Console.ReadLine();        }    }}


运行结果:

BMW工厂生产BMW汽车
BWM汽车启动

--------------------------------------------------------------------------------------------------------

-->在配置文件App.config中更改Value值则更改具体工厂类.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

下面说一下工厂方法模式中用到的一种技巧:

                                                                                                     反射

        反射(Reflection)是.NET的重要机制之一,通过反射,可以在运行时获得.NET中每一个类型(包括类,结构,委托,接口,枚举等)的成员,包括方法,属性,事件,以及构造函数等,可以获得每一个成员的名称,限定符和参数等.由于获取了构造函数的信息,因此可以通过类名来直接创建对象,即使这个对象的类型在编译时是未知的.

 

看到测试类的这一段代码:

            string carFactory = ConfigurationManager.AppSettings["factory"];            factory = (Factory)Assembly.Load("P913").CreateInstance(carFactory);

                         //导入命名空间

                         using System.Reflection;

                         object obj = Assembly.Load("程序集名称").CerateInstance("命名空间.类");

在第二行就是用了反射,因为抽象类是不能直接 new 的 , 而我们恰恰由要用到它,怎么办 ,这里就用到了反射,可以在不用 new 关键字的前提下 ,针对与抽象编程.

         

 

 

---------------------------------------------------->更新中