更详细见:https://www.runoob.com/design-pattern/abstract-factory-pattern.html

什么是抽象工厂

抽象工厂就是从一个大工厂创建n多个小工厂,再从小工厂里面创建对象

  • 适用场景:当系统需要创建多个相关或依赖的对象,而不需要指定具体类时。
  • 运用实例:假设有不同类型的衣柜,每个衣柜(具体工厂)只能存放一类衣服(成套的具体产品),如商务装、时尚装等。每套衣服包括具体的上衣和裤子(具体产品)。所有衣柜都是衣柜类(抽象工厂)的具体实现,所有上衣和裤子分别实现上衣接口和裤子接口(抽象产品)。
  • 与简单工厂区别:可以批量管理相关联对象

缺优点

  • 优点:

a. 确保同一产品族的对象一起工作

比如都是怪物和颜色产品族,有哥布林、巨魔,每个怪物都得有颜色

b. 客户端不需要知道每个对象的具体类,简化了代码。直接干就行。

  • 缺点:

扩展产品族非常困难。增加一个新的产品呢族需要修改抽象工厂和所以具体工厂的代码

比如:新增了个道具族,抽象工厂要新增一个抽象的创建方法。所有具体的工厂必须去实现那个新增的方法。同时还要新增工厂类

使用场景

  • QQ 换皮肤时,整套皮肤一起更换。
  • 创建跨平台应用时,生成不同操作系统的程序。

具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface IMonster
{
/// <summary>
/// 攻击
/// </summary>
void Attack(IMonster monster);
/// <summary>
/// 受伤
/// </summary>
void Injured(int damage);

string GetMonterType();
}
//你的代码中 “怪物” 和 “颜色” 是两大相关产品族
//同一产品族内的对象(哥布林 / 巨魔、红色 / 蓝色)业务逻辑相通
//且怪物依赖颜色,这就是 “多个相关或依赖的对象”;
public interface IColor
{
/// <summary>
/// 设置颜色
/// </summary>
/// <param name="color"></param>
void SetColor(string color);

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public abstract class Monster
{
public int atk;
public int hp;
public string color;
}
public class Red : IColor
{
public string color;
public void SetColor(string color)
{
this.color = color;
}
}

public class Goblin : Monster, IMonster, IColor
{
public int atk = 10;
public int hp = 100;
public void Attack(IMonster monster)
{
Debug.Log(this.GetType() + "攻击了" + monster.GetMonterType());
monster.Injured(atk);

}

public string GetMonterType()
{
return this.GetType().Name;
}

public void Injured(int damage)
{
hp -= damage;
Debug.Log(this.GetType() + "受到了" + damage + "点伤害");
}

public void SetColor(string color)
{
this.color = color;
}
}

public class Troll : Monster, IMonster, IColor
{
public int atk = 20;
public int hp = 200;

public void Attack(IMonster monster)
{
Debug.Log(this.GetType() + "攻击了" + monster.GetMonterType());
monster.Injured(atk);

}

public string GetMonterType()
{
return this.GetType().Name;
}

public void Injured(int damage)
{
hp -= damage;
Debug.Log(this.GetType() + "受到了" + damage + "点伤害");
}

public void SetColor(string color)
{
this.color = color;
}


}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public abstract class AbstractFactory
{
public abstract IMonster CreateMonster(string monster);
public abstract IColor CreateColor(string color);
}

public class MonsterFactory : AbstractFactory
{
public override IColor CreateColor(string color)
{
return null;
}
public override IMonster CreateMonster(string monster)
{
if (monster == null)
return null;
switch (monster)
{
case "哥布林":
return new Goblin();
case "巨魔":
return new Troll();
default:
return null;
}

}
}

public class ColorFactory : AbstractFactory
{
public override IColor CreateColor(string color)
{
if (color == null) return null;
switch (color)
{
case "red":
return new Red();
default: return null;
}
}

public override IMonster CreateMonster(string monster)
{
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class FactoryProducer
{
public static AbstractFactory getFactory(String choice)
{
if (choice == "怪物")
{
return new MonsterFactory();
}
else if (choice == "颜色")
{
return new ColorFactory();
}
return null;
}
}