23种设计模式的Unity实现一一一命令模式/状态模式/观察者模式/中介者模式


游戏开发中常用的设计模式“单例模式”,“观察者模式”,“迭代器模式”,“访问者模式”。工厂

1.Command Pattern 命令模式

Definition

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. 
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持可撤消的操作。

Participants

The classes and objects participating in this pattern are:

Command

  • declares an interface for executing an operation

ConcreteCommand

  • defines a binding between a Receiver object and an action
  • implements Execute by invoking the corresponding operation(s) on Receiver

Client

  • creates a ConcreteCommand object and sets its receiver

Invoker

  • asks the command to carry out the request

Receiver



using UnityEngine;

using System.Collections;

using System.Collections.Generic;


namespace CommandPatternExample4
{
    public class CommandPatternExample4 : MonoBehaviour
    {
        void Start()
        {
            //创建命令管理者
            Invoker theInvoker = new Invoker();


            Command theCommand = null;
            // 结合命令与执行者
            theCommand = new ConcreteCommand1(new Receiver1(), "hi");
            theInvoker.AddCommand(theCommand);
            theCommand = new ConcreteCommand2(new Receiver2(), 666);
            theInvoker.AddCommand(theCommand);


            // 进行执行
            theInvoker.ExecuteCommand();
        }


    }




    /// <summary>
    /// 命令抽象类
    /// </summary>
    public abstract class Command
    {
        public abstract void Execute();
    }


    /// <summary>
    /// 实际命令1-绑定命令和receiver
    /// </summary>
    public class ConcreteCommand1 : Command
    {
        Receiver1 m_Receiver = null;
        string m_Command = "";


        public ConcreteCommand1(Receiver1 Receiver, string param)
        {
            m_Receiver = Receiver;
            m_Command = param;
        }


        public override void Execute()
        {
            m_Receiver.Action(m_Command);
        }
    }


    /// <summary>
    /// 实际命令2-绑定命令和receiver
    /// </summary>
    public class ConcreteCommand2 : Command
    {
        Receiver2 m_Receiver = null;
        int m_Param = 0;


        public ConcreteCommand2(Receiver2 Receiver, int Param)
        {
            m_Receiver = Receiver;
            m_Param = Param;
        }


        public override void Execute()
        {
            m_Receiver.Action(m_Param);
        }
    }


    /// <summary>
    /// 功能执行者1
    /// </summary>
    public class Receiver1
    {
        public Receiver1() { }
        public void Action(string param)
        {
            Debug.Log("Receiver1.Action:Command[" + param + "]");
        }
    }


    /// <summary>
    /// 功能执行者2
    /// </summary>
    public class Receiver2
    {
        public Receiver2() { }
        public void Action(int Param)
        {
            Debug.Log("Receiver2.Action:Param[" + Param.ToString() + "]");
        }
    }




    /// <summary>
    /// 命令管理者
    /// </summary>
    public class Invoker
    {
        List<Command> m_Commands = new List<Command>();


        // 加入命令
        public void AddCommand(Command theCommand)
        {
            m_Commands.Add(theCommand);
        }


        /// <summary>
        /// 执行命令
        /// </summary>
        public void ExecuteCommand()
        {
            // 执行
            foreach (Command theCommand in m_Commands)
                theCommand.Execute();
            // 清空 
            m_Commands.Clear();
        }
    }

}

2.State Pattern 状态模式

有限状态机/状态者模式 点击打开链接

Definition

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. 
当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。

Participants

The classes and objects participating in this pattern are:

Context (Account)

  • defines the interface of interest to clients
  • maintains an instance of a ConcreteState subclass that defines the current state.

State (State)

  • defines an interface for encapsulating the behavior associated with a particular state of the Context.

Concrete State (RedState, SilverState, GoldState)

  • each subclass implements a behavior associated with a state of Context

3.Observer Pattern 观察者模式

Definition

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

观察者的设计意图和作用是 它将对象与对象之间创建一种依赖关系,当其中一个对象发生变化时,它会将这个变化通知给与其创建关系的对象中,实现自动化的通知更新。

游戏中观察者的适用环境有

1:UI控件管理类。当我们的GUI控件都使用观察者模式后,那么用户的任何界面相关操作和改变都将会通知其关联对象-----我们的UI事件机。

2:动画管理器。很多时候我们在播放一个动画桢的时候,对其Frame有很大兴趣,此时我们设置一个FrameLister对象对其进行监视,获得我们关心的事件进行处理是必须的。

非程序语言描述

A是B的好朋友,对B的行为非常关心。B要出门,此时A给了B一个警报器,告诉B说:“如果你有事,立刻按这个警报器告诉我。”。结果B在外面遇上了麻烦,按下警报器(Update()),B就知道A出了事,于是就调查一下B到底遇到了什么麻烦(GetState()),当知道B原来是因为被人打了,于是立刻进行处理DisposeFun(),派了一群手下帮B打架。

当然关心A的人可以不止一个,C,D可能也对A很关心,于是A这里保存一个所有关心它的人的链表,当遇到麻烦的时候,轮流给每个人一份通知。



Participants

The classes and objects participating in this pattern are:

Subject (Stock)

  • knows its observers. Any number of Observer objects may observe a subject
  • provides an interface for attaching and detaching Observer objects.

ConcreteSubject (IBM)

  • stores state of interest to ConcreteObserver
  • sends a notification to its observers when its state changes

Observer (IInvestor)

  • defines an updating interface for objects that should be notified of changes in a subject.

ConcreteObserver (Investor)

  • maintains a reference to a ConcreteSubject object
  • stores state that should stay consistent with the subject's
  • implements the Observer updating interface to keep its state consistent with the subject's

概念:它将对象与对象之间创建一种依赖关系,当其中一个对象发生变化时,它会将这个变化通知给与其创建关系的对象中,实现自动化的通知更新。

在游戏开发中,比如UI上有一个下拉的List,我选择了其中的每一项,都会导致UI界面的变化,比如我选择“强化”,对应出现强化装备的界面;我选择“镶嵌”,就会出现镶嵌的界面。


//-------------------------------------------------------------------------------------
//	ObserverStructure.cs
//-------------------------------------------------------------------------------------


//[Definition]
//--------------------------------
// Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
// 
// [Participants]
//--------------------------------
//  The classes and objects participating in this pattern are:
// 
// Subject
//      knows its observers.Any number of Observer objects may observe a subject
//      provides an interface for attaching and detaching Observer objects.
// ConcreteSubject
//      stores state of interest to ConcreteObserver
//      sends a notification to its observers when its state changes
// Observer
//      defines an updating interface for objects that should be notified of changes in a subject.
// ConcreteObserver
//      maintains a reference to a ConcreteSubject object
//      stores state that should stay consistent with the subject's
//      implements the Observer updating interface to keep its state consistent with the subject's


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


public class ObserverStructure : MonoBehaviour
{
    void Start()
    {
        // Configure Observer pattern
        ConcreteSubject s = new ConcreteSubject();

        s.Attach(new ConcreteObserver(s, "X"));//此实例化的观察者,它观察的对象是s , 观察者的名字是 X 
        s.Attach(new ConcreteObserver(s, "Y"));
        s.Attach(new ConcreteObserver(s, "Z"));

        // Change subject and notify observers
        s.SubjectState = "ABC";
        s.Notify();
        // Change subject and notify observers again
        s.SubjectState = "666";
        s.Notify();
    }
}

/// <summary>
/// The 'Subject' abstract class
/// </summary>
abstract class Subject
    {
        private List<Observer> _observers = new List<Observer>();

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

        /// <summary>
        /// 删除观察者
        /// </summary>
        /// <param name="observer"></param>
        public void Detach(Observer observer)
        {
            _observers.Remove(observer);
        }

        public void Notify()
        {
            foreach (Observer o in _observers)
            {
            //调用观察者中的更新函数
                o.Update();
            }
        }
    }

    /// <summary>
    /// The 'ConcreteSubject' class
    /// 具体的主题
    /// </summary>
    class ConcreteSubject : Subject
    {
        private string _subjectState;

        // Gets or sets subject state
        //主题
        public string SubjectState
        {
            get { return _subjectState; }
            set { _subjectState = value; }
        }
    }

    /// <summary>
    /// The 'Observer' abstract class
    /// </summary>
    abstract class Observer
    {
        public abstract void Update();
    }

    /// <summary>
    /// The 'ConcreteObserver' class
    /// 具体的观察者
    /// </summary>
    class ConcreteObserver : Observer
    {
        //观察者的名字
        private string _name;
        private string _observerState;
        private ConcreteSubject _subject;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="subject">观察者观察的事件</param>
        /// <param name="name">观察者的名字</param>
        public ConcreteObserver(
          ConcreteSubject subject, string name)
        {
            this._subject = subject;
            this._name = name;
        }

        public override void Update()
        {
            _observerState = _subject.SubjectState;
            Debug.Log("Observer "+ _name+"'s new state is "+_observerState);
    }

        // Gets or sets subject
        public ConcreteSubject Subject
        {
            get { return _subject; }
            set { _subject = value; }
        }
    }


3.Mediator Pattern 中介者模式

模式优点

简化了对象之间的关系,将系统的各个对象之间的交互关系进行封装,将各个子系统类解耦;

提供系统的灵活性,使得各个系统对象独立而易于复用

模式缺点

由于中介者承担了较多的责任,所以当中介者被破坏后,各个系统将可能受到影响

当我们的游戏中需要添加新的系统时候,这样将要修改中介类,违背了设计原则的开闭原则

Definition

Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. 

用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

每一位同事只要与另一位同事进行其他交流,就会与其调解员进行沟通

Participants

The classes and objects participating in this pattern are:

Mediator (IChatroom)

  • defines an interface for communicating with Colleague objects

ConcreteMediator (Chatroom)

  • implements cooperative behavior by coordinating Colleague objects
  • knows and maintains its colleagues

Colleague classes (Participant)

  • each Colleague class knows its Mediator object
  • each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague
//-------------------------------------------------------------------------------------
//	MediatorStructure.cs
//-------------------------------------------------------------------------------------

using UnityEngine;
using System.Collections;

/// <summary>
/// 终介者模式
/// </summary>
public class MediatorStructure : MonoBehaviour
{
    void Start()
    {
        //中介
        ConcreteMediator m = new ConcreteMediator();
        //同事
        ConcreteColleague1 c1 = new ConcreteColleague1(m);
        ConcreteColleague2 c2 = new ConcreteColleague2(m);

        m.Colleague1 = c1;
        m.Colleague2 = c2;

        c1.Send("How are you?");
        c2.Send("Fine, thanks");

    }
}

/// <summary>
/// The 'Mediator' abstract class
/// </summary>
abstract class Mediator
{
    public abstract void Send(string message,Colleague colleague);
}

/// <summary>
/// The 'ConcreteMediator' class
/// </summary>
class ConcreteMediator : Mediator
{
    private ConcreteColleague1 _colleague1;
    private ConcreteColleague2 _colleague2;

    public ConcreteColleague1 Colleague1
    {
        set { _colleague1 = value; }
    }

    public ConcreteColleague2 Colleague2
    {
        set { _colleague2 = value; }
    }

    public override void Send(string message,Colleague colleague)
    {
        ///如果是第一个同事,则_colleague2收到话
        if (colleague == _colleague1)
        {
            _colleague2.Notify(message);
        }
        else///如果不是第一个同事,则_colleague1收到话
        {
            _colleague1.Notify(message);
        }
    }
}

/// <summary>
/// The 'Colleague' abstract class
/// </summary>
abstract class Colleague
{
    protected Mediator mediator;

    // Constructor
    public Colleague(Mediator mediator)
    {
        this.mediator = mediator;
    }
}

/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
class ConcreteColleague1 : Colleague
{
    // Constructor
    public ConcreteColleague1(Mediator mediator)
        : base(mediator)
    {
    }

    public void Send(string message)
    {
        mediator.Send(message, this);
    }

    public void Notify(string message)
    {
        Debug.Log("Colleague1 gets message: "+ message);
    }
}

/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
class ConcreteColleague2 : Colleague
{
    // Constructor
    public ConcreteColleague2(Mediator mediator)
        : base(mediator)
    {
    }

    public void Send(string message)
    {
        mediator.Send(message, this);
    }

    public void Notify(string message)
    {
        Debug.Log("Colleague2 gets message: "+ message);
    }
}
转载和工程链接: 点击打开链接

猜你喜欢

转载自blog.csdn.net/qq_35433081/article/details/80670169