刚开始接触设计模式时就常常听到同事提起工厂模式,那时也看过一些人写的
Blog
,
但是往往把注意力放在代码的编写上。在这段时间的学习中慢慢体会到设计模式是用来解决一类问题,而不是某些固定的代码片段。换句话说是解决问题的思想。设
计模式可以解决模块的耦合关系,可以解决因需求变动带来的问题。程序在第一次编写时,各个模块之间可能是紧耦合,但是经过代码重构,可以将模块之间变为松
耦合。当然,我觉得我们也可以在软件设计之初把变化考虑到其中,对于业务型软件设计,在了解需求后,可以尽可能将其分出主次关系。也就是主体与枝节的关
系。如下图
对
于工厂模式来说,要求高层模块变化相对较慢,底层模块变化相对较快。这样符合设计模式中的依赖倒置原则——高层模块不依赖于底层模块。换句话说,软件设计
是要划分易变部分和稳定部分。这样在一些枝节问题发生变化时,主干不用变化。如果是紧耦合状态,有可能造成一个地方变化,连带着很多地方要发生变化。
工厂模式要解决的是“某个对象”的创建工作,由于需求的变化,这个对象常常面临着剧烈的变化,但是这个对象拥有的接口相对稳定。也就是说:枝节常常发生变化,但是枝节与主干的接口相对稳定。
《设计模式》中是这样说明:定义一个用于创建对象的接口,让子类决定实例化那个类。
FactoryMethod
使得一个类的实例化延迟到子类。
现在看这句话可能有些不明白,我们一会再来分析一下。先来看看工厂模式的大体结构。如下图:
我们还是用实例化汽车的例子来解释。对于客户端程序(
ClientApp
)如果想要一个汽车的对象,需要调用生产这个汽车的
Factory
的对象。当然,这个类继承自一个
AbstractFactory
基类。而这个
Factory
类就是《设计模式》中提到的“子类”,它来决定实例化那个类。
下面我们来具体实现一下代码,首先,我们需要两个基类,一个是
Car
的,一个是
Factory
的。
Factory
类型的作用是构建
Car
的对象。代码如下:
public
abstract
class AbstractCar
{
public
abstract
string Run();
public
abstract
string Stop();
public
abstract
string Accelerate();
public
abstract
string Decelerate();
}
public
abstract
class AbstractFactory
{
public
abstract AbstractCar CreateCar();
}
下面,我们来做一个BMW的实现代码:
public
class BMWCar:AbstractCar
{
public
override
string Run()
{
return
"BMW Run";
}
public
override
string Stop()
{
return
"BMW Stop";
}
public
override
string Accelerate()
{
return
"BMW Accelerate";
}
public
override
string Decelerate()
{
return
"BMW Decalerate";
}
}
public
class BMWFactory:AbstractFactory
{
public
override AbstractCar CreateCar()
{
return
new BMWCar();
}
}
这样我们就可以在客户端程序得到一个BMW的实例,并使用它的方法:
class
Class1
{
///
<summary>
///
应用程序的主入口点。
///
</summary>
[STAThread]
static
void
Main(string[] args)
{
AbstractCar car = CreateCarFunc(new BMWFactory ());
Console.Write(car.Run() + "\n");
Console.Write(car.Stop() + "\n");
Console.Write(car.Accelerate() + "\n");
Console.Write(car.Decelerate() + "\n");
Console.Read();
}
public
static AbstractCar CreateCarFunc(AbstractFactory factory)
{
return factory.CreateCar();
}
}
在客户端程序中,我们AbstractFactory的对象来得到Car的对象
结果如下:
BMW Run
BMW Stop
BMW Accelerate
BMW Decalerate
如果我们需求变了,现在要
BORA
的对象,那末,我们首先要对程序作一下扩展,先加入
BOAR
的
Car
类和
Factory
类,代码如下:
public
class BORACar:AbstractCar
{
public
override
string Run()
{
return
"BORA Run";
}
public
override
string Stop()
{
return
"BORA Stop";
}
public
override
string Accelerate()
{
return
"BORA Accelerate";
}
public
override
string Decelerate()
{
return
"BORA Decelerate";
}
}
public
class BORAFactory:AbstractFactory
{
public
override AbstractCar CreateCar()
{
return
new BORACar();
}
}
在客户端程序中,我们只要稍作修改,将BMWFactory的实例化变为BORAFactory的实例化就可以,代码如下:
class
Class1
{
///
<summary>
///
应用程序的主入口点。
///
</summary>
[STAThread]
static
void
Main(string[] args)
{
AbstractCar car = CreateCarFunc(new BORAFactory());
Console.Write(car.Run() + "\n");
Console.Write(car.Stop() + "\n");
Console.Write(car.Accelerate() + "\n");
Console.Write(car.Decelerate() + "\n");
Console.Read();
}
public
static AbstractCar CreateCarFunc(AbstractFactory factory)
{
return factory.CreateCar();
}
}
得到的结果是:
BORA Run
BORA Stop
BORA Accelerate
BORA Decelerate
Factory Method
的几个要点:
1
、
Factory Method
模式主要用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致软件的脆弱。
2
、
Factory Method
模式通过面向对象的手法,将所要创建的对象工作延迟到子类,从而实现一种扩展的策略,较好的解决了这种紧耦合关系。