zoukankan      html  css  js  c++  java
  • 抽象工厂模式(Abstract Factory)

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

    重点概念

    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);
            }
        }
    
    }
    冯瑞涛
  • 相关阅读:
    洛谷 P6851 【onu】贪心
    联赛模拟测试12 C. sum 莫队+组合数
    晚间测试4 哪一天她能重回我身边 神奇建图+基环树
    联赛模拟测试11 D. 甜圈 线段树维护哈希值
    CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树上启发式合并(DSU ON TREE)
    CF788B Weird journey 题解
    联赛模拟测试10 C. 射手座之日
    晚间测试3 B. 单(single)
    CF538B Quasi Binary 思维题
    CF600E Lomsat gelral 树上启发式合并
  • 原文地址:https://www.cnblogs.com/finehappy/p/1615722.html
Copyright © 2011-2022 走看看