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

引言

 上一篇介绍了设计模式中的简单工厂模式-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();
        }
    }
}

调用结果

优缺点

优点

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

缺点

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

posted on 2017-08-15 21:39  yxtic  阅读(945)  评论(4编辑  收藏  举报