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

1.简单工厂模式

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

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

     public interface IDatabase
{
void Insert();
void Delete();
}

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

     public class SqlServer : IDatabase
{
public void Delete()
{
Console.WriteLine("delete data from sqlserver");
} public void Insert()
{
Console.WriteLine("insert data to sqlserver");
}
} public class MySql : IDatabase
{
public void Delete()
{
Console.WriteLine("delete data from mysql");
} public void Insert()
{
Console.WriteLine("insert data to mysql");
}
} public class MongoDB : IDatabase
{
public void Delete()
{
Console.WriteLine("delete data from mongoDb");
} public void Insert()
{
Console.WriteLine("insert data to mongoDb");
}
}

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

     public static class DatabaseFactory
{
public static IDatabase CreateDatabase(string dbType)
{
IDatabase db = null; switch (dbType)
{
case "MySql":
db = new MySql();
break;
case "SqlServer":
db = new SqlServer();
break;
case "MongoDB":
db = new MongoDB();
break;
default:
break;
} return db;
}
}

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

         static void Main(string[] args)
{
IDatabase db1 = DatabaseFactory.CreateDatabase("MySql");
db1.Insert();
db1.Delete(); IDatabase db2 = DatabaseFactory.CreateDatabase("SqlServer");
db2.Insert();
db2.Delete(); IDatabase db3 = DatabaseFactory.CreateDatabase("MongoDB");
db3.Insert();
db3.Delete();
}

  来看一些控制台的输出:

  这就是简单工厂模式。

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

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

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

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

2.工厂模式

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

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

     interface IDatabaseFactory
{
IDatabase CreateDatabase();
}

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

     public class MongoDbFactory : IDatabaseFactory
{
public IDatabase CreateDatabase()
{
return new MongoDB();
}
} public class MySqlFactory : IDatabaseFactory
{
public IDatabase CreateDatabase()
{
return new MySql();
}
} public class SqlServerFactory : IDatabaseFactory
{
public IDatabase CreateDatabase()
{
return new SqlServer();
}
}

  最后我们在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();
}

  下面是运行结果。

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

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

  缺点:

  1.代码量成倍的增加

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

4.总结

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

C#设计模式 —— 工厂模式的更多相关文章

  1. .NET设计模式: 工厂模式

    .NET设计模式: 工厂模式(转) 转自:http://www.cnblogs.com/bit-sand/archive/2008/01/25/1053207.html   .NET设计模式(1): ...

  2. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

  3. [Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  4. javascript 设计模式-----工厂模式

    所谓的工厂模式,顾名思义就是成批量地生产模式.它的核心作用也是和现实中的工厂一样利用重复的代码最大化地产生效益.在javascript中,它常常用来生产许许多多相同的实例对象,在代码上做到最大的利用. ...

  5. JavaScript设计模式——工厂模式

    工厂模式:是一种实现“工厂”概念的面上对象设计模式.实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.创建一个对象常常需要复杂的过程,所以不 ...

  6. 10.Java设计模式 工厂模式,单例模式

    Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...

  7. 学习:java设计模式—工厂模式

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...

  8. 设计模式——工厂模式 (C++实现)

    软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累. ...

  9. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  10. 设计模式——工厂模式(Factory)

    要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1.概念 工厂模式定 ...

随机推荐

  1. iView开始结束时间组件

    演示地址:https://run.iviewui.com/TGIKGkIt 测试页面文件: <template> <div> <startEndTime @newEndT ...

  2. drupal中安装CKEditor文本编辑器,并配置图片上传功能 之 方法二

    drupal中安装CKEditor文本编辑器,并配置图片上传功能 之 方法一 中介绍了ckeditor的安装和配置方法,其实还有另一种新方法,不用IMCE模块. 不过需要ckfinder的JS库,可以 ...

  3. Linux菜鸟简单命令

    想要使用Linux,以下这些命令不可少的哦! 我在工作中经常用到的大多数都是一些文件的查找,和上传下载什么的,没什么技术含量,所以除了自己整理的之外,还有借鉴的别的大神的一些命令,我会在最后标注的\( ...

  4. C#-创建并添加TXT文件

    public static void WriteToText(string txtContent, string txtPath) { using (FileStream fs = new FileS ...

  5. number to string

    C++进行int to string和string to int 下面方法一存在内存泄露 #include<strstream>void main(){ std::strstream ss ...

  6. 基于SVM.NET的验证码识别算法实现

    工作之余,对这个算法做了一些研究,并成功对验证码进行了识别,对普通验证码识别率在90%左右,识别速度相当快,已基于此做过一些自动查询.提交程序(例如投票.发帖等) ,还上过淘宝店,赚过一笔外快,现将相 ...

  7. Vue 框架-01- 入门篇 图文教程

    Vue 框架-01- 入门篇 图文教程 Vue 官网:https://cn.vuejs.org/ 关于 Vue 的基础大家可以在官网的[起步]去学习,本系列文章主要针对实例项目应用 一.Vue 的安装 ...

  8. VS2010 创建 windows service 程序

    参考网上保护眼睛程序,自写程序如下. 1.创建一个名词为“CareEyeService”,类型为“WindowsService”的应用程序. 自动生成代码如下图: 2.修改ServiceCareEye ...

  9. sqldataAdapter/dataset/datatable的使用

    public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Loa ...

  10. 面向对象进阶----->反射 getattr 和hasattr方法

    判断一个对象有没有血缘关系:isinstance() 里面写的是字类对象和父类名用来判断他们的关系 issubclass()是用来判断两个类是不是有继承的关系 ,括号内 写字类名和父类名  可以判断出 ...