🚀24个C#设计模式目录    🍺源码地址

概述

一个水果农场,用户需要某一种水果时,农场能够根据用户所提供的水果名称返回该水果。在此,水果农场被称为工厂(Factory),而生产出的水果被称为产品,水果的名称被称为参数,工厂可以根据参数的不同返回不同的产品,这就是简单工厂的动机。

简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

使用频率:★★★☆☆

结构与实现

简单工厂模式包含以下3个角色:

  1. Factory(工厂角色)
  2. Product (抽象产品角色)
  3. ConcreteProduct (具体产品角色)

这里仍然使用开头的例子,水果农场(FruitFactory)作为工厂角色,水果(Fruit)为抽象产品角色,苹果和橘子作为具体产品角色,由此可以得出模式结构:

工厂角色是这个简单工厂模式的核心,他需要提供静态的工厂方法,来根据参数返回实例化对象。抽象产品角色封装了各个产品的公共方法,其具体产品角色间不同的方法由各自子类实现。

1
2
3
4
5
6
7
8
9
10
abstract class Fruit
{
// 所有产品类的公共业务方法
public void MethodSame()
{
Console.WriteLine("Same method for all fruit");
}
// 声明抽象业务方法
public abstract void MethodDiff();
}

🍎Apple和🍊Orange继承Fruit并重载MethodDiff()

1
2
3
4
5
6
7
class Apple : Fruit
{
public override void MethodDiff()
{
Console.WriteLine("Different method for Apple");
}
}
1
2
3
4
5
6
7
class Orange : Fruit
{
public override void MethodDiff()
{
Console.WriteLine("Different method for Orange");
}
}

FruitFactory提供静态方法根据参数返回不同实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}
}

客户端调用方法如下:

1
2
3
4
5
6
static void Main(string[] args)
{
Fruit fruit= FruitFactory.GetFruit("Apple");
fruit.MethodSame();
fruit.MethodDiff();
}

在实现上,也可以将FruitFruitFactory合并,将GetFruit方法移动到Fruit中以简化此模式。

优缺点

优点:

  1. 简单工厂模式实现了对象创建和使用的分离。
  2. 客户端无需知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可。
  3. 通过引入配置文件,可以在不修改任何客户端代码的情况下,更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

缺点:

  1. 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
  2. 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
  3. 系统扩展困难,一旦添加新产品不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  4. 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法新城基于继承的等级结构。在C#语言中,不能通过类的实例化对象来访问静态方法和静态变量,无法在客户端代码中针对父类编程,而在运行时使用工厂子类对象来覆盖父类,因此,工厂类不能得到很好的扩展。

适用场景

  • 工厂类负责创建的对象较少时
  • 客户端只知道传入工厂类的参数,不关心如何创建对象