C#设计模式 —— 工厂模式
。 工厂模式同样是项目中最常用的设计模式,工厂模式中又分为简单工厂,工厂方法,抽象工厂。下面我们由简单的开始逐一介绍。
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#设计模式 —— 工厂模式的更多相关文章
- .NET设计模式: 工厂模式
.NET设计模式: 工厂模式(转) 转自:http://www.cnblogs.com/bit-sand/archive/2008/01/25/1053207.html .NET设计模式(1): ...
- 【设计模式】Java设计模式 -工厂模式
[设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...
- [Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- javascript 设计模式-----工厂模式
所谓的工厂模式,顾名思义就是成批量地生产模式.它的核心作用也是和现实中的工厂一样利用重复的代码最大化地产生效益.在javascript中,它常常用来生产许许多多相同的实例对象,在代码上做到最大的利用. ...
- JavaScript设计模式——工厂模式
工厂模式:是一种实现“工厂”概念的面上对象设计模式.实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.创建一个对象常常需要复杂的过程,所以不 ...
- 10.Java设计模式 工厂模式,单例模式
Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...
- 学习:java设计模式—工厂模式
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...
- 设计模式——工厂模式 (C++实现)
软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累. ...
- Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...
- 设计模式——工厂模式(Factory)
要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1.概念 工厂模式定 ...
随机推荐
- 解决ArcMap启动时只停留在初始化界面的方法
方法1 修改环境变量TEMP和TMP为C:\Temp 重启ArcMap. 方法2 关闭系统进程Print Spooler. 打开C:\WINDOWS\system32\spool\PRINTERS,删 ...
- 【javascript】javascript设计模式mixin模式
概述: Mixin是JavaScript中用的最普遍的模式,几乎所有流行类库都会有Mixin的实现.任意一个对象的全部或部分属性拷贝到另一个对象上. 一 .混合对象 二 .混合类
- Java 之集合框架 上(9)
Java 中的集合框架 如果一个类中存在很多相同类型的属性. 例如:学生类 学生可以选课,因此存在很多课程类型的属性.但是每个学生选择的课程的种类和数量是不一样的. 如果将每一个课程类型的属性都列到课 ...
- Install MySQL on Mac
1. 可参考此文章:http://www.cnblogs.com/macro-cheng/archive/2011/10/25/mysql-001.html 2. 目前MySQL(我用的mysql 5 ...
- 应用程序 调用 webservice
首先用VS创建一个WebService服务工程,并且完成基本功能,本人完成的是html转pdf功能. 然后,新建一个Windows应用程序. 添加WebService到Windows项目中,如图 然后 ...
- Selenium之TestNG安装
一.在Eclipse中安装TestNG 1.打开eclipse-->help-->Install New Software-->Add,输入Name和Location后,点击OK. ...
- laravel入门-01
创建laravel应用 laravel new app_name 使用 PHP 内置 web server 驱动我们的网站 cd xxx/public php -S localhost:port 查看 ...
- 沉淀再出发:用python画各种图表
沉淀再出发:用python画各种图表 一.前言 最近需要用python来做一些统计和画图,因此做一些笔记. 二.python画各种图表 2.1.使用turtle来画图 import turtle as ...
- 【最强】微软Tech Summit 2017动手实验室教程
[最强]微软Tech Summit 2017动手实验室教程 原创 2017-11-07 MSPrecious MSPrecious成长荟 这是! 你绝对找不到的教程! Ignite2016的教程你找到 ...
- August 28th 2017 Week 35th Monday
The truth may hurt for a little while but a lie hurts forever. 真相会让我们痛一阵,但谎言会让我们痛一生. Once you make a ...