《C#设计模式》 三种工厂设计模式
-
【简单工厂模式】
-
【工厂方法模式】
-
【抽象工厂模式】
第一种:简单工厂模式
一:【简单工厂模式】
简单工厂模式概念(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
二: 案例分析
使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图工具,每个几何图形都具有绘制draw()和擦除erase()两个方法;
首先定义一个接口类;包含两个方法;绘制;擦除;
public interface Draws
{
//绘制图形
void draw();
//擦除图形
void erase();
}
再在某个具体产品类继承这个Draws接口;以下为三种图形实现方式;
//==============================================================
// 作者:zhoupei
// 时间:2019/2/18 14:12:11
// 文件名:Circular
// 版本:V1.0.1
// 说明:圆形具体产品类
//==============================================================
class Circular : Draws
{
public void draw()
{
Console.WriteLine("绘制圆形图形");
}
public void erase()
{
Console.WriteLine("擦除圆形图形");
}
}
class Rectangle : Draws
{
//绘制矩形
public void draw()
{
Console.WriteLine("绘制矩形图形");
}
//擦除矩形
public void erase()
{
Console.WriteLine("擦除矩形图形");
}
}
class Triangle: Draws
{
public void draw()
{
Console.WriteLine("绘制三角形图形");
}
public void erase()
{
Console.WriteLine("擦除三角形图形");
}
}
再写个图形处理工厂类,静态工厂方法;
class FigureFactory
{
//静态工厂方法
public static Draws Getfigure(string figtype)
{
Draws dws = null;
switch (figtype.ToLower())
{
case "rectangle":
dws = new Rectangle();
break;
case "triangle":
dws = new Rectangle();
break;
case "circular":
dws = new Rectangle();
break;
default:
dws = null;
break;
}
return dws;
}
}
客户端调用方法,这里根据读取全局配置文件的方式来获取路径;
添加app.config文件;配置路径;
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="figureType" value="Circular"/> //传入圆形
</appSettings>
</configuration>
Main函数调用方法;
static void Main(string[] args)
{
Draws dw;
string figurestr = ConfigurationSettings.AppSettings["figureType"];
dw = FigureFactory.Getfigure(figurestr);
dw.draw();//绘制 - 圆形
dw.erase();//擦除 - 圆形
Console.ReadLine();
}
优缺点总结:
1. 主要优点
简单工厂模式的主要优点如下:
(1) 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂模式实现了对象创建和使用的分离。
(2) 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量。
(3) 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
2. 主要缺点
简单工厂模式的主要缺点如下:
(1) 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
(2) 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
(3) 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
(4) 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
第二种:工厂方法模式
工厂方法模式概念:工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。
案例分析:使用工厂方法模式设计一个程序来读取各种不同类型的图片格式,针对每一种图片格式都设计一个图片读取器,如GIF图片读取器用于读取GIF格式的图片、JPG图片读取器用于读取JPG格式的图片。需充分考虑系统的灵活性和可扩展性。
首先定义图片接口 即抽象产品类;代码如下!
/// <summary>
/// 图片处理接口
/// 抽象产品:它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
/// </summary>
interface Imager
{
void GetImages();
}
然后定义抽象工工厂类; 代码如下!
interface ImagerFactory
{
Imager GetImagelist(); //抽象产品工厂类
}
现在客户需求里要分别读取处理JPG格式的图片跟GIF格式的图片;
具体产品类
//==============================================================
// 作者:zhoupei
// 时间:2019/2/18 11:45:23
// 文件名:GifImg
// 版本:V1.0.1
// 说明:Gif图片 - 具体产品类
//==============================================================
class GifImg : Imager
{
public void GetImages()
{
Console.WriteLine("读取GIF图片。");
}
}
class JpgImg : Imager
{
public void GetImages()
{
Console.WriteLine("读取Jpg图片。");
}
}
具体产品工厂
//==============================================================
// 作者:zhoupei
// 时间:2019/2/18 11:46:05
// 文件名:GifImgFactory
// 版本:V1.0.1
// 说明:产品具体工厂
//==============================================================
class GifImgFactory : ImagerFactory //继承自抽象产品类
{
public Imager GetImagelist()
{
Imager im = new GifImg();
return im;
}
}
class JpgImgFactory : ImagerFactory
{
public Imager GetImagelist()
{
Imager im = new JpgImg();
return im;
}
}
客户端Main()调用: 方式跟以上一样
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="imageFactory" value="FactoryMethod.JpgImgFactory"/>
</appSettings>
</configuration>
static void Main(string[] args)
{
ImagerFactory ifc;
Imager img;
string factStr = ConfigurationManager.AppSettings["imageFactory"];
ifc = (JpgImgFactory)Assembly.Load("FactoryMethod").CreateInstance(factStr);
img = ifc.GetImagelist();
img.GetImages();
Console.ReadLine();
}
工厂方法模式总结:
1. 主要优点
工厂方法模式的主要优点如下:
(1) 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
(2) 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,就正是因为所有的具体工厂类都具有同一抽象父类。
(3) 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
2. 主要缺点
工厂方法模式的主要缺点如下:
(1) 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
(2) 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
第三中:抽象工厂模式
抽象工厂模式概述:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。
案例分析:某个软件公司欲推出一款新的手机游戏软件,该软件能够支持Symbian、Android和Windows Mobile等多个智能手机操作系统平台,针对不同的手机操作系统,该游戏软件提供了不同的游戏操作控制(OperationController)类和游戏界面控制(InterfaceController)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台,为了满足上述需求,试采用抽象工厂模式对其进行设计。
具体实现:
//抽象产品类
interface Android
{
void Description();
}
interface Apple
{
void Description();
}
interface ASymbian
{
void Description();
}
抽象工厂类:
/// <summary>
/// 游戏支持系统抽象工厂
/// </summary>
interface GameFactory
{
ASymbian CanRunonSymbian();
Android CanRunonAndroid();
Apple CanRunonApple();
}
具体产品类
//==============================================================
// 作者:zhoupei
// 时间:2019/2/18 16:08:35
// 文件名:InterfaceControllerOnAndroid
// 版本:V1.0.1
// 说明:安卓系统支持InterfaceControllerOnAndroid
//==============================================================
class InterfaceControllerOnAndroid : Android
{
public void Description()
{
Console.WriteLine("安卓系统支持InterfaceControllerOnAndroid游戏操作控制");
}
}
class InterfaceControllerOnApple : Apple
{
public void Description()
{
Console.WriteLine("苹果支持 InterfaceController游戏操作控制");
}
}
class InterfaceControllerOnSymbian :ASymbian
{
public void Description()
{
Console.WriteLine("塞班系统支持InterfaceController游戏操作控制");
}
}
//==============================================================
// 作者:zhoupei
// 时间:2019/2/18 16:07:45
// 文件名:OperationControllerOnAndroid
// 版本:V1.0.1
// 说明:支持OperationController
//==============================================================
class OperationControllerOnAndroid :Android
{
public void Description()
{
Console.WriteLine("安卓系统支持OperationControllerOnAndroid游戏操作控制");
}
}
class OperationControllerOnApple : Apple
{
public void Description()
{
Console.WriteLine("苹果系统支持OperationController游戏操作控制");
}
}
class OperationControllerOnSymbian : ASymbian
{
public void Description()
{
Console.WriteLine("塞班系统支持OperationController游戏操作控制");
}
}
具体工厂类:
//==============================================================
// 作者:zhoupei
// 时间:2019/2/18 16:10:59
// 文件名:B_InterfaceController
// 版本:V1.0.1
// 说明:
//==============================================================
class B_InterfaceController : GameFactory
{
public Android CanRunonAndroid()
{
return new InterfaceControllerOnAndroid();
}
public Apple CanRunonApple()
{
return new InterfaceControllerOnApple();
}
public ASymbian CanRunonSymbian()
{
return new InterfaceControllerOnSymbian();
}
}
class B_OperationController : GameFactory
{
public Android CanRunonAndroid()
{
return new OperationControllerOnAndroid();
}
public Apple CanRunonApple()
{
return new OperationControllerOnApple();
}
public ASymbian CanRunonSymbian()
{
return new OperationControllerOnSymbian();
}
}
抽象工厂模式总结
1. 主要优点
抽象工厂模式的主要优点如下:
(1) 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
(2) 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
(3) 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
2. 主要缺点
抽象工厂模式的主要缺点如下:
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
三种工厂方式学习总结完毕,欢迎指正,讨论指教;
学习来自我的大学老师《C#设计模式》,感谢恩师;