zoukankan      html  css  js  c++  java
  • C#设计模式(3)-工厂方法模式

    点击这里查看全部设计模式系列文章导航

    引言

     上一篇介绍了设计模式中的简单工厂模式-C#设计模式(2)-简单工厂模式,本篇将介绍工厂方法模式,在简单工厂模式下进行改造;

    工厂方法模式简介

     工厂方法(FactoryMethod)模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类中;

          上一篇简单工厂模式中讲到了其缺点,工厂类集中了所有产品创建逻辑的,如果不能正常工作的话会对系统造成很大的影响。如果我们增加一个产品,我们就需要在工厂类中增加case分支条件,修改原有的类,这样我们不但对扩展开放了,也对修改开放了,违背了“开放-封闭”原则,所以我们对简单工厂模式进行优化,对工厂抽出一个接口,就有了以下的工厂方法模式

     

    结构图

    (来自大话设计模式)

     

    应用实例

        这里实例依然采用上一篇中的实例:现在市面上很多种数据库,Oracle、SqlSever、Mysql等;比如我们现在需要写一个通用的数据处理,如新增、更新等操作,能够达到切换任意一个数据库,都能够调用对应版本数据库的的新增或者更新操作;

      下面的类图、代码将均以数据库操作为实例;

    类图

    代码实例

    注:这里实例仅做示例,不包含业务逻辑;

    创建数据操作抽象类

    以新增、更新为例;

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FactoryMethod
    {
        /// <summary>
        /// 数据库操作抽象类
        /// </summary>
        public abstract class AbstractDataBaseOpr
        {
            /// <summary>
            /// 新增
            /// </summary>
          public  abstract bool Insert();
    
            /// <summary>
            /// 更新
            /// </summary>
            /// <returns></returns>
          public abstract bool Update();
        }
    }

    Oracle数据操作类

    继承上述数据库操作抽象类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FactoryMethod
    {
        /// <summary>
        /// oracle操作
        /// </summary>
        public class OracleDbOpr : AbstractDataBaseOpr
        {
            /// <summary>
            /// 新增
            /// </summary>
            public override bool Insert()
            {
                Console.WriteLine("Oracle新增记录");
                return true;
            }
    
            /// <summary>
            /// 更新
            /// </summary>
            /// <returns></returns>
            public override bool Update()
            {
                Console.WriteLine("Oracle更新记录");
                return true;
            }
    
        }
    }
    View Code

    SqlServer数据操作类

    继承上述数据库操作抽象类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FactoryMethod
    {
        /// <summary>
        /// sqlServer操作
        /// </summary>
        public class SqlServerDbOpr : AbstractDataBaseOpr
        {
            /// <summary>
            /// 新增
            /// </summary>
            public override bool Insert()
            {
                Console.WriteLine("SqlServer新增记录");
                return true;
            }
    
            /// <summary>
            /// 更新
            /// </summary>
            /// <returns></returns>
            public override bool Update()
            {
                Console.WriteLine("SqlServer更新记录");
                return true;
            }
    
        }
    }
    View Code

    创建DB工厂接口

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FactoryMethod
    {
        /// <summary>
        /// DB工厂接口
        /// </summary>
        public interface IDbFactory
        {
            /// <summary>
            /// 创建db操作实例
            /// </summary>
            /// <returns></returns>
            AbstractDataBaseOpr CreateDbOpr();
        }
    }

    Oracle工厂类

    实现接口

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FactoryMethod
    {
        /// <summary>
        /// oracle db工厂
        /// </summary>
        public class OracleDbFactory : IDbFactory
        {
            /// <summary>
            /// 创建数据库操作实例
            /// </summary>
            /// <returns></returns>
            public AbstractDataBaseOpr CreateDbOpr()
            {
                return new OracleDbOpr();
            }
        }
    }

    SqlServer工厂类

    实现接口

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FactoryMethod
    {
        /// <summary>
        /// SqlServer db工厂
        /// </summary>
        public class SqlServerDbFactory : IDbFactory
        {
            /// <summary>
            /// 创建数据库操作实例
            /// </summary>
            /// <returns></returns>
            public AbstractDataBaseOpr CreateDbOpr()
            {
                return new SqlServerDbOpr();
            }
        }
    }

    业务调用

    oracle数据库和sqlserver数据库操作分别调用

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FactoryMethod
    {
        class Program
        {
            static void Main(string[] args)
            {
                //oracle操作
                IDbFactory dbFactory1 = new OracleDbFactory();
                AbstractDataBaseOpr opr1 = dbFactory1.CreateDbOpr();
                opr1.Insert();
                opr1.Update();
    
                Console.WriteLine("-----------------------------------------");
    
                //切换为sqlserer
                IDbFactory dbFactory2 = new SqlServerDbFactory();
                AbstractDataBaseOpr opr2 = dbFactory2.CreateDbOpr();
                opr2.Insert();
                opr2.Update();
    
                Console.ReadKey();
            }
        }
    }

    调用结果

    优缺点

    优点

    • 用户只需要关心所需产品对应的工厂,不需要关注如何创建。
    • 在增加新产品时,需要增加新的产品类及对应的工厂类,不会影响其它产品,符合开闭原则

    缺点

    当需要增加新产品的时候,需要增加新的产品类,还需要增加对应的工厂类

  • 相关阅读:
    [蓝桥] 基础练习 数列排序(java)
    关不掉之以假乱真
    关不掉.vbs
    1.3内置数据类型
    1.2成员变量+类变量+static关键字
    1.1变量+命名规则
    Java 大数任意进制转换
    打印十字图
    c语言求最大公约数和最小公倍数
    核桃的数量
  • 原文地址:https://www.cnblogs.com/yx007/p/FactoryMethodPattern.html
Copyright © 2011-2022 走看看