设计模式------抽象工厂模式(五)

定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类 。我的理解是:1.有多产品(需要生产创建)2.多工厂(每个工厂都创建所有的产品)3.在工厂接口包含所有的产品创建

优点:1.调用的时候只需要初始化一次,就可以完全工厂的切换。增加新的工厂也符合开放封闭-封闭原则   2.创建实例的过程隐藏,客户端完全面向接口编程,产品的具体名称也被具体的工厂实现分离,不会出现再客户端。完全符合依赖倒转原则。
缺点:不够灵活,如果业务代码新增一个产品的方法,则需要改动的至少改动 工厂,工厂的实现类,外加新增产品和产品的实现类。

改进:下一章,我将利用反射,简单工厂,配置等方式简单化和改进一下抽象工厂模式。

类图:

  

案例:多数据库下的应用。假设现在有2个产品需要创建,同时也需要支持比较容易的支持SQLServer和MySQL数据库,该如何设计?

 

1.把每一个产品,抽象出一个接口或者抽象类,作用:定义规范,面向对象编程。(产品)

  public interface IUser
    {
        void InsertUser();
        void GetUser();
    }
   public interface IDepartment
    {
        void InsertDepartment();
        void GetDepartment();
    }

2..不同工厂下的(多数据库)实现类。(产品)

 department:

public class MySqlDepartment : IDepartment
    {
       public void InsertDepartment()
       {
           Console.WriteLine("插入一条Department数据---mysql");
       }

       public void GetDepartment()
       {
           Console.WriteLine("查询Department信息---mysql");
       }
    }


 public class SqlDepartment : IDepartment
    {
       public void InsertDepartment()
       {
           Console.WriteLine("插入一条Department数据---sqlserver");
       }

       public void GetDepartment()
       {
           Console.WriteLine("查询Department信息---sqlserver");
       }
    }

User:

 public class SqlUser : IUser
    {
      public void InsertUser()
      {
          Console.WriteLine("插入一条User数据---sqlserver");
      }

      public void GetUser()
      {
          Console.WriteLine("查询User信息---sqlserver");
      } 
    }


public class MySqlUser : IUser
    {
      public void InsertUser()
      {
          Console.WriteLine("插入一条User数据---mysql");
      }

      public void GetUser()
      {
          Console.WriteLine("查询User信息---mysql");
      }
    }

3.定义工厂,创造所有产品的方法,面向接口编程,定义规范。(工厂)

  interface I工厂
    {
        IUser CreateUser();
        IDepartment CreateDepartment();
    }

4.工厂实现类,依赖具体的产品,工厂和产品的耦合就这这里。(工厂)

 public class MySql工厂 : I工厂
   {
        public IUser CreateUser()
        {
            return new MySqlUser();
        }

        public IDepartment CreateDepartment()
        {
            return new MySqlDepartment();
        }
    }



 public class Sql工厂:I工厂
    {
        public IUser CreateUser()
        {
            throw new NotImplementedException();
        }

        public IDepartment CreateDepartment()
        {
            throw new NotImplementedException();
        }
    }

 

5.调用,只需要new 不同的工厂。其他不变,都是面向接口,客户端和实际操作的实例分离。也就是说,我只要工厂和接口,不用需要知道具体的类。如果要成其他数据库,那我只需要new 不同数据库就可以了。其他的没有任何改动。

  static void Main(string[] args)
        {
            //如果需要换成sqlserver,只需要更改这里
            I工厂 factory = new MySql工厂();


            //工厂创建用户对象
            IUser iu = factory.CreateUser();
            //执行正常业务操作
            iu.InsertUser();
            iu.GetUser();


            //工厂创建部门对象
            IDepartment idepart = factory.CreateDepartment();
            //执行正常业务操作
            idepart.InsertDepartment();
            idepart.GetDepartment();

            Console.ReadLine();
        }

 

现在的这种模式就是写起来有点费劲,创建很多的类或接口,调试也不那么方便,下一章,会稍微简化下,敬请期待。

posted @ 2017-09-26 17:05  关关雎鸠,在广州  阅读(184)  评论(0编辑  收藏  举报