【UnityUI程序框架】The PureMVC Framework[一]底层源码中文详解

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏:Unity基础实战

🅰️



文章目录

    • 🅰️
    • 前言
    • 🎶(==A==) PureMVC的构成
  • 🎶(==一==) PureMVC基类
    • 🎶(==1==) Model_Proxy(模型代理)
    • 🎶(==2==) View_Mediator(视图中介)
    • 🎶(==3==) Conotrller_SimpleCommand (简单命令)
    • 🎶(==4==) Facade(外观)
    • 🎶(==5==) Notifier (通知者)
  • 🎶(==二==)PureMVC 接口
    • 🎶(==1==) INotification(通知接口)
    • 🎶(==2==) INotifier(通知者接口)
    • 🎶(==2==) IFacade(外观接口)
    • 🎶(==3==) IProxy(代理接口)
    • 🎶(==3==) IView(视图接口)
  • 🎶(==三==)PureMVC 核心
    • 🎶(==1==) View(视图)
    • ` ⭐🅰️


前言

PureMVC是一个基于模型-视图-控制器(MVC)架构的开源框架,用于创建面向对象的、可重用的应用程序。它提供了一套成熟的模式和标准,以帮助开发人员实现松散耦合的代码,以便更好地分离关注点和简化应用程序的开发和维护。PureMVC框架适用于各种编程语言,包括Java、ActionScript、C#、PHP、JavaScript等,并且它已经被广泛地应用于各种类型的应用程序中,包括桌面应用程序、Web应用程序和移动应用程序等。
官方网址:http://puremvc.org/

在这里插入图片描述

  • 移入Unity’中

🎶(A PureMVC的构成


在这里插入图片描述

  • PureMVC由三个文件夹组成分别是 Core ,Interfaces,Patterns
    在这里插入图片描述

在这里插入图片描述

PureMVC中涉及到的设计模式

1.代理设计模式
2.中介者设计模式
3.外观设计模式
4.观察者设计模式
5.命令设计模式
6.单例设计模式


🎶( PureMVC基类



🎶(1 Model_Proxy(模型代理)


  • 代理设计模式

Proxy
由一个常量,两个属性,一个构造函数,两个虚方法组成

————————————在这里插入图片描述

using PureMVC.Interfaces;
using PureMVC.Patterns.Observer;namespace PureMVC.Patterns.Proxy
{/// <summary>/// 一个基本的IProxy实现。在PureMVC中,Proxy类用于管理应用程序的数据模型/// </summary>///<remarks>///一个Proxy(代理) 可以简单地管理对本地数据对象的引用, 在这种情况下,与它的交互可能涉及设置和  以同步方式获取其数据。        /// <para>/// 代理类还用于封装应用程序与远程服务的交互,以保存或检索数据,在这种情况下,我们采用异步习惯用法;在代理服务器上设置数据(或调用方法),并在代理服务器从服务中检索到数据时侦听要发送的通知。///  </para>/// </remarks>public class Proxy: Notifier, IProxy{/// <summary> Name of the proxy</summary>public const string NAME = "Proxy";/// <summary>/// 构造函数/// </summary>/// <param name="proxyName">代理名字</param>/// <param name="data">代理关联的数据</param>public Proxy(string proxyName, object data = null){ProxyName = proxyName ?? NAME;if (data != null) Data = data;}/// <summary>/// 注册代理时由Model调用/// </summary>public virtual void OnRegister(){ }/// <summary>///删除代理时由模型Model调用/// </summary>public virtual void OnRemove(){}/// <summary>代理名称</summary>public string ProxyName { get; protected set; }/// <summary>数据对象</summary>public object Data { get; set; }}
}

🎶(2 View_Mediator(视图中介)


  • 中介者设计模式

在这里插入图片描述

———————在这里插入图片描述


using PureMVC.Interfaces;
using PureMVC.Patterns.Observer;namespace PureMVC.Patterns.Mediator
{/// <summary>/// 一个基本的IMediator实现。/// </summary>/// <seealso cref="PureMVC.Core.View"/>public class Mediator : Notifier, IMediator{/// <summary>/// 中介程序的名称/// </summary>/// <remarks>///     <para>///       通常,Mediator将被编写为服务于特定的控件或组控件,因此不需要动态命名。///     </para>/// </remarks>public static string NAME = "Mediator";/// <summary>///构造函数/// </summary>/// <param name="mediatorName">中介名字</param>/// <param name="viewComponent">视图组件(界面脚本)</param>public Mediator(string mediatorName, object viewComponent = null){MediatorName = mediatorName ?? NAME;ViewComponent = viewComponent;}/// <summary>/// 列出此Mediator(中介)有兴趣获得通知的通知名称/// </summary>/// 然后返回通知名称的列表</returns>public virtual string[] ListNotificationInterests(){return new string[0];}/// <summary>/// 处理通知/// </summary>/// <remarks>///     <para>///        通常,这将在switch语句中处理,每个(Mediator)中介感兴趣的通知(INotification)都有一个“case”条目。///     </para>/// </remarks>/// <param name="notification"></param>public virtual void HandleNotification(INotification notification){}/// <summary>/// 注册中介时由视图调用/// </summary>public virtual void OnRegister(){}/// <summary>///移除中介时由视图调用/// </summary>public virtual void OnRemove(){}/// <summary>中介名称</summary>public string MediatorName { get; protected set; }/// <summary>视图组件</summary>public object ViewComponent { get; set; }}
}

🎶(3 Conotrller_SimpleCommand (简单命令)


在这里插入图片描述


using PureMVC.Interfaces;
using PureMVC.Patterns.Observer;namespace PureMVC.Patterns.Command
{/// <summary>///一个基本的<c>ICommand</c>实现。/// </summary>/// <remarks>///  <para>///         您的子类应该覆盖业务逻辑将处理INotification的execute方法///  </para>/// </remarks>public class SimpleCommand : Notifier, ICommand{/// <summary>///完成由给定<c>INotification</c>启动的用例。/// </summary>/// <remarks>///     <para>///        在命令模式中,应用程序用例通常以一些用户操作开始,///        这导致正在广播的通知,该通知由ICommand的 execute 执行方法中的业务逻辑处理///     </para>/// </remarks>/// <param name="notification">the <c>INotification</c> to handle.</param>public virtual void Execute(INotification notification){}}
}

🎶(4 Facade(外观)


在这里插入图片描述
在这里插入图片描述

using System;
using PureMVC.Interfaces;
using PureMVC.Core;
using PureMVC.Patterns.Observer;namespace PureMVC.Patterns.Facade
{/// <summary>/// 一个基本的单例 IFacade实现。/// </summary>/// <remarks>///     <para>///        在PureMVC中,Facade类承担以下职责:///        1.初始化模型、视图和控制器单体。///        2.提供IModel、IView和IController接口定义的所有方法。///        3.提供覆盖创建的特定模型、视图和控制器单体的功能。为应用程序提供单一联系点,用于注册命令和通知观察员///     </para>public class Facade : IFacade{/// <summary>/// 构造函数/// </summary>/// <remarks>///  <para>/// 此IFacade实现是Singleton,因此不应直接调用构造函数,/// 而是应调用静态Factory方法,/// 传递此实例Facade.getInstance(()=>new Facade())的唯一键/// </para>/// </remarks>/// <exception cref="System.Exception">如果已经构造了此Singleton键的实例,则抛出</exception>public Facade(){if (instance != null) throw new Exception(SingletonMsg);instance = this;InitializeFacade();}/// <summary>/// 初始化单例模式 Facade实例。/// </summary>/// <remarks>/// <para>/// 由构造函数自动调用。在子类中重写以进行任何特定于子类的初始化。/// 不过,一定要调用super.initializeFacade()。/// </para>/// </remarks>protected virtual void InitializeFacade(){InitializeModel();InitializeController();InitializeView();}/// <summary>///Facade单例模式 /// </summary>/// <param name="facadeFunc"></param>/// <returns>the Singleton instance of the Facade</returns>public static IFacade GetInstance(Func<IFacade> facadeFunc){if (instance == null){instance = facadeFunc();}return instance;}/// <summary>///初始化Controller(控制器)/// </summary>/// <remarks>///     <para>///       由InitializeFacade方法调用。如果以下一项或两项都为真,请在Facade的子类中重写此方法:///      如果不想初始化不同的IController,请在方法的开头调用csuper.initializeController(),然后注册Commands。 ///     </para>/// </remarks>protected virtual void InitializeController(){controller = Controller.GetInstance(() => new Controller());}/// <summary>/// 初始化Model/// </summary>/// <remarks>///     <para>///        由initializeFacade方法调用。如果以下一项或两项都为真,请在Facade的子类中重写此方法:///        如果您不想初始化不同的IModel,请在方法的开头调用super.initializeModel(),然后注册Proxys。///        注意:此方法很少被重写;在实践中,您更有可能使用命令来创建代理并将其注册到模型中,///        因为具有可变数据的代理可能需要发送通知,因此可能希望在构建过程中获取对立面的引用。///      </para>/// </remarks>protected virtual void InitializeModel(){model = Model.GetInstance(() => new Model());}/// <summary>/// 初始化 View(视图)./// </summary>/// <remarks>///     <para>///       由initializeFacademethod调用。如果以下一项或两项都为真,请在Facade的子类中重写此方法:///     </para>/// </remarks>protected virtual void InitializeView(){view = View.GetInstance(() => new View());}/// <summary>///按通知名称向控制器注册ICommand./// </summary>/// <param name="notificationName">将ICommand与对ICommand类的引用相关联的通知的名称<</param>/// <param name="factory">将ICommand与对ICommand类的引用相关联的通知的名称</param>public virtual void RegisterCommand(string notificationName, Func<ICommand> factory){controller.RegisterCommand(notificationName, factory);}/// <summary>/// 从控制器中删除以前注册的ICommand到INotification映射。/// </summary>/// <param name="notificationName">要删除的ICommand映射的INotification的名称</param>public virtual void RemoveCommand(string notificationName){controller.RemoveCommand(notificationName);}/// <summary>///检查是否为给定通知注册了命令/// </summary>/// <param name="notificationName"></param>/// <returns>当前为给定的notificationName注册了一个命令</returns>public virtual bool HasCommand(string notificationName){return controller.HasCommand(notificationName);}/// <summary>/// 按名称向模型(Model)注册IProxy。/// </summary>/// <param name="proxy">要向模型注册的IProxy实例.</param>public virtual void RegisterProxy(IProxy proxy){model.RegisterProxy(proxy);}/// <summary>/// 按名称从模型(Model)中检索IProxy。/// </summary>/// <param name="proxyName">要检索的代理的名称.</param>/// <returns> 返回先前使用给定proxyName注册的IProxy实例</returns>public virtual IProxy RetrieveProxy(string proxyName){return model.RetrieveProxy(proxyName);}/// <summary>/// 按名称从模型中删除一个IProxy。/// </summary>/// <param name="proxyName">the <c>IProxy</c> to remove from the <c>Model</c>.</param>/// <returns>the <c>IProxy</c> that was removed from the <c>Model</c></returns>public virtual IProxy RemoveProxy(string proxyName){return model.RemoveProxy(proxyName);}/// <summary>/// 检查是否已注册代理/// </summary>/// <param name="proxyName"></param>/// <returns>whether a Proxy is currently registered with the given <c>proxyName</c>.</returns>public virtual bool HasProxy(string proxyName){return model.HasProxy(proxyName);}/// <summary>///向视图注册IMediator/// </summary>/// <param name="mediator">a reference to the <c>IMediator</c></param>public virtual void RegisterMediator(IMediator mediator){view.RegisterMediator(mediator);}/// <summary>/// 从视图中检索IMediator/// </summary>/// <param name="mediatorName"></param>/// <returns>the <c>IMediator</c> previously registered with the given <c>mediatorName</c>.</returns>public virtual IMediator RetrieveMediator(string mediatorName){return view.RetrieveMediator(mediatorName);}/// <summary>/// 从视图中删除IMediator/// </summary>/// <param name="mediatorName">name of the <c>IMediator</c> to be removed.</param>/// <returns>the <c>IMediator</c> that was removed from the <c>View</c></returns>public virtual IMediator RemoveMediator(string mediatorName){return view.RemoveMediator(mediatorName);}/// <summary>/// 检查中介是否已注册/// </summary>/// <param name="mediatorName"></param>/// <returns>whether a Mediator is registered with the given <c>mediatorName</c>.</returns>public virtual bool HasMediator(string mediatorName){return view.HasMediator(mediatorName);}/// <summary>/// 创建并发送INotification 通知/// </summary>/// <remarks>///     <para>///         使我们不必在实现代码中构造新的通知实例。///     </para>/// </remarks>/// <param name="notificationName">要发送的通知的名称</param>/// <param name="body">通知的正文(可选)</param>/// <param name="type">键入通知的类型(可选)</param>public virtual void SendNotification(string notificationName, object body = null, string type = null){NotifyObservers(new Notification(notificationName, body, type));}/// <summary>/// 通知观察者/// </summary>/// <remarks>///     <para>///        此方法保留为公共方法,主要是为了向后兼容,并允许您使用facade发送自定义通知类。///     </para>///     <para>///         通常,您应该只调用sendNotification并传递参数,而不必自己构造通知。///     </para>/// </remarks>/// <param name="notification">使视图通知观察者的通知</param>public virtual void NotifyObservers(INotification notification){view.NotifyObservers(notification);}/// <summary>涉及的控制器</summary>protected IController controller;/// <summary>涉及的Model模型</summary>protected IModel model;/// <summary>涉及的视图View</summary>protected IView view;/// <summary>单例模式实例</summary>protected static IFacade instance;/// <summary>消息常量名称</summary>protected const string SingletonMsg = "Facade Singleton already constructed!";}
}

🎶(5 Notifier (通知者)


在这里插入图片描述


using PureMVC.Interfaces;namespace PureMVC.Patterns.Observer
{/// <summary>/// 一个基本的INotifier实现。/// </summary>/// <remarks>///     <para>///      MacroCommand、Command、Mediator和Proxy都需要发送通知。///     </para>///     <para>///         INotifier接口提供了一个名为sendNotification的通用方法///         该方法免除了实现代码实际构造Notifications的必要性///     </para>///     <para>///        上述所有类都扩展了Notifier类,///        该类提供了对Facade单例的初始化引用,///        这是发送Notifications的方便方法所必需的,///        但也简化了实现,因为这些类具有频繁的<c>Facade</c>交互,///        并且通常需要访问Facade。///     </para>/// </remarks>public class Notifier : INotifier{/// <summary>返回单例模式 Facade实例</summary>protected IFacade Facade{get{return Patterns.Facade.Facade.GetInstance(() => new Facade.Facade());}}/// <summary>/// 创建并发送通知INotification/// </summary>/// <remarks>///     <para>///   使我们不必在实现代码中构造新的INotification实例。///     </para>/// </remarks>/// <param name="notificationName">the name of the notification to send</param>/// <param name="body">the body of the notification (optional)</param>/// <param name="type">the type of the notification (optional)</param>public virtual void SendNotification(string notificationName, object body = null, string type = null){Facade.SendNotification(notificationName, body, type);}}
}

🎶(PureMVC 接口



🎶(1 INotification(通知接口)


在这里插入图片描述

namespace PureMVC.Interfaces
{/// <summary>///一个通知接口的基本实现/// </summary>/// <remarks>///     <para>/// PureMVC不依赖于底层事件模型,例如Flash提供的事件模型,ActionScript3也没有固有的事件模型。/// 在PureMVC中实现的观察者模式支持应用程序和MVC三元组的参与者之间的事件驱动通信。/// 通知并不意味着要取代Flex/Flash/Apollo中的事件。通常,中介实现者将事件侦听器放置在他们的视图组件上,然后以通常的方式进行处理。这可能导致通知的广播以触发ICommands或与其他IMediator通信///IProxy和ICommand实例通过广播INotification相互通信并与IMediator通信/// </para>/// </remarks>/// <seealso cref="IView"/>/// <seealso cref="IObserver"/>public interface INotification{/// <summary>/// 获取INotification实例的名称。没有setter,只能由构造函数设置/// </summary>string Name { get; }/// <summary>/// 获取或设置INotification实例的主体(通知包含的信息)/// </summary>object Body { get; set; }/// <summary>///获取或设置INotification实例的类型/// </summary>string Type { get; set; }/// <summary>/// 获取INotification实例的字符串表示形式/// </summary>/// <returns>返回字符串表示</returns>string ToString();}
}

🎶(2 INotifier(通知者接口)


在这里插入图片描述

namespace PureMVC.Interfaces
{/// <summary>///一个基本的INotifier实现。/// </summary>/// <remarks>///     <para>///        <c> MacroCommand、Command、Mediator</c>和<c>Proxy</c>都需要发送<c>Notifications</c>。///     </para>///     <para>///       Notifier接口提供了一个名为sendNotification的通用方法,该方法免除了实现代码实际构造Notifications的必要性///   上面提到的所有类都扩展了Notifier类,它提供了对Facade Multiton的初始化引用,///   这是发送通知的便利方法所必需的,但也简化了实现,因为这些类具有频繁的Facade交互,通常需要访问Facade/// </para>/// </remarks>public interface INotifier{/// <summary>/// 发送通知INotification/// </summary>/// <remarks>///     <para>///      便捷的方法以防止必须在我们的实现代码中构造新的通知实例。///     </para>/// </remarks>/// <param name="notificationName">the name of the notification to send</param>/// <param name="body">the body of the notification (optional)</param>/// <param name="type">the type of the notification (optional)</param>void SendNotification(string notificationName, object body = null, string type = null);}
}

🎶(2 IFacade(外观接口)


在这里插入图片描述

using System;
namespace PureMVC.Interfaces
{/// <summary>/// Facade(外观)的接口定义/// </summary>/// <remarks>///     <para>///        Facade(外观)模式建议提供一个类作为子系统的中心通信点。///        在PureMVC中,Facade充当核心MVC参与者(Model、View、Controller)///        和应用程序其余部分之间的接口。///     </para>/// </remarks>public interface IFacade: INotifier{/// <summary>/// 按名称向Model注册IProxy。/// </summary>/// <param name="proxy">要向模型Model注册的IProxy</param>void RegisterProxy(IProxy proxy);/// <summary>/// 按名称从模型中检索IProxy。/// </summary>/// <param name="proxyName">要检索的IProxy实例的名称.</param>/// <returns>the <c>IProxy</c> previously registered by <c>proxyName</c> with the <c>Model</c>.</returns>IProxy RetrieveProxy(string proxyName);/// <summary>/// 按名称从<c>模型</c>中删除<c>IProxy</c>实例。/// </summary>/// <param name="proxyName">the <c>IProxy</c> to remove from the <c>Model</c>.</param>/// <returns>the <c>IProxy</c> that was removed from the <c>Model</c></returns>IProxy RemoveProxy(string proxyName);/// <summary>/// 检查是否已注册代理/// </summary>/// <param name="proxyName"></param>/// <returns>whether a Proxy is currently registered with the given <c>proxyName</c>.</returns>bool HasProxy(string proxyName);/// <summary>/// 向<c>控制器</c>注册<c>ICommand</c>。/// </summary>/// <param name="notificationName">the name of the <c>INotification</c> to associate the <c>ICommand</c> with.</param>/// <param name="factory">a reference to the <c>FuncDelegate</c> of the <c>ICommand</c></param>void RegisterCommand(string notificationName, Func<ICommand> factory);/// <summary>/// 从控制器中删除以前注册的<c>ICommand</c>到<c>INotification</c>的映射。/// </summary>/// <param name="notificationName">the name of the <c>INotification</c> to remove the <c>ICommand</c> mapping for</param>void RemoveCommand(string notificationName);/// <summary>/// 检查是否为给定通知注册了命令/// </summary>/// <param name="notificationName"></param>/// <returns>whether a Command is currently registered for the given <c>notificationName</c>.</returns>bool HasCommand(string notificationName);/// <summary>/// 使用<c>View</c>注册<c>IMediator</c>实例。/// </summary>/// <param name="mediator">a reference to the <c>IMediator</c> instance</param>void RegisterMediator(IMediator mediator);/// <summary>///从<c>View</c>检索<c>IMediator</c>实例。/// </summary>/// <param name="mediatorName">the name of the <c>IMediator</c> instance to retrievve</param>/// <returns>the <c>IMediator</c> previously registered with the given <c>mediatorName</c>.</returns>IMediator RetrieveMediator(string mediatorName);/// <summary>/// 从<c>View</c>中删除<c>IMediator</c>实例。/// </summary>/// <param name="mediatorName">name of the <c>IMediator</c> instance to be removed</param>/// <returns>the <c>IMediator</c> instance previously registered with the given <c>mediatorName</c>.</returns>IMediator RemoveMediator(string mediatorName);/// <summary>/// 检查中介是否已注册/// </summary>/// <param name="mediatorName"></param>/// <returns>whether a Mediator is registered with the given <c>mediatorName</c>.</returns>bool HasMediator(string mediatorName);/// <summary>///通知<c>观察员</c>s。/// </summary>/// <remarks>///     <para>///        此方法保留为公共方法,主要是为了向后兼容,并允许您使用facade发送自定义通知类。///        通常,您应该只调用sendNotification并传递参数,而不必自己构造通知。///     </para>/// <param name="notification">the <c>INotification</c> to have the <c>View</c> notify <c>Observers</c> of.</param>void NotifyObservers(INotification notification);}
}

🎶(3 IProxy(代理接口)


namespace PureMVC.Interfaces
{/// <summary>/// PureMVC代理的接口定义。/// </summary>/// <remarks>///     <para>///         在PureMVC中,IProxy实现者承担以下职责:///             <item>实现一个返回代理名称的通用方法.</item>///             <item>提供设置和获取数据对象的方法.</item>    ///     </para>///     <para>///   此外,IProxys通常:///   维护对一个或多个模型数据的引用。///   提供处理该数据的方法。///   当其模型数据发生更改时生成通知。///   如果没有多次实例化,则将它们的名称公开为名为name的公共静态常量。///   封装与用于获取和持久化模型数据的本地或远程服务的交互。</item>   ///     </para>/// </remarks>public interface IProxy: INotifier{/// <summary>/// 获取代理名称/// </summary>string ProxyName { get; }/// <summary>/// 获取或设置数据对象/// </summary>object Data { get; set; }/// <summary>/// 注册代理时由模型调用/// </summary>void OnRegister();/// <summary>/// 删除代理时由模型调用/// </summary>void OnRemove();}
}

🎶(3 IView(视图接口)



namespace PureMVC.Interfaces
{/// <summary>///  PureMVC视图的接口定义IView。/// </summary>/// <remarks> <para> 在PureMVC中,View类承担以下职责:/// 维护IMediator实例的缓存/// 提供注册、检索和删除IMediators的方法/// 管理应用程序中每个INotification的观察者列表/// 提供一种将IObservers附加到INotification的观察者列表的方法/// 提供一种广播INotification的方法/// 广播时通知IObservers给定的INotification/// </para></remarks>public interface IView{/// <summary>/// 注册<c>IObserver</c>以获得通知/// of <c>INotifications</c> with a given name./// </summary>/// <param name="notificationName">the name of the <c>INotifications</c> to notify this <c>IObserver</c> of</param>/// <param name="observer">the <c>IObserver</c> to register</param>void RegisterObserver(string notificationName, IObserver observer);/// <summary>/// 从给定通知名称的观察者列表中删除一组观察者。/// </summary>/// <param name="notificationName">which observer list to remove from </param>/// <param name="notifyContext">removed the observers with this object as their notifyContext</param>void RemoveObserver(string notificationName, object notifyContext);/// <summary>///针对特定的<c>IObservers</c>,通知<c>INotification</c>。/// </summary>/// <remarks>///     <para>///       所有先前连接的<c>I观察器</c>,用于此<c>通知</c>///    列表将得到通知,并按其注册顺序传递到<c> INotification</c>的引用。///     </para>/// </remarks>/// <param name="notification">the <c>INotification</c> to notify <c>IObservers</c> of.</param>void NotifyObservers(INotification notification);/// <summary>/// 使用<c>View</c>注册<c>IMediator</c>实例。/// </summary>/// <remarks>///     <para>///         Registers the <c>IMediator</c> so that it can be retrieved by name,///         and further interrogates the <c>IMediator</c> for its ///         <c>INotification</c> interests.///     </para>///     <para>///         If the <c>IMediator</c> returns any <c>INotification</c> ///         names to be notified about, an <c>Observer</c> is created encapsulating ///         the <c>IMediator</c> instance's <c>handleNotification</c> method ///         and registering it as an <c>Observer</c> for all <c>INotifications</c> the ///         <c>IMediator</c> is interested in.///     </para>/// </remarks>/// <param name="mediator">a reference to the <c>IMediator</c> instance</param>void RegisterMediator(IMediator mediator);/// <summary>/// 从<c>视图</c>检索<c>IMediator</c>。/// </summary>/// <param name="mediatorName">the name of the <c>IMediator</c> instance to retrieve.</param>/// <returns>the <c>IMediator</c> instance previously registered with the given <c>mediatorName</c>.</returns>IMediator RetrieveMediator(string mediatorName);/// <summary>///从<c>视图</c>中删除<c>IMediator</c>。/// </summary>/// <param name="mediatorName">name of the <c>IMediator</c> instance to be removed.</param>/// <returns>the <c>IMediator</c> that was removed from the <c>View</c></returns>IMediator RemoveMediator(string mediatorName);/// <summary>/// 检查中介是否已注册/// </summary>/// <param name="mediatorName"></param>/// <returns>whether a Mediator is registered with the given <c>mediatorName</c>.</returns>bool HasMediator(string mediatorName);}
}

🎶(PureMVC 核心


在这里插入图片描述


🎶(1 View(视图)


using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using PureMVC.Interfaces;
using PureMVC.Patterns.Observer;namespace PureMVC.Core
{/// <summary>///  一个IView的实现/// </summary>/// <remarks> <para> 在PureMVC中,View类承担以下职责:/// 护IMediator实例的缓存/// 提供注册、检索和删除IMediators的方法/// 管理应用程序中每个INotification的观察者列表/// 提供一种将IObservers附加到INotification的观察者列表的方法/// 提供一种广播INotification的方法/// 广播时通知IObserver给定的INotifications/// </para></remarks>public class View: IView{/// <summary>/// 构造和初始化新视图/// </summary>/// <remarks>///     <para>///    这个<c>IView</c>实现是Singleton,///    所以你不应该调用构造函数///    直接,但改为调用静态Singleton///    工厂方法<c>View.getInstance(()=>new View())</c>///     </para>/// </remarks>/// <exception cref="System.Exception">Thrown if Singleton instance has already been constructed</exception>public View(){if (instance != null) throw new Exception(SingletonMsg);instance = this;mediatorMap = new ConcurrentDictionary<string, IMediator>();observerMap = new ConcurrentDictionary<string, IList<IObserver>>();InitializeView();}/// <summary>/// 初始化Singleton View实例。/// </summary>/// <remarks>///     <para>///       由构造函数自动调用,这是您在不重写构造函数的情况下初始化子类中的Singleton实例的机会。///     </para>/// </remarks>protected virtual void InitializeView(){}/// <summary>/// 查看Singleton Factory方法。/// </summary>/// <param name="factory">the <c>FuncDelegate</c> of the <c>IView</c></param>/// <returns>the instance for this Singleton key </returns>public static IView GetInstance(Func<IView> factory){if (instance == null){instance = factory();}return instance;}/// <summary>///  使用给定的名称注册IObserver以获得通知/// </summary>/// <param name="notificationName">the name of the <c>INotifications</c> to notify this <c>IObserver</c> of</param>/// <param name="observer">the <c>IObserver</c> to register</param>public virtual void RegisterObserver(string notificationName, IObserver observer){if (observerMap.TryGetValue(notificationName, out var observers)){observers.Add(observer);}else{observerMap.TryAdd(notificationName, new List<IObserver> { observer });}}/// <summary>/// 针对特定的INotification通知,通知I观察器IObservers/// </summary>/// <remarks>///     <para>///       之前为该INotification的列表附加的所有IObservers都会得到通知,并按其注册顺序传递对INotification的引用。///     </para>/// </remarks>/// <param name="notification"></param>public virtual void NotifyObservers(INotification notification){// 获取对此通知名称的观察者列表的引用if (observerMap.TryGetValue(notification.Name, out var observersRef)){// 将观察者从参考阵列复制到工作阵列,//因为引用数组可能在通知循环期间发生变化var observers = new List<IObserver>(observersRef);// 通知工作阵列中的观察者foreach (var observer in observers){observer.NotifyObserver(notification);}}}/// <summary>/// 从给定Notification名称的观察者列表中删除给定notifyContext的观察者。/// </summary>/// <param name="notificationName">which observer list to remove from </param>/// <param name="notifyContext">remove the observer with this object as its notifyContext</param>public virtual void RemoveObserver(string notificationName, object notifyContext){//被检查通知的观察员名单if (observerMap.TryGetValue(notificationName, out var observers)){//找到notifyContext的观察者for (var i = 0; i < observers.Count; i++){if (observers[i].CompareNotifyContext(notifyContext)){//对于给定的notifyContext,只能有一个观察者//在任何给定的观察者列表中,删除它并中断observers.RemoveAt(i);break;}}//此外,当通知的观察者列表长度降至//零,从观察者映射中删除通知密钥if (observers.Count == 0)observerMap.TryRemove(notificationName, out _);}}/// <summary>/// 使用<c>View</c>注册<c>IMediator</c>实例。/// </summary>/// <remarks>///     <para>///  注册<c>IMediator</c>,以便可以按名称检索它,并进一步询问IMediator的通知兴趣。///     </para>///     <para>///        如果<c>IMediator</c>返回任何要通知的<c>INotification</c>名称,则会创建一个<c>Observer</c>,它封装<c>IMediator<c>实例的<c>handleNotification</c>方法,并将其注册为<c>Observer</c>,用于<c>IM mediator</c>感兴趣的所有<c>通知</c>。///     </para>/// </remarks>/// <param name="mediator">the name to associate with this <c>IMediator</c> instance</param>public virtual void RegisterMediator(IMediator mediator){//不允许重新注册(必须先删除Mediator)//注册中介以按名称检索if (mediatorMap.TryAdd(mediator.MediatorName, mediator)){//获取通知兴趣(如果有)。var interests = mediator.ListNotificationInterests();//将调解员注册为每次利益通知的观察员if (interests.Length > 0){//创建引用此中介的handleNotification方法的ObserverIObserver observer = new Observer(mediator.HandleNotification, mediator);//将调解员注册为其通知利益列表的观察员foreach (var interest in interests){RegisterObserver(interest, observer);}}//提醒调解员它已经注册mediator.OnRegister();}}/// <summary>/// 从视图检索<c>IMediator</c>。/// </summary>/// <param name="mediatorName">the name of the <c>IMediator</c> instance to retrieve.</param>/// <returns>the <c>IMediator</c> instance previously registered with the given <c>mediatorName</c>.</returns>public virtual IMediator RetrieveMediator(string mediatorName){return mediatorMap.TryGetValue(mediatorName, out var mediator) ? mediator : null;}/// <summary>///从View中删除IMediator。/// </summary>/// <param name="mediatorName">name of the <c>IMediator</c> instance to be removed.</param>/// <returns>the <c>IMediator</c> that was removed from the <c>View</c></returns>public virtual IMediator RemoveMediator(string mediatorName){// 检索命名的中介if (mediatorMap.TryRemove(mediatorName, out var mediator)){//对于该调解员感兴趣的每一个通知。。。var interests = mediator.ListNotificationInterests();foreach (var interest in interests){// 删除连接中介的观察者//通知权益RemoveObserver(interest, mediator);}//从映射中删除中介mediator.OnRemove();}return mediator;}/// <summary>/// 检查中介是否已注册/// </summary>/// <param name="mediatorName"></param>/// <returns>whether a Mediator is registered with the given <c>mediatorName</c>.</returns>public virtual bool HasMediator(string mediatorName){return mediatorMap.ContainsKey(mediatorName);}///<summary>中介名称到中介实例的映射</summary>protected readonly ConcurrentDictionary<string, IMediator> mediatorMap;/// <summary>通知名称到观察者列表的映射</summary>protected readonly ConcurrentDictionary<string, IList<IObserver>> observerMap;/// <summary>Singleton实例</summary>protected static IView instance;/// <summary>消息常量</summary>protected const string SingletonMsg = "View Singleton already constructed!";}
}

` ⭐🅰️


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/325980.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推导 模型矩阵的逆转置矩阵求运动物体的法向量

一个物体表面的法向量如何随着物体的坐标变换而改变&#xff0c;取决于变换的类型。使用逆转置矩阵&#xff0c;可以安全地解决该问题&#xff0c;而无须陷入过度复杂的计算中。 法向量变化规律 平移变换不会改变法向量&#xff0c;因为平移不会改变物体的方向。 旋转变换会改…

Python 全栈系列244 nginx upstream 负载均衡 踩坑日记

说明 最初是因为租用算力机(Python 全栈系列242 踩坑记录:租用算力机完成任务)&#xff0c;所以想着做一个负载均衡&#xff0c;然后多开一些服务&#xff0c;把配置写在nginx里面就好了。 一开始租用了一个3080起了一个服务&#xff0c;后来觉得速度不够快&#xff0c;再起了…

基于地平线J6E,「吃蟹者」易航智能重塑高速NOA

作者 |张祥威 编辑 |德新 一批基于地平线J6E的智驾方案将要到来&#xff0c;高速NOA领域很快会变天。 易航智能是这批智驾方案公司中的一家。 近日在北京车展&#xff0c;这家公司推出一套基于地平线J6 E的7V1R方案&#xff0c;可以实现城市记忆领航、高速NOA、记忆泊车、L2…

社交媒体数据恢复:密聊猫

一、概述 密聊猫是一款提供多种优质体验的手机社交聊天软件。通过这款软件&#xff0c;用户可以享受到多种不同的乐趣体验&#xff0c;如真人在线匹配、真实的交友体验等。同时&#xff0c;密聊猫也提供了数据恢复功能&#xff0c;帮助用户找回丢失的数据。 二、数据恢复步骤…

前端Vue架构

1 理解&#xff1a; 创建视图的函数&#xff08;render&#xff09;和数据之间的关联&#xff1b; 当数据发生变化的时候&#xff0c;希望render重新执行&#xff1b; 监听数据的读取和修改&#xff1b; defineProperty&#xff1a;监听范围比较窄&#xff0c;只能通过属性描…

博客互动革命:如何打造活跃读者社区并提升参与度

CSDN 的朋友你们好&#xff0c;我是未来&#xff0c;今天给大家带来专栏【程序员博主教程&#xff08;完全指南&#xff09;】的第 10 篇文章“与读者互动”。本文揭示了提升技术博客参与度的秘诀。从评论互动到社交媒体策略&#xff0c;本文将指导你如何建立强大的读者社区。掌…

blender 为世界环境添加纹理图像

1、打开世界环境配置项 2、点击颜色右侧的黄色小圆&#xff0c;选择环境纹理 3、打开一张天空图像 4、可以通过调整强度/力度&#xff0c;调整世界环境的亮度

传感网应用开发教程--AT指令访问新大陆云平台(ESP8266模块+物联网云+TCP)

实现目标 1、熟悉AT指令 2、熟悉新大陆云平台新建项目 3、具体目标&#xff1a;&#xff08;1&#xff09;注册新大陆云平台&#xff1b;&#xff08;2&#xff09;新建一个联网方案为WIFI的项目&#xff1b;&#xff08;3&#xff09;ESP8266模块&#xff0c;通过AT指令访问…

用python写算法——队列笔记

1.队列定义 队列是一种特殊的线性表&#xff0c;它只允许在表的前端进行删除操作&#xff0c;在表的后端进行插入操作&#xff0c;和栈一样&#xff0c;队列是一种操作受限制的线性表。进行插入操作的端称为队尾&#xff0c;进行删除操作的端称为队头。队列中没有元素时&#…

部署Discuz论坛项目

DIscuz 是由 PHP 语言开发的一款开源社交论坛项目。运行在典型的LNMP/LAMP 环境中。 安装MySQL数据库5.7 主机名IP地址操作系统硬件配置discuz-db192.168.226.128CentOS 7-mini-20092 Core/4G Memory 修改主机名用来自己识别 hostnamectl set-hostname discuz-db #重连远程…

一键复制:基于vue实现的tab切换效果

需求&#xff1a;顶部栏有切换功能&#xff0c;内容区域随顶部切换而变化 目录 实现效果实现代码使用示例在线预览 实现效果 如下 实现代码 组件代码 MoTab.vue <template><div class"mo-tab"><divv-for"item in options"class"m…

OBS插件--视频回放

视频回放 视频回放是一款源插件&#xff0c;它可以将指定源的视频缓存一段时间&#xff08;时间可以设定&#xff09;&#xff0c;将缓存中的视频添加到当前场景中后&#xff0c;可以快速或慢速不限次数的回放。这个功能在类似体育比赛的直播中非常有用&#xff0c;可以捕获指…

网络基础(三)——网络层

目录 IP协议 1、基本概念 2、协议头格式 2.1、报头和载荷如何有效分离 2.2、如果超过了MAC的规定&#xff0c;IP应该如何做呢&#xff1f; 2.3、分片会有什么影响 3、网段划分 4、特殊的ip地址 5、ip地址的数量限制 6、私有ip地址和公网ip地址 7、路由 IP协议 网络…

C++/Qt 小知识记录6

工作中遇到的一些小问题&#xff0c;总结的小知识记录&#xff1a;C/Qt 小知识6 dumpbin工具查看库导出符号OSGEarth使用编出的protobuf库&#xff0c;报错问题解决VS2022使用cpl模板后&#xff0c;提示会乱码的修改设置QProcess调用cmd.exe执行脚本QPainterPath对线段描边处理…

实验0.0 Visual Studio 2022安装指南

Visual Studio 2022 是一个功能强大的开发工具&#xff0c;对于计算机专业的学生来说&#xff0c;它不仅可以帮助你完成学业项目&#xff0c;还能为你将来的职业生涯打下坚实的基础。通过学习和使用 Visual Studio&#xff0c;你将能够更高效地开发软件&#xff0c;并在编程领域…

picoCTF-Web Exploitation-More SQLi

Description Can you find the flag on this website. Additional details will be available after launching your challenge instance. Hints SQLiLite 先随便输入个账号密码登录一下&#xff0c;得到查询SQL&#xff0c;接下来应该对SQL进行某些攻击来绕过密码登录成功 -- …

Unity Editor 找物体助手

找啊找朋友~ &#x1f371;功能介绍&#x1f959;使用方法 &#x1f371;功能介绍 &#x1f4a1;输入相关字符串&#xff0c;它会帮你找到名称中带有该字符串的所有物体&#xff0c;还会找包含该字符串的Text、TextMeshProUGUI。 &#x1f959;使用方法 &#x1f4a1;导入插…

商场学习之微服务

前言 寒假前在新电脑上配置了java环境&#xff0c;maven仓库&#xff0c;node,js&#xff0c;navicat&#xff0c;MySQL&#xff0c;linux&#xff0c;vmware等环境&#xff0c;创建了6个mysql数据库&#xff0c;77张表。 如此多的表&#xff0c;字段&#xff0c;去手写基础…

加州大学欧文分校英语高级语法专项课程01:Verb Tenses and Passives 学习笔记

Verb Tenses and Passives Course Certificate Course Intro 本文是学习 Verb Tenses and Passives 这门课的学习笔记。 文章目录 Verb Tenses and PassivesWeek 01: Simple, Progressive, and Perfect Verb Tenses ReviewLearning Objectives Present Perfect Tense Review L…

从我的实体书单中,精选这六本书推荐

工作之余偶尔看看书&#xff0c;偏爱翻阅实体书。随着时间的推移&#xff0c;书逐渐变得多了起来。为了给新书腾出空间&#xff0c;同时也为了减轻收藏实体书的经济负担&#xff0c;我决定进行一次书籍的整理和出售。在这一过程中&#xff0c;我特意挑选了六本我个人喜爱的书籍…