比如我们想生产两种饮料(农夫山泉和脉动),在不使用任何设计模式时是这样的:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
Drink drink1 = Instantiate("农夫山泉");
Drink drink2 = Instantiate("脉动");
}
private Drink Instantiate(string type)
{
Drink Drink = null;
if (type.Equals("农夫山泉"))
{
Drink = new NongFuShanQuan();
}
else if (type.Equals("脉动"))
{
Drink = new MaiDong();
}
return Drink;
}
}
public class Drink
{
public int Id;
public string content;
/// <summary>
/// 构造函数创建饮料实体
/// </summary>
public Drink()
{
GameObject g = new GameObject(this.GetType().FullName);
}
}
public class NongFuShanQuan : Drink
{
public NongFuShanQuan()
{
Id = 1;
content = "500mL";
}
}
public class MaiDong : Drink
{
public MaiDong()
{
Id = 2;
content = "450mL";
}
}
我们把饮料对象的创建工作放在了Instantiate方法中,通过传入的参数来确定要创建的饮料对象。简单工厂模式将Instantiate方法中的内容封装到一个新的简单工厂类中。如此我们便可以通过简单工厂类来创建各种饮料。当需要增加饮料品种时,只需要在简单工厂类里面做修改。(加上新的具体饮料类是都要处理的)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
DrinkFactory factory = new DrinkFactory();
factory.Instantiate("农夫山泉");
factory.Instantiate("脉动");
}
}
public class DrinkFactory
{
public Drink Instantiate(string type)
{
Drink Drink = null;
if (type.Equals("农夫山泉"))
{
Drink = new NongFuShanQuan();
}
else if (type.Equals("脉动"))
{
Drink = new MaiDong();
}
return Drink;
}
}
public class Drink
{
public int Id;
public string content;
/// <summary>
/// 构造函数创建饮料实体
/// </summary>
public Drink()
{
GameObject g = new GameObject(this.GetType().FullName);
}
}
public class NongFuShanQuan : Drink
{
public NongFuShanQuan()
{
Id = 1;
content = "500mL";
}
}
public class MaiDong : Drink
{
public MaiDong()
{
Id = 2;
content = "450mL";
}
}
但是增加新的饮料品种我们觉得要修改的地方还是太多了,这样可拓展性比较差,于是工厂方法模式来了
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
DrinkFactory nongfushanquanfactory = new NongFuShanQuanFactory();
DrinkFactory maidongfactory = new MaiDongnFactory();
Drink nongfushanqaun = nongfushanquanfactory.Instantiate();
Drink maidong = maidongfactory.Instantiate();
}
}
public abstract class DrinkFactory
{
public abstract Drink Instantiate();
}
public class NongFuShanQuanFactory : DrinkFactory
{
public override Drink Instantiate()
{
return new NongFuShanQuan();
}
}
public class MaiDongnFactory : DrinkFactory
{
public override Drink Instantiate()
{
return new MaiDong();
}
}
public class Drink
{
public int Id;
public string content;
/// <summary>
/// 构造函数创建饮料实体
/// </summary>
public Drink()
{
GameObject g = new GameObject(this.GetType().FullName);
}
}
public class NongFuShanQuan : Drink
{
public NongFuShanQuan()
{
Id = 1;
content = "500mL";
}
}
public class MaiDong : Drink
{
public MaiDong()
{
Id = 2;
content = "450mL";
}
}
工厂方法模式核心是专业的工厂生产专业的饮料,简单来讲就是脉动厂只生产脉动饮料,农夫山泉厂只生产农夫山泉。因此我们需要加入新的具体工厂类,并且各自实现父类工厂的生产方法。
但是一个工厂只生产一种饮料太奢侈了,我要生产两个或多个,而且我要开放生产每种饮料的方法,让客户自己选择。于是抽象工厂模式来了:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
public class Test : MonoBehaviour
{
void Start()
{
Factory factory = new DrinkFactory();
Drink maidong = factory.CreateMaiDong();
Drink nongfushanquan = factory.CreateNongFuShanQuan();
Factory otherfactory = new OtherDrinkFactory();
Drink coco = otherfactory.CreateMaiDong();
Drink bear = otherfactory.CreateNongFuShanQuan();
}
}
public class Drink
{
public int Id;
public string content;
public Drink()
{
GameObject g = new GameObject(this.GetType().FullName);
}
}
public abstract class Factory
{
public abstract Drink CreateMaiDong();
public abstract Drink CreateNongFuShanQuan();
}
public class DrinkFactory : Factory
{
public override Drink CreateMaiDong()
{
return new MaiDong();
}
public override Drink CreateNongFuShanQuan()
{
return new NongFuShanQuan();
}
}
public class OtherDrinkFactory : Factory
{
public override Drink CreateMaiDong()
{
return new MaiDong_600();
}
public override Drink CreateNongFuShanQuan()
{
return new NongFuShanQuan_1000();
}
}
public class NongFuShanQuan : Drink
{
public NongFuShanQuan()
{
Id = 1;
content = "500mL";
}
}
public class MaiDong : Drink
{
public MaiDong()
{
Id = 2;
content = "450mL";
}
}
public class NongFuShanQuan_1000 : Drink
{
public NongFuShanQuan_1000()
{
Id = 3;
content = "1000mL";
}
}
public class MaiDong_600 : Drink
{
public MaiDong_600()
{
Id = 4;
content = "600mL";
}
}
工厂方法和抽象工厂非常相似,主要区别在于抽象工厂在具体工厂类中封装的是多个实例的创建方法,新增的工厂类可以重写这些方法并且可以在这些方法中自由选择产品。
如果用工厂方法模式需要一个脉动厂和农夫山泉厂,脉动厂只负责创建脉动对象,农夫山泉厂只负责创建农夫山泉对象
而使用抽象工程模式只需要一个饮料厂,该饮料厂既负责创建脉动,也负责创建农夫山泉,当然也可以负责创建需要的其他饮料。