说到工厂方法不得不提简单工厂,那么简单工厂与工厂方法有什么不同呢?
下面我以气球来做一个简单的例子来说明:
简单工厂的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化 相关的类,对于客户端来说,去除了与具体产品的依赖。
//抽象类-气球
class Balloon
{
public void Show()
{
Console.WriteLine("展示");
}
public void Fly()
{
Console.WriteLine("放飞");
}
}
//蓝色气球
class BlueBalloon : Balloon
{
//继承基类方法
}
//红色气球
class RedBalloon : Balloon
{
//继承基类方法
}
简单工厂代码:
//简单工厂
class SimpleFactory
{
public static Balloon CreateBalloon(string type)
{
Balloon result = null;
switch (type)
{
case "蓝色气球":
result = new Balloon();
break;
case "红色气球":
result = new RedBalloon();
break;
}
return result;
}
}
客户端代码:
static void Main(string[] args)
{
Balloon Rqiqiu = SimpleFactory.CreateBalloon("红色气球");
Rqiqiu.Fly();
Balloon Bqiqiu = SimpleFactory.CreateBalloon("蓝色气球");
Bqiqiu.Show();
Console.Read();
}
而如果要增加一个"GreenBalloon"的功能,就一定要给SimpleFactory类的方法里面加‘Case’的分支条件,修改原有的类,这就违背了开放-封闭原则,所以工厂方法模式应运而生。
工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
//抽象类-气球
class Balloon
{
public void show()
{
Console.WriteLine("展示");
}
public void Fly()
{
Console.WriteLine("放飞");
}
}
//蓝色气球
class BlueBalloon : Balloon
{
//继承基类方法
}
//红色气球
class RedBalloon : Balloon
{
//继承基类方法
}
工厂方法模式代码为:
//制作气球的工厂
interface BFactory
{
Balloon CreateBalloon();
}
//制作蓝色气球的工厂
class BlueballoonFactory : BFactory
{
public Balloon CreateBalloon()
{
return new BlueBalloon();
}
}
//制作红色气球的工厂
class RedballoonFactory : BFactory
{
public Balloon CreateBalloon()
{
return new RedBalloon();
}
}
客户端代码为:
static void Main(string[] args)
{
BFactory factory = new BlueballoonFactory();
Balloon qiqiu = factory.CreateBalloon();
qiqiu.Fly();
qiqiu.show();
Console.Read();
}
对比两种代码我们可以发现:依据依赖倒转的原则,把工厂类抽象出一个接口,这个接口只有创建抽象气球的方法。然后,所有的要生产的具体类的工厂就去实现这个接口,这样一个简单工厂模式的工厂类变成了一个工厂抽象接口和多个具体生产对象的工厂,增加GreenBalloon的功能时,就不需要更改原有的工厂类。
下列情况可以考虑使用工厂方法模式:
- 创建对象需要大量重复的代码。
- 创建对象需要访问某些信息,而这些信息不应该包含在复合类中。
- 创建对象的生命周期必须集中管理,以保证在整个程序中具有一致的行为。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说工厂方法把简单工厂的内部逻辑选择判断转移到了客户端代码来进行,这样本来是改工厂类,而现在是修改客户端!这样就降低了客户程序与产品对象的耦合,因此工厂方法模式是简单工厂模式的进一步抽象和推广。