Общие шаблоны проектирования разработки в Unity

Ниже приводится подробное введение в распространенные шаблоны проектирования разработки в Unity:

одноэлементный шаблон

представлять

Одноэлементный шаблон — это распространенный шаблон проектирования, который гарантирует, что класс имеет только один экземпляр, и предоставляет глобальную точку доступа для доступа к этому экземпляру.

метод

Метод реализации одноэлементного режима заключается в приватизации конструктора класса, чтобы экземпляр класса нельзя было создать с помощью нового ключевого слова. Затем определите статический метод в классе, чтобы получить единственный экземпляр класса, и, если экземпляр не существует, создайте новый экземпляр и верните его.

например

Вот пример класса GameManager, реализованного с использованием шаблона singleton:

public class GameManager
{
    
    
    private static GameManager instance;

    private GameManager() {
    
     }

    public static GameManager Instance
    {
    
    
        get
        {
    
    
            if (instance == null)
            {
    
    
                instance = new GameManager();
            }
            return instance;
        }
    }

    public void StartGame()
    {
    
    
        // ...
    }

    public void EndGame()
    {
    
    
        // ...
    }
}

В приведенном выше примере конструктор класса GameManager сделан закрытым, а свойство Instance предоставляет глобальную точку доступа к единственному экземпляру GameManager. Другие классы могут обращаться к экземплярам GameManager через GameManager.Instance и вызывать его общедоступные методы.

заводской узор

представлять

Фабричный шаблон — это распространенный шаблон проектирования, который делегирует создание объектов классу фабрики, тем самым отделяя клиентский код от создания экземпляров конкретных классов.

метод

Метод реализации фабричного шаблона заключается в определении абстрактного фабричного класса или интерфейса и объявлении фабричного метода для создания в нем объектов. Затем создайте конкретный фабричный класс для реализации фабричного метода, который будет создавать экземпляр объекта конкретного класса и возвращать его. Клиентскому коду нужно только вызвать фабричный метод, чтобы получить желаемый объект, не создавая экземпляр конкретного класса напрямую.

например

Вот пример класса EnemyFactory, реализованного с использованием шаблона factory:

public abstract class Enemy
{
    
    
    public abstract void Attack();
}

public class Slime : Enemy
{
    
    
    public override void Attack()
    {
    
    
        // ...
    }
}

public class Goblin : Enemy
{
    
    
    public override void Attack()
    {
    
    
        // ...
    }
}

public abstract class EnemyFactory
{
    
    
    public abstract Enemy CreateEnemy();
}

public class SlimeFactory : EnemyFactory
{
    
    
    public override Enemy CreateEnemy()
    {
    
    
        return new Slime();
    }
}

public class GoblinFactory : EnemyFactory
{
    
    
    public override Enemy CreateEnemy()
    {
    
    
        return new Goblin();
    }
}

В приведенном выше примере Enemy — это абстрактный базовый класс, а Slime и Goblin — конкретные подклассы. EnemyFactory — это абстрактный фабричный класс, а SlimeFactory и GoblinFactory — конкретные фабричные классы, которые соответственно реализуют метод CreateEnemy и возвращают экземпляры Slime и Goblin. Клиентский код может использовать EnemyFactory для создания желаемых объектов Enemy без непосредственного создания экземпляров Slime или Goblin.

Шаблон наблюдателя

представлять

Режим наблюдателя — это общий шаблон проектирования, который определяет зависимость «один ко многим», позволяя нескольким объектам-наблюдателям одновременно отслеживать объект-субъект, когда объект-субъект изменяется, все его наблюдатели получают уведомления и обновления.

метод

Шаблон наблюдателя реализуется путем определения объекта-субъекта, который поддерживает список наблюдателей и предоставляет методы для регистрации и уведомления наблюдателей. Объекты-наблюдатели реализуют метод обновления, который вызывается при изменении объекта-субъекта. Клиентский код может отслеживать изменение предметного объекта, регистрируя наблюдателя, и выполнять соответствующие операции в методе обновления.

например

Ниже приведен пример классов Subject и Observer, реализованных с использованием шаблона Observer:

using System;
using System.Collections.Generic;

public class Subject
{
    
    
    private List<Observer> observers = new List<Observer>();

    public void Attach(Observer observer)
    {
    
    
        observers.Add(observer);
    }

    public void Detach(Observer observer)
    {
    
    
        observers.Remove(observer);
    }

    public void Notify()
    {
    
    
        foreach (Observer observer in observers)
        {
    
    
            observer.Update();
        }
    }
}

public abstract class Observer
{
    
    
    protected Subject subject;

    public Observer(Subject subject)
    {
    
    
        this.subject = subject;
    }

    public abstract void Update();
}

public class ConcreteObserver : Observer
{
    
    
    public ConcreteObserver(Subject subject) : base(subject) {
    
     }

    public override void Update()
    {
    
    
        // ...
    }
}

В приведенном выше примере Subject — это субъектный класс, который поддерживает список наблюдателей и предоставляет методы Attach, Detach и Notify для регистрации, отмены регистрации и уведомления наблюдателей. Observer — это абстрактный класс наблюдателя, а ConcreteObserver — конкретный класс наблюдателя, реализующий метод обновления. Клиентский код может прослушивать изменения в объекте субъекта, создавая экземпляр ConcreteObserver и регистрируя его в субъекте.

модель делегирования

представлять

Шаблон делегата — это распространенный шаблон проектирования, в котором объекты делегата используются для представления функций и передачи их в качестве параметров другим функциям. Это организует код в более мелкие модули, что упрощает его обслуживание и повторное использование.

метод

Шаблон делегата реализуется путем определения типа делегата и передачи его в качестве параметра другим функциям. Другие функции могут передать свою реализацию объекту делегата, тем самым вызывая функцию, представленную объектом делегата.

например

Вот пример класса EventHandler, реализованного с использованием шаблона делегата:

public delegate void EventHandler();

public class EventPublisher
{
    
    
    public event EventHandler OnEvent;

    public void RaiseEvent()
    {
    
    
        if (OnEvent != null)
        {
    
    
            OnEvent();
        }
    }
}

public class EventSubscriber
{
    
    
    public void HandleEvent()
    {
    
    
        // ...
    }
}

В приведенном выше примере EventHandler — тип делегата, EventPublisher — класс издателя событий, который определяет событие OnEvent и запускает событие в методе RaiseEvent. EventSubscriber — это класс подписчика событий, который определяет метод HandleEvent, который может быть реализован как делегат EventHandler. Клиентский код может создавать экземпляры EventPublisher и EventSubscriber и передавать метод HandleEvent EventSubscriber событию OnEvent EventPublisher, тем самым реализуя шаблон делегирования.

режим состояния

представлять

Шаблон состояния — это общий шаблон проектирования, который разделяет поведение и состояние объекта, чтобы изменения в состоянии не влияли напрямую на поведение объекта.

метод

Метод реализации шаблона состояния заключается в определении абстрактного класса состояния и нескольких конкретных классов состояния, каждый конкретный класс состояния представляет определенное состояние и реализует набор методов, определенных в классе абстрактного состояния. Затем определите класс контекста, который содержит переменные-члены класса абстрактного состояния, которые представляют текущее состояние, и реализуйте набор методов в классе контекста для переключения состояний и вызова методов текущего состояния.

например

Вот пример классов PlayerState и Player, реализованных с использованием шаблона State:

public abstract class PlayerState
{
    
    
    protected Player player;

    public PlayerState(Player player)
    {
    
    
        this.player = player;
    }

    public abstract void Move();

    public abstract void Jump();

    public abstract void Attack();
}

public class IdleState : PlayerState
{
    
    
    public IdleState(Player player) : base(player) {
    
     }

    public override void Move()
    {
    
    
        player.State = new RunState(player);
    }

    public override void Jump()
    {
    
    
        player.State = new JumpState(player);
    }

    public override void Attack()
    {
    
    
        // ...
    }
}

public class RunState : PlayerState
{
    
    
    public RunState(Player player) : base(player) {
    
     }

    public override void Move()
    {
    
    
        // ...
    }

    public override void Jump()
    {
    
    
        player.State = new JumpState(player);
    }

    public override void Attack()
    {
    
    
        // ...
    }
}

public class JumpState : PlayerState
{
    
    

Guess you like

Origin blog.csdn.net/qq_20179331/article/details/130607768