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(); } } }

调用结果

优缺点

优点

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

缺点

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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM