C#设计模式 —— 工厂模式

Wesley13
• 阅读 748

。  工厂模式同样是项目中最常用的设计模式,工厂模式中又分为简单工厂,工厂方法,抽象工厂。下面我们由简单的开始逐一介绍。

1.简单工厂模式

  简单工厂又被称为静态工厂,在设计模式中属于创建型模式。主要解决的问题是封装了实例化的过程,通过传入参数来获不同实例。下面我们举一个项目中可能会用到的例子。

  假设我们程序的数据保存在几个不同的数据库中,有MySql,SQLServer和MongoDB。数据库都有增删改查的操作,我们就声明一个接口定义这些操作。

1     public interface IDatabase
2     {
3         void Insert();
4         void Delete();
5     }

  然后我们让三个数据库类分别实现这个接口。

 1     public class SqlServer : IDatabase
 2     {
 3         public void Delete()
 4         {
 5             Console.WriteLine("delete data from sqlserver");
 6         }
 7 
 8         public void Insert()
 9         {
10             Console.WriteLine("insert data to sqlserver");
11         }
12     }
13 
14     public class MySql : IDatabase
15     {
16         public void Delete()
17         {
18             Console.WriteLine("delete data from mysql");
19         }
20 
21         public void Insert()
22         {
23             Console.WriteLine("insert data to mysql");
24         }
25     }
26 
27     public class MongoDB : IDatabase
28     {
29         public void Delete()
30         {
31             Console.WriteLine("delete data from mongoDb");
32         }
33 
34         public void Insert()
35         {
36             Console.WriteLine("insert data to mongoDb");
37         }
38     }

  之后我们再声明一个工厂类,这个类中的静态方法可以根据传入不同的参数来创建不同的实例。

 1     public static class DatabaseFactory
 2     {
 3         public static IDatabase CreateDatabase(string dbType)
 4         {
 5             IDatabase db = null;
 6 
 7             switch (dbType)
 8             {
 9                 case "MySql":
10                     db = new MySql();
11                     break;
12                 case "SqlServer":
13                     db = new SqlServer();
14                     break;
15                 case "MongoDB":
16                     db = new MongoDB();
17                     break;
18                 default:
19                     break;
20             }
21 
22             return db;
23         }
24     }

  最后我们再Main函数里声明三个接口,然后给工厂类传入不同的参数来创建三个不同的实例,再分别调用接口中声明的方法。

 1         static void Main(string[] args)
 2         {
 3             IDatabase db1 = DatabaseFactory.CreateDatabase("MySql");
 4             db1.Insert();
 5             db1.Delete();
 6 
 7             IDatabase db2 = DatabaseFactory.CreateDatabase("SqlServer");
 8             db2.Insert();
 9             db2.Delete();
10 
11             IDatabase db3 = DatabaseFactory.CreateDatabase("MongoDB");
12             db3.Insert();
13             db3.Delete();
14         }

  来看一些控制台的输出:

C#设计模式 ——  工厂模式

  这就是简单工厂模式。

  我们可以看到简单工厂模式的优点:

  1.拓展性好,如果这时候我们又添加了一个Oracle数据库,只需要再添加一个新的类并实现IDatabase这个这个接口就行了。

  2.我们只需要关注接口中的方法,不需要关注具体类的实现。

  缺点:只适用于工厂需要创建比较少的具体类这样的情况。如果具体类多,代码的复杂程度会增加。

2.工厂模式

  工厂模式在简单工厂模式的基础上进行了更加全面的面向对象封装,可以让我们不要单独的工厂方法就能创建出具体的实例。做法就是为每一个具体的类创建单独的工厂。接下来我们对刚刚几个类稍加改造。

  首先发DatabaseFactory修改成一个接口,接口中定义一个用来创建实例的方法。

1     interface IDatabaseFactory
2     {
3         IDatabase CreateDatabase();
4     }

  然后我们然后我们为每个具体类单独创建一个工厂类,工厂类实现刚刚定义的接口。

 1     public class MongoDbFactory : IDatabaseFactory
 2     {
 3         public IDatabase CreateDatabase()
 4         {
 5             return new MongoDB();
 6         }
 7     }
 8 
 9     public class MySqlFactory : IDatabaseFactory
10     {
11         public IDatabase CreateDatabase()
12         {
13             return new MySql();
14         }
15     }
16 
17     public class SqlServerFactory : IDatabaseFactory
18     {
19         public IDatabase CreateDatabase()
20         {
21             return new SqlServer();
22         }
23     }

  最后我们在main函数中创建工厂的实例。

static void Main(string[] args)
        {
            IDatabaseFactory dbFactory1 = new MySqlFactory();
            IDatabase db1 = dbFactory1.CreateDatabase();
            db1.Insert();
            db1.Delete();

            IDatabaseFactory dbFactory2 = new SqlServerFactory();
            IDatabase db2 = dbFactory1.CreateDatabase();
            db2.Insert();
            db2.Delete();

            IDatabaseFactory dbFactory3 = new MongoDbFactory();
            IDatabase db3 = dbFactory3.CreateDatabase();
            db3.Insert();
            db3.Delete();
        }

  结果输出是和刚刚一模一样的。工厂模式的好处便是它符合开闭原则(对扩展开放,对修改封闭)。在刚刚的简单工厂模式中,如果我们扩展一个新的类,除了添加一个新的类之外,我们还需要去修改CrateDatabase(string dbType)这个方法,这是违反开闭原则的。在工厂模式中我们就不需要修改CreateDatabase这个方法,只需要实现工厂类这个接口便能完场扩展。缺点便是我们需要写更多的代码。

3.抽象工厂模式

  有了前面工厂模式的铺垫,抽象工厂应该不难理解吧。我看到过很多的博客都写着很多概念,什么产品层级,产品族,抽象产品等等,感觉不是特别容易理解。我的理解是这样的:把多个不同的工厂再抽象出来,再用一个抽象工厂(超级工厂)来创建这些工厂。也就是说抽象工厂是工厂的工厂。为了说明这个模式我想出了一个例子(其实我在工作中没有遇到过使用抽象工厂的例子):

  操作系统有Windows操作系统,Linux操作系统。每个操作系统都可以启动关闭。于是我们就创建一个操作系统工厂,用来创建(安装)这些操作系统,方法和上面的创建数据库工厂是一样的。

// 操作系统具有的操作
    public interface IOpSystem
    {
        void Start();
        void Shutdown();
    }

    // 操作系统工厂
    public interface IOpSystemFactory
    {
        IOpSystem InstallSystem();
    }

    // windows操作系统
    public class WindowsSystem : IOpSystem
    {
        public void Shutdown()
        {
            Console.WriteLine("windows shutdown");
        }

        public void Start()
        {
            Console.WriteLine("windows start");
        }
    }

    // linux操作系统
    public class LinuxSystem : IOpSystem
    {
        public void Shutdown()
        {
            Console.WriteLine("linux shutdown");
        }

        public void Start()
        {
            Console.WriteLine("linux start");
        }
    }

    // windows操作系统工厂,用来创建windows系统实例
    public class WindowsFactory : IOpSystemFactory
    {
        public IOpSystem InstallSystem()
        {
            return new WindowsSystem();
        }
    }

    // linux操作系统工厂,用来创建linux系统实例
    public class LinuxFactory : IOpSystemFactory
    {
        public IOpSystem InstallSystem()
        {
            return new LinuxSystem();
        }
    }

  我们可以看到操作系统工厂和数据库工厂是完全两个不同的工厂。假设一台服务器上需要安装操作系统和数据库,我们便可以用一个超级工厂来把这两个不同的工厂抽象出来。

public interface ISuperFactory
    {
        IDatabaseFactory InstallDB();
        IOpSystemFactory InstallOpSystem();
    }

  然后我们定义一个具体的服务器类来实现这个超级工厂,在接口的实现中我们让这个服务器类安装windows system和mysql db。

public class ServerWithWindowsAndMySql : ISuperFactory
    {
        public IDatabaseFactory InstallDB()
        {
            return new MySqlFactory();
        }

        public IOpSystemFactory InstallOpSystem()
        {
            return new WindowsFactory();
        }
    }

  最后在Main函数中调用看看。

static void Main(string[] args)
        {
            ISuperFactory server1 = new ServerWithWindowsAndMySql();
            server1.InstallDB().CreateDatabase().Delete();
            server1.InstallDB().CreateDatabase().Insert();
            server1.InstallOpSystem().InstallSystem().Start();
            server1.InstallOpSystem().InstallSystem().Shutdown();
        }

  下面是运行结果。

C#设计模式 ——  工厂模式

  我们可以看到实现了超级工厂的服务器类同时拥有了创建数据库和安装操作系统的功能。这就是抽象工厂的用法。我们来看看抽象工厂的优缺点。优点:

  1.实现了不同工厂之间的解耦。

  缺点:

  1.代码量成倍的增加

  2.抽象工厂并不符合开闭原则。如果这个时候我们需要在超级工厂中添加一个新的工厂,那么具体类也必须要作出修改。

4.总结

  工厂模式同样是设计模式中比较常用而且比较容易理解(抽象工厂除外)的设计模式。同时也能加深我们对面向对象中“多态”这个概念的理解:我们只需要关注接口中方法的声明,不用知道具体类有什么方法方法如何实现。换句话说我们只需要声明了一个接口,便可以直接调用接口的方法,当然前提是接口必须由实现该接口的具体类来实例化。同时我们在工作中也必须对设计模式的使用稍加思考,只有我们需要去使用这个设计模式的时候才去使用,如果我们为了使用设计模式而去使用设计模式,我们反而会得到糟糕的效果。

点赞
收藏
评论区
推荐文章
happlyfox happlyfox
3年前
笑说设计模式-小白逃课被点名
关于我简介工厂模式(FactoryPattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。分类工厂模式可以分为三种,其中简单工厂一般不被认为是一种设计模式,可以将其看成是工厂方法的一种特殊
zdd小小菜鸟 zdd小小菜鸟
2年前
创建型-2-抽象工厂模式( Abstract Factory Pattern )
创建型2抽象工厂模式(AbstractFactoryPattern)抽象工厂模式(AbstractFactoryPattern)是围绕一个超级工厂创建其他工厂tex该超级工厂又称为其他工厂的工厂在抽象
Wesley13 Wesley13
3年前
Java设计模式之三种工厂模式
工厂模式实现了创建者和调用者的分离,实现了更好的解耦。详细分类:1)简单工厂模式(静态工厂模式);2)工厂方法模式;3)抽象工厂模式面向对象设计的基本原则:1)      OCP(开闭原则,OpenClosedPrinciple):一个软件的实体应当对扩展开放,对修改关闭。2)      
Wesley13 Wesley13
3年前
Unity C# 设计模式(二)简单工厂模式
定义:简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactoryMethod)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该
Wesley13 Wesley13
3年前
Java描述设计模式(04):抽象工厂模式
一、抽象工厂模式1、生活场景汽车生产根据用户选择的汽车类型,指定不同的工厂进行生产,选择红旗轿车,就要使用中国工厂,选择奥迪轿车,就要使用德国工厂。2、抽象工厂模式1.抽象工厂模式:定义了一个interface用于创建相关对象或相互依赖的对象,而无需指明具体的类;2.抽象工厂模式可以
Wesley13 Wesley13
3年前
Java进阶篇设计模式之三
前言在上一篇(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxuwujing%2Fp%2F9363142.html)中我们学习了工厂模式,介绍了简单工厂模式、工厂方法和抽象工厂模式。本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式。
Wesley13 Wesley13
3年前
Java中23种设计模式详解
Java中23种设计模式1\.设计模式31.1创建型模式41.1.1工厂方法41.1.2抽象工厂61.1.3建造者模式101.1.4单态模式131.1.5原型模式151.2结构型模式171.2.1适配器模式171.2.2桥接模式191.2.3组合
Stella981 Stella981
3年前
Python之设计模式
一、设计模式分类a、创建型模式简单工厂模式一、内容不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。二、角色工厂角色(Creator)抽象产品角色(Product)具体产品角色(ConcreteProduct)
Wesley13 Wesley13
3年前
23种设计模式(面向对象语言)
一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。所有的创建型模式都有两个主要功能:  1.将系统所使用的具体类的信息封装起来  2.隐藏
Wesley13 Wesley13
3年前
C++ 常用设计模式(学习笔记)
设计模式1、工厂模式在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时,建议直接new完成一个实例对象的创建。1.1、简单工厂模式主要特点是需要在工厂类中做判断,从而创造相应的产品,当