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.概念 工厂模式定 ...
随机推荐
- JQuery和html+css实现带小圆点和左右按钮的轮播图
是的!你没看错!还是轮播图.这次的JQuery的哟!! CSS代码: /*轮播图 左右按钮 小白点*/ #second_div{ margin-top: 160px; } .img_box{ over ...
- 微信小程序-view组件
<view class="section"> <view class="section__title">flex-direction: ...
- CentOS 7.2mini版本下编译安装php7.0.10+MySQL5.7.14+Nginx1.10.1
一.安装前的准备工作 1.yum update #更新系统 1.1)vi /etc/selinux/config # 禁止SELINUX,设置SELINUX=disabled 2.yum in ...
- CI框架去除index.php
打开apache的配置文件,conf/httpd.conf : LoadModule rewrite_module modules/mod_rewrite.so 把该行前的#去掉. 搜索 AllowO ...
- 使用 Nginx 对 ASP.NETCore网站 或 Docker 等进行反向代理,宝塔面板对 ASP.NET Core 反向代理
1,Nginx 的 配置文件 Nginx 可以配置反向代理.负载均匀等, 其默认配置文件名为 nginx.conf . 一般存放于 /你的安装目录/nginx/conf 下 Nginx 加载配置信息 ...
- 沉淀再出发:再谈java的多线程机制
沉淀再出发:再谈java的多线程机制 一.前言 自从我们学习了操作系统之后,对于其中的线程和进程就有了非常深刻的理解,但是,我们可能在C,C++语言之中尝试过这些机制,并且做过相应的实验,但是对于ja ...
- c# winform文本框数字,数值校验
文本框数字,数值校验 public void DigitCheck_KeyPress(object sender, KeyPressEventArgs e) { e.Handled = !char.I ...
- Java虚拟机10:Client模式和Server模式的区别
部分商用虚拟机中,Java程序最初是通过解释器对.class文件进行解释执行的,当虚拟机发现某个方法或代码块运行地特别频繁的时候,就会把这些代码认定为热点代码Hot Spot Code(这也是我们使用 ...
- 绕过disable_functions执行命令实验
绕过disable_functions执行命令实验 看下disable函数,所有命令函数都被禁用: 编译64位共享库: 命令成功执行: 参考链接: https://www.freebuf.com/ar ...
- 2、Android-UI(RecyclerView)
2.6.滚动控件-RecylerView ListView虽然使用的效果很好但是也是有缺点的 不使用一些技巧来提升它的运行效率,性能就非常差 扩展性也不是很好 只能实现数据的纵向滚动效果 实现横向滚动 ...