目录
抽象工厂模式
思维导图
接口(抽象类)
工厂接口
抽象产品类
抽象武器接口
抽象人物接口
具体工厂和具体产品
具体工厂
(1)产品接口,生成具体人物
(2)武器接口,生成具体武器
具体产品的实现
Soldier类型
ShotGunA 类型
单例模式资源加载
测试
GameController
PerformanceTest
抽象工厂模式
思维导图
一个工厂里面可以生产多个产品
一个工厂可以生产一系列产品(一族产品),极大减少了工厂类的数量
接口(抽象类)
工厂接口
在工厂里声明创造的武器和产品
武器:创造武器方法创造具体的武器
人物:创造产品方法创造具体的人物
public interface IGameFactory
{
IWeapon GreateWeapon();
ICharacter CreateCharacter();
}
抽象产品类
抽象武器接口
用来生产不同的武器,武器类型
/// <summary>
/// 抽象武器接口-抽象产品
/// </summary>
public interface IWeapon
{
void Use();//使用武器
void Display();//显示武器
}
抽象人物接口
用来生成不同的产品,人物类型
/// <summary>
/// 抽象产品
/// </summary>
public interface ICharacter
{
void Display();//显示模型
}
具体工厂和具体产品
现代风格的具体工厂,返回具体的产品
具体工厂
(1)产品接口,生成具体人物
返回要生成的产品,Soldier类型
(2)武器接口,生成具体武器
public class ModernGameFactory : IGameFactory
{
public ICharacter CreateCharacter()
{
return new Soldier();
}
public IWeapon GreateWeapon()
{
return new ShotGunA();
}
}
具体产品的实现
Soldier类型
实现ICharacter接口,生产具体的人物
/// <summary>
/// 具体产品---士兵
/// </summary>
public class Soldier : ICharacter
{
private GameObject _model;
public Soldier()
{
_model = ResourceManager.Instance.GetResource("Bot/SoldierA");
}
public void Display()
{
if (_model != null)
{
GameObject.Instantiate(_model);
}
else
{
Debug.LogError("Soldier model not found");
}
}
}
ShotGunA 类型
ShotGunA产品的生产
实现IWeapon接口
public class ShotGunA : IWeapon
{
private GameObject _model;
public ShotGunA()
{
_model = ResourceManager.Instance.GetResource("Weapon/LaserGun_A");
}
public void Display()
{
if (_model != null)
{
GameObject.Instantiate(_model);
}
else
{
Debug.LogError("ShotGunA model not found");
}
}
public void Use()
{
Debug.Log("使用武器");
}
}
单例模式资源加载
单例模式(Singleton Pattern):是一种创建对象的设计模式,确保一个类只有一个实例,并提供全局访问点。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 单例模式
/// </summary>
public class ResourceManager
{
//本类实例的引用
private static ResourceManager _instance;
//资源缓存器
private Dictionary<string, GameObject> _resourceCache = new Dictionary<string, GameObject>();
//为私有的字段准备的属性
public static ResourceManager Instance
{
get
//保证有且只有一个实例
{
if (_instance == null)
{
_instance = new ResourceManager();
}
return _instance;
}
}
//获取资源的工作代码,从硬盘或者缓存中获取模型资源
//传入路径path
public GameObject GetResource(string path)
{
//询问资源存储器中是否包含当前路径(不需要重复加载)
if (!_resourceCache.ContainsKey(path))
{
GameObject resource = Resources.Load<GameObject>(path);
if (resource == null)
{
Debug.LogError($"Failed to load resource at path: {path}");
return null;
}
_resourceCache[path] = resource;
}
return _resourceCache[path];
}
}
测试
GameController
建个空物体挂上即可
功能:创建产品进行测试
public class GameController : MonoBehaviour
{
private ICharacter _character;
private IWeapon _weapon;
public void StartGame(IGameFactory factory)
{
try
{
_character = factory.CreateCharacter();
_weapon = factory.GreateWeapon();
_character.Display();
_weapon.Use();
}
catch (System.Exception e)
{
Debug.LogError($"Error starting game: {e.Message}");
}
}
}
PerformanceTest
建个空物体挂上即可
功能:测试用抽象工厂模式创建物体和直接实例化物体的时间性能区别
(直接创建会快)
public class PerformanceTest : MonoBehaviour
{
private void Start()
{
//TestDirectInstantiation(500);
TestFactoryPattern(500);
}
//直接实例化
void TestDirectInstantiation(int count)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
List<GameObject> objects = new List<GameObject>();
GameObject prefab = Resources.Load<GameObject>("Bot/SoldierA");
for (int i = 0; i < count; i++)
{
objects.Add(GameObject.Instantiate(prefab));
}
stopwatch.Stop();
UnityEngine.Debug.Log($"Direct Instantiation ({count} objects): {stopwatch.ElapsedMilliseconds} ms");
// Clean up
foreach (var obj in objects)
{
GameObject.Destroy(obj);
}
objects.Clear();
Resources.UnloadUnusedAssets();
}
//抽象工厂的实例化测试
void TestFactoryPattern(int count)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
IGameFactory factory = new ModernGameFactory();
List<ICharacter> characters = new List<ICharacter>();
for (int i = 0; i < count; i++)
{
characters.Add(factory.CreateCharacter());
characters[i].Display();
}
stopwatch.Stop();
UnityEngine.Debug.Log($"Factory Pattern ({count} objects): {stopwatch.ElapsedMilliseconds} ms");
//Clean up
characters.Clear();
Resources.UnloadUnusedAssets();
}
}