Unity에서 사용되는 디자인 패턴(싱글톤 패턴, 옵저버 패턴, 팩토리 패턴, 전략 패턴, 조합 패턴)

1. 싱글톤 모드: 클래스의 인스턴스가 하나만 있는지 확인하고 전역 액세스 포인트를 제공합니다. 싱글톤 모드를 사용하면 리소스를 절약하고 여러 인스턴스 생성으로 인한 불필요한 오버헤드를 피할 수 있습니다.
1. 제네릭을 사용하여 제네릭 싱글톤 스크립트 생성(마운트할 수 없음)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//where如果约束为MonoBehaviour,则T可以是派生子MonoBehaviour的组件或脚本
public class SingleMono<T> : MonoBehaviour where T:new()
{
    private static T instance;
    public static T Instance
    {
        get
        {
            if(instance == null) instance = new T();
            return instance;
        }
    }
}

2. 싱글톤 스크립트를 생성하기 위해 제네릭을 사용하지 마십시오.
(1) 진정한 싱글톤: 다중 스레드 환경에서 하나의 인스턴스 개체만 있고 스레드로부터 안전함(여러 시나리오에서 호출 가능)이 보장됩니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RealSingle
{
    private static RealSingle instance;
    public static RealSingle Instance
    {
        get
        {
            if(instance == null)
            {
                instance = new RealSingle();
            }
            return instance;
        }
    }
}

(2) Pseudo-singleton: 단일 스레드 환경에서 사용하기에 적합하며 다중 스레드 환경에서는 여러 인스턴스 개체가 생성될 가능성이 높습니다(MonoBehaviour를 상속하므로 장면 간에 호출할 수 없음).

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FakeSingle : MonoBehaviour
{
    public static FakeSingle instance;
    private void Awake()
    {
        instance = this;
    }
}

추가 콘텐츠: 싱글톤 모드 | 루키 튜토리얼

2. 관찰자 모드: 일대다 종속 관계를 정의하여 여러 관찰자 개체가 동시에 특정 주체 개체를 모니터링할 수 있도록 합니다.주체 개체의 상태가 변경되면 모든 종속 개체(관찰자)는 알림을 받고 자동 업데이트

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObserverDemo : MonoBehaviour
{
    public delegate void CallBack(object param);
    public event CallBack callBackEvent;
    Dictionary<int,List<CallBack>> dicEvent=new Dictionary<int,List<CallBack>>();
    //添加事件方法
    public void AddEvent(int eventID,CallBack callBack)
    {
        if(!dicEvent.ContainsKey(eventID))
        {
            List<CallBack> list = new List<CallBack>();
            list.Add(callBack);
            dicEvent.Add(eventID, list);
            callBackEvent += callBack;
        }
        else
        {
            if (!dicEvent[eventID].Contains(callBack))
            {
                dicEvent[eventID].Add(callBack);
                callBackEvent += callBack;
            }
            else
            {
                return;
            }
        }
    }
    //删除事件方法
    public void DelEvent(int eventID,CallBack callBack)
    {
        if(!dicEvent.ContainsKey(eventID)) return;
        if (!dicEvent[eventID].Contains(callBack)) return;
        dicEvent[eventID].Remove(callBack);
        callBackEvent -= callBack;
        if (dicEvent[eventID].Count==0)
        {
            dicEvent.Remove(eventID);
        }
    }
    //通过委托来通知某个eventID下的CallBack组
    public void SendEvent(int eventID,object param)
    {
        if (dicEvent[eventID].Count>0)
        {
            foreach(var item in dicEvent[eventID])
            {
                item(param);
            }
        }
    }
    //通过事件来通知所有CallBack
    public void SendAllEvent(object param)
    {
        callBackEvent(param);
    }
    private void Start()
    {
        AddEvent(0,Show);
        object temp=null;
        SendEvent(0, temp);
        SendAllEvent(temp);
        DelEvent(0, Show);
    }
    void Show(object param)
    {
        Debug.Log("更新");
    }
}

추가 콘텐츠: 관찰자 패턴 | 초보자 자습서

3. 팩토리 모드: 코드에서 직접 객체를 생성하는 대신 팩토리 클래스를 정의하여 객체를 생성합니다. 개체 생성의 세부 정보를 숨길 수 있으므로 코드를 보다 유연하고 유지 관리할 수 있습니다.


추상 클래스: 인스턴스화할 수 없습니다. 추상메서드와 비추상메서드를 포함할 수 있으며, 추상메서드에 메소드 본체가 없을 수 있음 추상클래스가 상속되면 추상클래스의 추상메소드를 구현해야 함(단, 추상클래스를 상속받은 추상클래스는 제외) ).인터페이스: 참조 유형에 속합니다
. 인스턴스화할 수 없고 특성 필드를 포함할 수 없으며 메서드 선언만 작성할 수 있으며 메서드 본문이 있는 메서드를 가질 수 없습니다. 일단 상속되면 인터페이스의 모든 메서드 선언을 구현해야 합니다(인터페이스에서 상속하는 인터페이스 제외).

(1) 단순 팩토리 패턴: 모든 객체를 생성하는 팩토리 클래스는 하나뿐입니다. 융통성이 없고 확장할 수 없습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FactoryDemo : MonoBehaviour
{
    private void Start()
    {
        Factory factory = GetComputer(Computer.Lenovo);
        factory.FactoryObject();
        factory = GetComputer(Computer.Huawei);
        factory.FactoryObject();
    }
    public Factory GetComputer(Computer com)
    {
        Factory factory = null;
        switch (com)
        {
            case Computer.Lenovo:factory = new Lenovo();break;
            case Computer.Huawei: factory = new HuaWei(); break;
            default: Debug.Log("工厂无法生产"); break;
        }
        return factory;
    }
}
public enum Computer {Lenovo,Huawei}
public abstract class Factory
{
    public string name = "电脑";
    //虚函数可重写可不重写
    public virtual void FactoryObject()
    {
        Debug.Log("生产" + name);
    }
}
class Lenovo:Factory
{
    public Lenovo()
    {
        name = "联想";
    }
}
class HuaWei:Factory
{
    public HuaWei()
    {
        name = "华为";
    }
}

(2) 복잡한 팩토리 패턴: 일반적으로 다양한 종류의 객체를 생성하기 위해 여러 팩토리 클래스가 있습니다. 확장 및 수정 용이

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ComplexFactoryDemo : MonoBehaviour
{
    private void Start()
    {
        FactoryElectronics factory = new Factory1();
        factory.CreateComputer().GetInfo();
        factory.CreatePhone().CallInfo();
        factory=new Factory2();
        factory.CreateComputer().GetInfo();
        factory.CreatePhone().CallInfo();
    }
}
interface IElectronics
{
    void SameInfo();
}
interface IComputer : IElectronics
{
    void GetInfo();
}
interface IPhone : IElectronics
{
    void CallInfo();
}
class LenoveComputer : IComputer
{
    public void GetInfo()
    {
        Debug.Log("联想电脑");
    }

    public void SameInfo()
    {
        Debug.Log("这是电子产品");
    }
}
class AppleComputer : IComputer
{
    public void GetInfo()
    {
        Debug.Log("苹果电脑");
    }

    public void SameInfo()
    {
        Debug.Log("这是电子产品");
    }
}
class HuaWei : IPhone
{
    public void CallInfo()
    {
        Debug.Log("华为手机");
    }

    public void SameInfo()
    {
        Debug.Log("这是电子产品");
    }
}
class Apple : IPhone
{
    public void CallInfo()
    {
        Debug.Log("苹果手机");
    }

    public void SameInfo()
    {
        Debug.Log("这是电子产品");
    }
}
interface FactoryElectronics
{
    IComputer CreateComputer();
    IPhone CreatePhone();
}
class Factory1 : FactoryElectronics
{
    public IComputer CreateComputer()
    {
        return new LenoveComputer();
    }

    public IPhone CreatePhone()
    {
        return new HuaWei();
    }
}
class Factory2 : FactoryElectronics
{
    public IComputer CreateComputer()
    {
        return new AppleComputer();
    }

    public IPhone CreatePhone()
    {
        return new Apple();
    }
}

추가 콘텐츠: 공장 패턴 | 루키 튜토리얼

4. 전략 모드: 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있도록 알고리즘 구현에서 알고리즘 선택을 분리합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StrategyDemo : MonoBehaviour
{
    private void Start()
    {
        PeopleAttack peopleAttack = new PeopleAttack();
        peopleAttack.hitDamage(new Weapon1()).HitAttack();
    }
}
interface WeaponSkill
{
    void HitAttack();
}
class Weapon1 : WeaponSkill
{
    public void HitAttack()
    { Debug.Log("攻击距离1"); }
}
class Weapon2 : WeaponSkill
{
    public void HitAttack()
    { Debug.Log("攻击距离2"); }
}

class Weapon3 : WeaponSkill
{
    public void HitAttack()
    { Debug.Log("攻击距离3");}
}
class PeopleAttack
{
    public WeaponSkill hitDamage(WeaponSkill weaponSkill)
    {
        weaponSkill = new Weapon3();
        return weaponSkill;
    }
}

추가 콘텐츠: 전략 모드 | 초보자 튜토리얼

5. 조합모드 : 개체의 조합을 마치 하나의 개체인 것처럼 처리할 수 있도록 하여 사용자가 개체를 사용할 때 개체와 조합의 차이를 무시할 수 있음

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CompositeDemo : MonoBehaviour
{
    private void Start()
    {
        //就是给某些物体加多个或给另外一些物体加一个
        this.gameObject.AddComponent<RunInfo>();
        this.gameObject.AddComponent<RunInfo>();
    }
}
public class RunInfo:MonoBehaviour
{ public void Run() { } }
public class WalkInfo : MonoBehaviour
{ public void Walk() { } }
public class JumpInfo : MonoBehaviour
{ public void Jump() { } }

추가 콘텐츠: 콤비네이션 모드 | 초보자 튜토리얼

결론: 품는 나무는 머리카락 끝에서 태어나고, 구층대는 흙더미에서 시작되며, 천리 길도 한 걸음부터 시작된다.

Supongo que te gusta

Origin blog.csdn.net/falsedewuxin/article/details/130197650
Recomendado
Clasificación