• 工厂模式(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
    }
    
     
     
  • 相关阅读:
    Spring Boot整合Freemarker
    Spring Boot异常处理
    CSAPP缓冲区溢出攻击实验(下)
    SparkSQL基础应用(1.3.1)
    程序员的自我修养:(1)目标文件
    CSAPP缓冲区溢出攻击实验(上)
    Redis源码学习:字符串
    六星经典CSAPP-笔记(7)加载与链接(上)
    Redis源码学习:Lua脚本
    六星经典CSAPP-笔记(10)系统IO
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1675309.html
Copyright © 2020-2023  润新知