概述
一个水果农场,用户需要某一种水果时,农场能够根据用户所提供的水果名称返回该水果。在此,水果农场被称为工厂(Factory),而生产出的水果被称为产品,水果的名称被称为参数,工厂可以根据参数的不同返回不同的产品,这就是简单工厂的动机。
简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
使用频率:★★★☆☆
结构与实现
简单工厂模式包含以下3个角色:
- Factory(工厂角色)
- Product (抽象产品角色)
- ConcreteProduct (具体产品角色)
这里仍然使用开头的例子,水果农场(FruitFactory)作为工厂角色,水果(Fruit)为抽象产品角色,苹果和橘子作为具体产品角色,由此可以得出模式结构:
工厂角色是这个简单工厂模式的核心,他需要提供静态的工厂方法,来根据参数返回实例化对象。抽象产品角色封装了各个产品的公共方法,其具体产品角色间不同的方法由各自子类实现。
abstract class Fruit
{
// 所有产品类的公共业务方法
public void MethodSame()
{
Console.WriteLine("Same method for all fruit");
}
// 声明抽象业务方法
public abstract void MethodDiff();
}
🍎Apple
和🍊Orange
继承Fruit
并重载MethodDiff()
。
class Apple : Fruit
{
public override void MethodDiff()
{
Console.WriteLine("Different method for Apple");
}
}
class Orange : Fruit
{
public override void MethodDiff()
{
Console.WriteLine("Different method for Orange");
}
}
FruitFactory
提供静态方法根据参数返回不同实例。
class FruitFactory
{
public static Fruit GetFruit(string arg)
{
Fruit fruit = null;
if (arg == "Apple")
{
fruit = new Apple();
}
else if (arg == "Orange")
{
fruit = new Orange();
}
return fruit;
}
}
客户端调用方法如下:
static void Main(string[] args)
{
Fruit fruit= FruitFactory.GetFruit("Apple");
fruit.MethodSame();
fruit.MethodDiff();
}
在实现上,也可以将Fruit
和FruitFactory
合并,将GetFruit
方法移动到Fruit
中以简化此模式。
优缺点
优点:
- 简单工厂模式实现了对象创建和使用的分离。
- 客户端无需知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可。
- 通过引入配置文件,可以在不修改任何客户端代码的情况下,更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点:
- 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
- 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
- 系统扩展困难,一旦添加新产品不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法新城基于继承的等级结构。在C#语言中,不能通过类的实例化对象来访问静态方法和静态变量,无法在客户端代码中针对父类编程,而在运行时使用工厂子类对象来覆盖父类,因此,工厂类不能得到很好的扩展。
适用场景
- 工厂类负责创建的对象较少时
- 客户端只知道传入工厂类的参数,不关心如何创建对象