ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

浅谈设计模式和其Unity中的应用:二、工厂模式

2022-01-03 13:02:20  阅读:263  来源: 互联网

标签:case 浅谈 res 子弹 break Unity Func 设计模式 public


目录

什么是工厂模式

工厂模式(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);
}

工厂模式的升级——抽象工厂模式

下一篇文章我们来进一步优化工厂模式:抽象工厂模式

标签:case,浅谈,res,子弹,break,Unity,Func,设计模式,public
来源: https://blog.csdn.net/qq_52855744/article/details/122285783

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有