开闭原则和依赖倒置原则是面向对象设计的重点,编程是一门艺术,大批量的改动,是不好看的做法。

重点概念

1. 工厂方法模式(不是抽象工厂)是定义一个用于创建对象的接口,让子类中实现这个接口的方法中的内容决定实例化那一个类(New 什么类)。

2. 抽象工厂模式提供几个创建类的接口,具体抽象子类利用父类定义的方法创建相关的“产品抽象类型”的一组子类具体实现。

image

3. 从上图中可以看出,抽象工厂接口的所有子类实现中中也定义有一个工厂方法,上图有些乱,元素命名不是很容易懂,但图的结构完全正确可以结合代码去理解。

4. 上图中IFactory 是一个抽象工厂接口,他里面应该包含所有的产品(所有指AbstractProductA下面的所有子类的个数,而不是AbstractProduct抽象类的个数)创建的抽象方法。产品抽象和抽象工厂所关注的是一个横向一个纵向

5. 也就是通常是在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应该使用不同的具体工厂。

6. 反射格式 Assembly.Load(“程序集名称”).CreateInstance(“命名空间.类名称”)

image

7. 利用反射可以使用字符串形式来实例化对象,而一般的情况实例化是写死在程序中的,将程序由编译时转为运行时。

8. 所有在用简单工厂的地方,都可以考虑用反射技术来去除Switch或If ,杰出分支判断带来的耦合。

9. 无痴迷,不成功

 

示例代码

上图中的源代码

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工厂模式
{
    class Program
    {
        static void Main(string[] args)
        {
            //建立具体的抽象工厂
            AbstractFactory factory1 = new ConcreteFactory1();
            Client c1 = new Client(factory1);
            c1.Run();

            AbstractFactory factory2 = new ConcreteFactory2();
            Client c2 = new Client(factory2);
            c2.Run();

            Console.Read();

        }
    }

    /// <summary>
    /// 抽象工厂
    /// </summary>
    abstract class AbstractFactory
    {
        //在抽象工厂中要实现那些表的特定访问方式的实例,有几个表
        public abstract AbstractProductA CreateProductA();
        public abstract AbstractProductB CreateProductB();
    }

    /// <summary>
    /// 具体抽象工厂,抽象了访问SQLServer 方式
    /// </summary>
    class ConcreteFactory1 : AbstractFactory
    {
        
        public override AbstractProductA CreateProductA()
        {
            return new ProductA1(); 
        }
        public override AbstractProductB CreateProductB()
        {
            return new ProductB1();
        }
    }

    /// <summary>
    /// Access
    /// </summary>
    class ConcreteFactory2 : AbstractFactory
    {
        public override AbstractProductA CreateProductA()
        {
            return new ProductA2();
        }
        public override AbstractProductB CreateProductB()
        {
            return new ProductB2();
        }
    }

    /// <summary>
    /// 产品抽象A,User表
    /// </summary>
    abstract class AbstractProductA
    {
    }

    /// <summary>
    /// 产品抽象B 部门表
    /// </summary>
    abstract class AbstractProductB
    {
        public abstract void Interact(AbstractProductA a);
    }

    #region ConcreteFactory1抽象工厂职能 ,比如SQL Server
    //实现 产品抽象A
    class ProductA1 : AbstractProductA
    {
    }

    //实现产品抽象B
    class ProductB1 : AbstractProductB
    {
        public override void Interact(AbstractProductA a)
        {
            Console.WriteLine(this.GetType().Name +
              " interacts with " + a.GetType().Name);
        }
    }
    #endregion


    #region ConcreteFactory2抽象工厂职能 ,比如Access
    class ProductA2 : AbstractProductA
    {
    }

    class ProductB2 : AbstractProductB
    {
        public override void Interact(AbstractProductA a)
        {
            Console.WriteLine(this.GetType().Name +
              " interacts with " + a.GetType().Name);
        }
    }
    #endregion

    /// <summary>
    /// 客户端程序
    /// </summary>
    class Client
    {
        private AbstractProductA AbstractProductA;
        private AbstractProductB AbstractProductB;

        // 选择哪个具体抽象工厂,也就是选择哪种数据库 
        public Client(AbstractFactory factory)
        {
            AbstractProductB = factory.CreateProductB();
            AbstractProductA = factory.CreateProductA();
        }

        //展示结果
        public void Run()
        {
            AbstractProductB.Interact(AbstractProductA);
        }
    }


}

 

示例2 反射+ 简单工厂

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Configuration;

namespace 抽象工厂模式
{
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            Department dept = new Department();

            IUser iu = DataAccess.CreateUser();

            iu.Insert(user);
            iu.GetUser(1);

            IDepartment id = DataAccess.CreateDepartment();
            id.Insert(dept);
            id.GetDepartment(1);

            Console.Read();
        }
    }

    #region 实体层
    class User
    {
        private int _id;
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }

    class Department
    {
        private int _id;
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _deptName;
        public string DeptName
        {
            get { return _deptName; }
            set { _deptName = value; }
        }
    }
    #endregion 

    #region 用户表
    interface IUser
    {
        void Insert(User user);

        User GetUser(int id);
    }

    class SqlserverUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在Sqlserver中给User表增加一条记录");
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
            return null;
        }
    }

    class AccessUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在Access中给User表增加一条记录");
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在Access中根据ID得到User表一条记录");
            return null;
        }
    }
    #endregion 

    #region 部门表
    interface IDepartment
    {
        void Insert(Department department);

        Department GetDepartment(int id);
    }

    class SqlserverDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在Sqlserver中给Department表增加一条记录");
        }

        public Department GetDepartment(int id)
        {
            Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
            return null;
        }
    }

    class AccessDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在Access中给Department表增加一条记录");
        }

        public Department GetDepartment(int id)
        {
            Console.WriteLine("在Access中根据ID得到Department表一条记录");
            return null;
        }
    }
    #endregion

    /// <summary>
    /// 简单工厂反射
    /// </summary>
    class DataAccess
    {
        private static readonly string AssemblyName = "抽象工厂模式";
        private static readonly string db = ConfigurationManager.AppSettings["DB"];
        
        //利用反射代替Switch 语句的判断,进行运行时实例化
        public static IUser CreateUser()
        {
            string className = AssemblyName + "." + db + "User";
            return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
        }

        public static IDepartment CreateDepartment()
        {
            string className = AssemblyName + "." + db + "Department";
            return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
        }
    }

}
posted on 2009-12-02 22:20  冯瑞涛  阅读(478)  评论(0编辑  收藏  举报