目录
什么是工厂模式
工厂模式(Factory Pattern)是 最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
关于具体的概念给个链接:工厂模式概念
具体场景
比如我们现在有一个工厂生成电脑,有Dell的,ASUS的,Acer的。用户需要购买电脑,工厂需要生产电脑,但是用户购买的电脑是有三种的,比如我们用户说想要Dell的就必须给他一个Dell的电脑。那这种情况就可以用工厂模式来解决。用户给需求(需要生产的电脑的名字),工厂生产(实例化具体是什么电脑),生产完用返回值返回给调用者(电脑生产完送到用户手里)。
怎么实现工厂模式(C#实现)
步骤一
首先应该有一个电脑接口
public interface Computer {
void Func();
}
步骤二
然后有具体的电脑,创建实现接口的实体类。
public class Dell : Computer {
public override void Func()
{
}
}
public class ASUS: Computer {
public override void Func()
{
}
}
public class Acer: Computer {
public override void Func()
{
}
}
步骤三
创建一个工厂,生成基于给定信息的实体类的对象。
public class Factory {
//使用 getShape 方法获取形状类型的对象
public Computer GetComputer(string computerName)
{
if(computerName == null)
{
result = null;
}
Computer result = null;
switch(computerName)
{
case: "Dell":
result = new Dell();
break;
case: "ASUS":
result = new ASUS();
break;
case: "Acer":
result = new Acer();
break;
default:
result = null;
break;
}
return result;
}
}
步骤四
使用该工厂,通过传递类型信息来获取实体类的对象。
public class FactoryPatternDemo
{
public static void Main(String[] args) {
Factory factory = new Factory();
//获取 Dell 的对象,并调用它的 Func 方法
Computer dell = factory.GetComputer("Dell");
//调用 Dell 的 Func 方法
dell.Func();
//获取 ASUS 的对象,并调用它的 Func 方法
Computer asus = factory.GetComputer("ASUS");
//调用 ASUS 的 Func 方法
asus.Func();
//获取 Acer 的对象,并调用它的 Func 方法
Computer acer = factory.GetComputer("Acer");
//调用 Acer 的 Func 方法
acer.Func();
}
}
在Unity中的应用(单例模式+对象池+工厂模式)
关于单例模式可以看看我的上一篇文章:浅谈设计模式和其Unity中的应用:一、单例模式
关于对象池可以看看我的这一篇文章:Unity射击游戏发射子弹的方法和提升流畅性的小技巧
具体场景
比如有一个射击游戏,有很多枪械:手枪、步枪、散弹枪、狙击步枪、冲锋枪等等,每把武器都有自己的子弹。
我们在射击的时候可以拜托工厂来创建子弹,然后返回。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletFactory : Singleton<BulletFactory>, BaseFactory
{
//步枪子弹对象池
private Stack<BulletController> m_rifleBulletPool = new Stack<BulletController>();
//狙击步枪子弹对象池
private Stack<BulletController> m_sniperBulletPool = new Stack<BulletController>();
//手枪子弹对象池
private Stack<BulletController> m_handGunBulletPool = new Stack<BulletController>();
//散弹枪子弹对象池
private Stack<BulletController> m_shotGunBulletPool = new Stack<BulletController>();
//冲锋枪子弹对象池
private Stack<BulletController> m_sMGBulletPool = new Stack<BulletController>();
//步枪子弹预制体
public BulletController AssaultRifleBulletPrefab;
//狙击步枪子弹预制体
public BulletController SniperBulletBulletPrefab;
//手枪子弹预制体
public BulletController HandGunBulletPrefab;
//散弹枪子弹预制体
public BulletController ShotGunBulletPrefab;
//冲锋枪子弹预制体
public BulletController SMGBulletPrefab;
protected override void Awake()
{
base.Awake();
DontDestroyOnLoad(this);
}
/// <summary>
/// 创建子弹时调用
/// </summary>
/// <param name="produceName">子弹名称:AssaultRifle、Sniper、Handgun、SMG、ShotGun</param>
/// <returns>子弹</returns>
public Component Creat(string produceName)
{
BulletController res = null;
switch (produceName)
{
case "AssaultRifle":
if(m_rifleBulletPool.Count >= 1)
{
res = m_rifleBulletPool.Pop();
}
else
{
res = Instantiate(AssaultRifleBulletPrefab);
}
break;
case "Sniper":
if (m_sniperBulletPool.Count >= 1)
{
res = m_sniperBulletPool.Pop();
}
else
{
res = Instantiate(SniperBulletBulletPrefab);
}
break;
case "Handgun":
if (m_handGunBulletPool.Count >= 1)
{
res = m_handGunBulletPool.Pop();
}
else
{
res = Instantiate(HandGunBulletPrefab);
}
break;
case "SMG":
if (m_sMGBulletPool.Count >= 1)
{
res = m_sMGBulletPool.Pop();
}
else
{
res = Instantiate(SMGBulletPrefab);
}
break;
case "ShotGun":
if (m_shotGunBulletPool.Count >= 1)
{
res = m_shotGunBulletPool.Pop();
}
else
{
res = Instantiate(ShotGunBulletPrefab);
}
break;
default:
break;
}
res.gameObject.SetActive(true);
return res.transform;
}
/// <summary>
/// 创建子弹时调用
/// </summary>
/// <param name="produceName">子弹名称:AssaultRifle、Sniper、Handgun、SMG、ShotGun</param>
/// <param name="position">子弹位置</param>
/// <param name="rotation">子弹旋转</param>
/// <returns>子弹</returns>
public Component Creat(string produceName, Vector3 position, Quaternion rotation)
{
Component go = Creat(produceName);
go.transform.position = position;
go.transform.rotation = rotation;
return go;
}
/// <summary>
/// 子弹重新加入对象池调用
/// </summary>
/// <param name="produceName">子弹名称:AssaultRifle、Sniper、Handgun、SMG、ShotGun</param>
/// <param name="go">子弹</param>
public void RecoveryGameObjectToPool(string produceName, Component go)
{
switch (produceName)
{
case "AssaultRifle":
m_rifleBulletPool.Push(go as BulletController);
break;
case "Sniper":
m_sniperBulletPool.Push(go as BulletController);
break;
case "Handgun":
m_handGunBulletPool.Push(go as BulletController);
break;
case "SMG":
m_shotGunBulletPool.Push(go as BulletController);
break;
case "ShotGun":
m_sMGBulletPool.Push(go as BulletController);
break;
default:
break;
}
go.gameObject.SetActive(false);
}
}
调用方法
public void CreatBullet(string bulletName)
{
Component bullet = BulletFactory.Ins.Creat(bulletName);
}
工厂模式的升级——抽象工厂模式
下一篇文章我们来进一步优化工厂模式:抽象工厂模式