工厂模式的定义和用途
工厂模式的主要目的就是将对象创建的过程封装起来,客户端只需要创建对象,而不需要去了解创建对象的过程。
举一个例子(骷髅、士兵、弓箭手等):如果我们在客户端去创建对象的话,我们还要去根据不同的类型去判断需要创建什么对象,怎么去创建的逻辑。而使用工厂模式的话,客户端只需要直接告诉工厂,我需要创建骷髅的对象,你直接给我就行了。这样客户端就无需知道创建的过程,只需要知道通过工厂,我可以拿到这个对象。
简单/静态工厂模式
接下来,我们将以一个案例去学习简单工厂模式
假设我们要开发一个地牢游戏,需要生成不同类型的怪物:
不用工厂模式的写法
// 直接创建具体怪物对象
monster = Zombie() // 创建僵尸
boss = Demon() // 创建恶魔
//当需要根据条件创建不同怪物时:
monster_type = “zombile”
if(monster_type == "zombie")
monster = new Zombie()
else if(monster_type == "skeleton")
monster = new Skeleton()
else if(monster_type == "demon")
monster = new Demon()
当客户端的某个部分需要用到怪物,也可能在另一个部分中,也会用到创建怪物的逻辑。就会造成创建逻辑分散在多处,难以维护
当我们创建一个新的怪物的时候,需要修改这里面的代码。
暴露的具体的类,违反了封装原则。
使用简单工厂模式
定义怪物的接口
// 怪物接口(抽象产品)
public interface IMonster
{
void Attack();
}
创建具体的怪物类
// 具体怪物类(具体产品)
public class Zombie : IMonster
{
public void Attack()
{
Console.WriteLine("僵尸撕咬攻击!");
}
}
public class Skeleton : IMonster
{
public void Attack()
{
Console.WriteLine("骷髅弓箭射击!");
}
}
public class Demon : IMonster
{
public void Attack()
{
Console.WriteLine("恶魔火焰喷射!");
}
}
创建怪物的工厂
public class MonsterFactory
{
// 创建怪物的静态方法
public static IMonster CreateMonster(string monsterType)
{
switch (monsterType.ToLower())
{
case "zombie":
return new Zombie();
case "skeleton":
return new Skeleton();
case "demon":
return new Demon();
default:
throw new ArgumentException("未知的怪物类型");
}
}
}
客户端使用
class Program
{
static void Main(string[] args)
{
// 通过工厂创建怪物
IMonster monster1 = MonsterFactory.CreateMonster("zombie");
IMonster monster2 = MonsterFactory.CreateMonster("skeleton");
IMonster boss = MonsterFactory.CreateMonster("demon");
monster1.Attack(); // 输出:僵尸撕咬攻击!
monster2.Attack(); // 输出:骷髅弓箭射击!
boss.Attack(); // 输出:恶魔火焰喷射!
}
}
动态生成挂物军团
void GenerateMonsterArmy(int count)
{
string[] types = { "zombie", "skeleton", "demon" };
Random rand = new Random();
for (int i = 0; i < count; i++)
{
string type = types[rand.Next(types.Length)];
IMonster monster = MonsterFactory.CreateMonster(type);
monster.Attack();
}
}
// 生成5个随机怪物
GenerateMonsterArmy(5);
抽象工厂模式
现在我们可以通过简单工厂模式创建不同的对象了。但是如果我们想要创建一个组合,比如:远程怪物有弓箭手、炮兵等。近战怪物有士兵、骷髅兵等。我们想创建一个组合了。
接下来我们有一个例子
1. 定义抽象产品接口
// 汉堡抽象类
public interface IHamburger {
void Describe();
}
// 薯条抽象类
public interface IFries {
void ShowCutStyle();
}
// 饮料抽象类
public interface IDrink {
void DisplayFlavor();
}
2. 创建具体产品类
// 美式风味组合
class AmericanBeefBurger : IHamburger {
public void Describe() => Console.WriteLine("美式厚牛肉汉堡");
}
class ThickCutFries : IFries {
public void ShowCutStyle() => Console.WriteLine("粗切波浪薯条");
}
class ColaDrink : IDrink {
public void DisplayFlavor() => Console.WriteLine("经典可乐");
}
// 日式风味组合
class JapaneseChickenBurger : IHamburger {
public void Describe() => Console.WriteLine("日式照烧鸡腿汉堡");
}
class ThinCutFries : IFries {
public void ShowCutStyle() => Console.WriteLine("细切直条薯条");
}
class GreenTeaDrink : IDrink {
public void DisplayFlavor() => Console.WriteLine("煎茶风味饮料");
}
3. 定义抽象工厂接口
public interface IFastFoodFactory {
IHamburger CreateHamburger();
IFries CreateFries();
IDrink CreateDrink();
}
4. 实现具体工厂类
class AmericanFoodFactory : IFastFoodFactory {
public IHamburger CreateHamburger() => new AmericanBeefBurger();
public IFries CreateFries() => new ThickCutFries();
public IDrink CreateDrink() => new ColaDrink();
}
class JapaneseFoodFactory : IFastFoodFactory {
public IHamburger CreateHamburger() => new JapaneseChickenBurger();
public IFries CreateFries() => new ThinCutFries();
public IDrink CreateDrink() => new GreenTeaDrink();
}
5. 客户端使用
class RestaurantSimulator {
// 通过抽象工厂接口操作
private IFastFoodFactory _factory;
public RestaurantSimulator(IFastFoodFactory factory) {
_factory = factory;
}
public void PrepareMeal() {
var burger = _factory.CreateHamburger();
var fries = _factory.CreateFries();
var drink = _factory.CreateDrink();
burger.Describe();
fries.ShowCutStyle();
drink.DisplayFlavor();
}
}
// 使用示例
var americanRestaurant = new RestaurantSimulator(new AmericanFoodFactory());
americanRestaurant.PrepareMeal();
/* 输出:
美式厚牛肉汉堡
粗切波浪薯条
经典可乐 */
var japaneseRestaurant = new RestaurantSimulator(new JapaneseFoodFactory());
japaneseRestaurant.PrepareMeal();
/* 输出:
日式照烧鸡腿汉堡
细切直条薯条
煎茶风味饮料 */
评论区