工厂模式

                                        工厂模式

我们在编程的时候,每当"new"一个对象之后,这个对象就依赖于这个类了。如果在后期的维护过程中由于某些原因需要修改一下这个类,则唯一的做法就是打开源代码,进行修改,修改所有与这个对象有关的操作。这对我们是非常不利的。
问题出来了:对象不能应对“具体实例化类型”的变化
解决思路:封装变化点,哪里变化,封装哪里。在这个例子中,要实例化的类变了,就将实例化这个操作封装起来,我们可以把"new"这个操作移交一个具体的类,由它去负责根据我们的条件创建具体类的实例,也就是下面要说的“简单工厂模式”。

现实生活中例子:
每次参加不同的聚会或者与不同的人见面,可能穿的衣服是不一样的,比如,你今天上午要与你的一个新客户见面,你可能会对你的老婆说:老婆,给拿件商务装(参数),我要去见我的一个客户,你老婆(工厂类)接到你的请求(商务装参数)后,从衣柜中取出一件商务装(具体产品),交给你。整个过程就完成了。

分析:
你可能根据不同的条件,要的衣服是不一样的,但要的衣服都是已经在你的衣柜中存在的。并且,每件上衣它们都属于同一种抽象,即它们可以从一个抽象类或接口中继承,这此衣服各自都有一定特征,这些都是条件。然后你要的时候,就可以向你老婆说一种特征,她就会根据这个特征为你服务了。这就是典型的简单工厂模式的应用。
 抽象产品类代码

    /// <summary>
    /// 抽象产品类:上衣
    /// </summary>
    public interface ICoat
    {
        void GetYourCoat();
    }


具体产品类代码

namespace SimpleFactory
 {
     //// <summary>
     /// 具体产品类:商务上衣
     /// </summary>
     public class BusinessCoat:ICoat
     {
         public void GetYourCoat()
         {
            Console.WriteLine("商务上衣");
        }
    }

    //// <summary>
    /// 具体产品类:时尚上衣
    /// </summary>
    public class FashionCoat : ICoat
    {
        /**//// <summary>
        /// 实现ICoat中定义的方法
        /// </summary>
        /// <returns></returns>
        public void GetYourCoat()
        {
            Console.WriteLine("时尚上衣");
        }
    }
} 


简单工厂模式中最核心的部分:工厂类

namespace SimpleFactory
 {
     //// <summary>
     /// 简单工厂模式中的核心部分:工厂类
     /// </summary>
     public class Factory
     {
         public ICoat CreateCoat(string styleName)
         {
            switch (styleName.Trim().ToLower())
            {
                case "business":
                    return new BusinessCoat();
                case "fashion":
                    return new FashionCoat();
                default :
                    throw new Exception("还没有你要的那种衣服");
            }
        }
    }
}


再看一下客户在调用的时候的代码

//// <summary>
    /// 客户类
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
            ICoat food;
            try
            {
                Factory factory = new Factory();

                Console.Write("我要的是时尚上衣\t");
                food = factory.CreateCoat("fashion");
                food.GetYourCoat();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }


在客户端的代码中有我们就可以根据具体的参数,返回我们希望返回的对象,将"new"操作推迟到工厂类中实现。
这里,参数我直接写上了,我们其实可以将这个参数写到一个xml文件中,如app.config文件中,动态的读出来,需要穿另外一种衣服了,只需要打开app.config文件,修改里面的值就行了,不需要项目重新编译。这样这个小程序就能够适应一定的变化了,其实它也是设计模式正要解决的问题,在不修改代码的情况下,使项目能够适应一定的客户需求变化。
     但这样又有一个新的问题,当添加一个新的衣服种类的时候,我们不但要添加一个新的衣服类,而且还要修改工厂类,为了解决这个问题,可以采用反射,需要修改一下工厂类

namespace SimpleFactory
 {
     //// <summary>
     /// 简单工厂模式中的核心部分:工厂类
     /// </summary>
     public class Factory
     {
         public ICoat CreateCoat(string className)
         {
	    string assemblyName = "程序集名";
	    ICoat instance;
            if(factoryName != "")
	     {
		instance = (ICoat)Assembly.Load(assemblyName).CreateInstance(className);
	     }
	    else
	   {
	       instance = null;
           }

        }
    }
}


这样,需要添加一个新的种类得时候,就不需要修现有代码了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值