工厂模式(Factory)

这是重读《设计模式》一书的读书笔记第二篇,主要探讨工厂模式(Factory)

有几个重点

  1. 为什么需要工厂模式呢?工厂模式要解决的问题是创建对象实例的多变性,一个典型的例子就是假设我们的应用程序要既能够使用SQL Server作为数据库,也需要支持使用Oracle作为数据库(当然还可能会有其他的数据库),那么如何在不修改应用程序的情况下,能让它自动适用多种数据源呢?答案就是工厂模式。
  2. 工厂模式其实无处不在,而且即便我们自己以前没有写过,但至少都用到过了。在.NET框架中,很多地方都有工厂模式的影子。
  3. 工厂模式的核心是面向接口的编程。
  4. 工厂模式的另外一个核心是动态加载类型,也就是通过反射动态加载某个类型的实例。
  5. 工厂模式有两个具体的子模式
    1. 工厂方法模式(Factory Method) ——应用得更加多一些
    2. 抽象工厂模式(可以理解为更加复杂一些的场景)——Abastract Factory

下面有一个简单的实例(工厂方法模式:Factory Method)

 

using System;
using System.Collections.Generic;
using System.Reflection;

namespace DesignPatternSample_Factory
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("使用SQL Server的数据访问组件");
            IDAL dal = Factory.GetDALInstance("DesignPatternSample_Factory.SQLServerDAL");

            foreach (var item in dal.GetEmployee())
            {
                Console.WriteLine(item);
            }


            Console.WriteLine();

            Console.WriteLine("使用Oracle的数据访问组件");
            dal = Factory.GetDALInstance("DesignPatternSample_Factory.OracleDAL");
            foreach (var item in dal.GetEmployee())
            {
                Console.WriteLine(item);
            }

            Console.Read();
        }
    }


    //第一步:定义接口

    /// <summary>
    /// 定义一个数据访问层的接口,要求所有数据访问层都实现该接口
    /// </summary>
    interface IDAL {
        List<string> GetEmployee();
    }

    //第二步:定义工厂

    class Factory
    {
        public static IDAL GetDALInstance(string typeName) {
            return Assembly.GetExecutingAssembly().CreateInstance(typeName) as IDAL;
        }
    }


    //第三步:具体实现DAL
    class SQLServerDAL : IDAL
    {

        #region IDAL 成员

        public List<string> GetEmployee()
        {
            return new List<string>(new[] { "John", "Mike" });
        }

        #endregion
    }

    class OracleDAL : IDAL
    {

        #region IDAL 成员

        public List<string> GetEmployee()
        {
            return new List<string>(new[] { "Roy", "Rebecca" });
       
        }

        #endregion
    }
}

下面再来看一个抽象工厂的模式实现的代码例子,从代码中可以看出,如果工厂需要做一系列的动态化工作,那么可以考虑抽象工厂模式。

using System;

using System.Configuration;
using System.Reflection;

namespace DesignPattern_Factory_AbstractFactorySample
{
    class Program
    {
        static void Main(string[] args)
        {
            var factoryType = ConfigurationManager.AppSettings["FactoryType"];
            var factory = Assembly.GetExecutingAssembly().CreateInstance(factoryType) as Factory;

            var profile = factory.GetProfileDALInstance();
            var business = factory.GetBusinessDALInstance();

            profile.Load("Test");
            profile.Save();

            business.CreateOrder(1, DateTime.Now, 1);


        }
    }

    #region 接口定义和抽象工厂定义

    interface IProfileDAL {
        void Save();
        object Load(string key);
    }

    interface IBusinessDAL
    {
        int CreateOrder(int orderID, DateTime time, int employeeId);
    }

    abstract class Factory
    {
        public abstract IProfileDAL GetProfileDALInstance();
        public abstract IBusinessDAL GetBusinessDALInstance();
    }

    #endregion

    #region 一套简单的工厂及其实现
    class SimpleFactory : Factory
    {

        public override IProfileDAL GetProfileDALInstance()
        {
            return new SimpleProfileDAL();
        }

        public override IBusinessDAL GetBusinessDALInstance()
        {
            return new SimpleBusinessDAL();
        }
    }

    class SimpleProfileDAL : IProfileDAL
    {

        #region IProfileDAL 成员

        public void Save()
        {
            
        }

        public object Load(string key)
        {
            return this.GetType();
        }

        #endregion
    }

    class SimpleBusinessDAL : IBusinessDAL {

        #region IBusinessDAL 成员

        public int CreateOrder(int orderID, DateTime time, int employeeId)
        {
            return 0;
        }

        #endregion
    }

    #endregion

    #region 一套复杂的工厂及其实现
    class ComplexFactory : Factory {
        public override IProfileDAL GetProfileDALInstance()
        {
            return new ComplexProfileDAL();
        }

        public override IBusinessDAL GetBusinessDALInstance()
        {
            return new ComplexBusinessDAL();
        }
    }


    class ComplexProfileDAL : IProfileDAL
    {

        #region IProfileDAL 成员

        public void Save()
        {
            throw new NotImplementedException();
        }

        public object Load(string key)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    class ComplexBusinessDAL : IBusinessDAL
    {

        #region IBusinessDAL 成员

        public int CreateOrder(int orderID, DateTime time, int employeeId)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
    #endregion
}
 
 
posted @ 2010-02-28 23:40  陈希章  阅读(717)  评论(0编辑  收藏  举报