PureMVC_ico

一: PureMVC 目录结构。
分三大目录,共21一个类(接口)。
Core: 包含三大核心类: Model 、View、Controller
Interface: 包含十个接口。
Pattern: 其他辅助类。
Mediator、Proxy、SimpleCommand(MarocCommand)。

Notification: 消息封装类:
包含 Name、Body 、Type 三个重要的字段,本身这个类的作用,就是一种消息的封装载体。

Notifer: 传递消息使用,里面存在SendNotification() 三个方法重载类,本质是引用 Façade 类中 SendNotification()的方法。

*Observer: 对指定对象调用指定方法。
核心方法: NotifyObserver() 就是这个类的核心方法,我们在应用框架开发时候,使用SnedNotifacation() 方法的消息,最终消息的执行,就是由这个方法最终完成。

二: 三大核心类:
Core 文件夹下: Model、View、Controller
 分析三大核心类共同特性:
1: 都具备注册、查询(Controller类除外)、是否存在、移除方法。
2: 都是“线程安全”、“延迟加载”的单例类。
3: 核心类,存在大量虚方法,方便我们不改变框架源代码基础上,重构进一步丰富框架实现。
4: View与Model 类都会执行 OnRegister() ,OnRemove() 虚方法。

 Model 类不具备处理消息的能力。
所以不能给模型层实现类发消息。

 Controller 类,具备两大功能: 1: 缓存所有控制层实现类对象。
2: 可以接受“命令消息”,且自动执行(继承ICommand 的类)的Excute() 方法。

 View 类,
分两大功能:1: 整个框架的消息中心。
2: 对于Mediator 做存储,查询,以及处理。


三: 入口与辅助类。

Façade 入口类,就是框架三大核心类的一个简化入口。
Mediator : 视图层需要继承的父类。
SimpleCommand: 命令类
MecroCommand: 多个命令类的集合。
Proxy : 模型代理类。
Notify: 是 Mediator、SimpleCommand、Proxy父类,目的是方便我们做消息传递。


四: 分析PureMVC 消息的流转:

1: GameStart 脚本,执行Start() 方法。

2: ApplicationFacade 实例化(三层的初始化方法被执行)
[例如: InitializeView() 都执行]

3: 执行 StartupApplication 控制层,执行 Excute() 方法。

4: 执行SendNotifacation() 。

5: 执行父类SimplyCommand 的父类Notifier.cs 中的 SendNotifacation()
6: Notifer 是引用的Facade 类中的方法。
7: Facade 类是PureMVC 的一个“空壳”,聚集了三大核心类中主要的对外公布的方法。
8: Facade 最终是引用核心类:View 中“消息执行”NotifyObservers() 方法.

PureMVC_mvc_02


主要的设计模式

PureMVC_父类_03


PureMVC_mvc_04


PureMVC_mvc_05


PureMVC_ico_06

PureMVC_mvc_07

PureMVC_父类_08


目录结构

PureMVC_ico_09


PureMVC_ico_10


PureMVC_父类_11


PureMVC_mvc_12

三大核心类

PureMVC_父类_13


PureMVC_ico_14

PureMVC_ico_15


PureMVC_mvc_16


PureMVC_mvc_17


PureMVC_ico_18


PureMVC_父类_19


PureMVC_父类_20


PureMVC_父类_21


PureMVC_mvc_22


PureMVC_ico_23


PureMVC_父类_24


PureMVC_mvc_25

Facade

PureMVC_mvc_26


PureMVC_mvc_27


PureMVC_ico_28


PureMVC_ico_29


PureMVC_ico_30

/* 
核心层: 控制类
*/
using System;
using System.Collections.Generic;
using PureMVC.Interfaces;
using PureMVC.Patterns;
namespace PureMVC.Core{
public class Controller : IController{
protected IView m_view; //IView 的引用
protected IDictionary<string, Type> m_commandMap; //Command 类引用的(通知名)映射
protected static volatile IController m_instance; //接口实例
protected readonly object m_syncRoot = new object();//锁对象
protected static readonly object m_staticSyncRoot = new object();//静态锁

protected Controller(){
m_commandMap = new Dictionary<string, Type>();
InitializeController(); //初始化
}
static Controller() {}
public static IController Instance{
get{
if (m_instance == null){
lock (m_staticSyncRoot){
if (m_instance == null) m_instance = new Controller();
}
}
return m_instance;
}
}
protected virtual void InitializeController(){
m_view = View.Instance;
}
public virtual void ExecuteCommand(INotification note){
Type commandType = null;
lock (m_syncRoot){
if (!m_commandMap.ContainsKey(note.Name)) return;
commandType = m_commandMap[note.Name];
}
object commandInstance = Activator.CreateInstance(commandType);
if (commandInstance is ICommand){
((ICommand) commandInstance).Execute(note);
}
}
public virtual void RegisterCommand(string notificationName, Type commandType){
lock (m_syncRoot){
if (!m_commandMap.ContainsKey(notificationName)){
m_view.RegisterObserver(notificationName, new Observer("executeCommand", this));
}
m_commandMap[notificationName] = commandType;
}
}//RegisterCommand_end

public virtual bool HasCommand(string notificationName){
lock (m_syncRoot){
return m_commandMap.ContainsKey(notificationName);
}
}

public virtual void RemoveCommand(string notificationName){
lock (m_syncRoot){
if (m_commandMap.ContainsKey(notificationName)){
m_view.RemoveObserver(notificationName, this);
m_commandMap.Remove(notificationName);
}
}
}
}//Class_end
}


/*
核心层: 模型类
*/
namespace PureMVC.Core{
public class Model : IModel{
protected static volatile IModel m_instance; //本类实例
protected IDictionary<string, IProxy> m_proxyMap; //代理集合类
protected readonly object m_syncRoot = new object();//同步锁定对象(配合Lock关键字)
protected static readonly object m_staticSyncRoot = new object();//静态同步锁定对象

protected Model(){
m_proxyMap = new Dictionary<string, IProxy>();
InitializeModel();
}
static Model(){}

public static IModel Instance{
get{
if (m_instance == null){
lock (m_staticSyncRoot){
if (m_instance == null) m_instance = new Model();
}
}
return m_instance;
}
}
protected virtual void InitializeModel(){}

public virtual void RegisterProxy(IProxy proxy){
lock (m_syncRoot){
m_proxyMap[proxy.ProxyName] = proxy;
}
proxy.OnRegister();
}
public virtual IProxy RetrieveProxy(string proxyName){
lock (m_syncRoot){
if (!m_proxyMap.ContainsKey(proxyName)) return null;
return m_proxyMap[proxyName];
}
}
public virtual bool HasProxy(string proxyName){
lock (m_syncRoot){
return m_proxyMap.ContainsKey(proxyName);
}
}

public virtual IProxy RemoveProxy(string proxyName){
IProxy proxy = null;

lock (m_syncRoot){
if (m_proxyMap.ContainsKey(proxyName)){
proxy = RetrieveProxy(proxyName);
m_proxyMap.Remove(proxyName);
}
}
if (proxy != null) proxy.OnRemove();
return proxy;
}
}
}
/*
核心类: 视图层
*/
namespace PureMVC.Core{
public class View : IView{
protected IDictionary<string, IMediator> m_mediatorMap;//缓存IMediator实例集合
protected IDictionary<string, IList<IObserver>> m_observerMap;
protected static volatile IView m_instance;
protected readonly object m_syncRoot = new object();
protected static readonly object m_staticSyncRoot = new object();

protected View(){
m_mediatorMap = new Dictionary<string, IMediator>();
m_observerMap = new Dictionary<string, IList<IObserver>>();
InitializeView();
}

static View(){}

public static IView Instance{
get
{
if (m_instance == null)
{
lock (m_staticSyncRoot)
{
if (m_instance == null) m_instance = new View();
}
}
return m_instance;
}
}
protected virtual void InitializeView(){ }

public virtual void RegisterObserver(string notificationName, IObserver observer){
lock (m_syncRoot){
if (!m_observerMap.ContainsKey(notificationName)){
m_observerMap[notificationName] = new List<IObserver>();
}
m_observerMap[notificationName].Add(observer);
}
}


public virtual void NotifyObservers(INotification notification){
IList<IObserver> observers = null;
lock (m_syncRoot){
if (m_observerMap.ContainsKey(notification.Name)){
IList<IObserver> observers_ref = m_observerMap[notification.Name];
observers = new List<IObserver>(observers_ref);
}
}
if (observers != null){
// Notify Observers from the working array
for (int i = 0; i < observers.Count; i++){
IObserver observer = observers[i];
observer.NotifyObserver(notification);
}
}
}
public virtual void RemoveObserver(string notificationName, object notifyContext){
lock (m_syncRoot){
if (m_observerMap.ContainsKey(notificationName)){
IList<IObserver> observers = m_observerMap[notificationName];

for (int i = 0; i < observers.Count; i++){
if (observers[i].CompareNotifyContext(notifyContext)){
observers.RemoveAt(i);
break;
}
}
if (observers.Count == 0){
m_observerMap.Remove(notificationName);
}
}
}
}
public virtual void RegisterMediator(IMediator mediator){
lock (m_syncRoot){
if (m_mediatorMap.ContainsKey(mediator.MediatorName)) return;
m_mediatorMap[mediator.MediatorName] = mediator;
IList<string> interests = mediator.ListNotificationInterests();
if (interests.Count > 0){
IObserver observer = new Observer("handleNotification", mediator);
for (int i = 0; i < interests.Count; i++){
RegisterObserver(interests[i].ToString(), observer);
}
}
}
mediator.OnRegister();
}

public virtual IMediator RetrieveMediator(string mediatorName)
{
lock (m_syncRoot)
{
if (!m_mediatorMap.ContainsKey(mediatorName)) return null;
return m_mediatorMap[mediatorName];
}
}

public virtual IMediator RemoveMediator(string mediatorName){
IMediator mediator = null;
lock (m_syncRoot)
{
if (!m_mediatorMap.ContainsKey(mediatorName)) return null;
mediator = (IMediator) m_mediatorMap[mediatorName];

IList<string> interests = mediator.ListNotificationInterests();

for (int i = 0; i < interests.Count; i++){
RemoveObserver(interests[i], mediator);
}

m_mediatorMap.Remove(mediatorName);
}

if (mediator != null) mediator.OnRemove();
return mediator;
}

public virtual bool HasMediator(string mediatorName)
{
lock (m_syncRoot)
{
return m_mediatorMap.ContainsKey(mediatorName);
}
}
}
}


/*
Facade 核心入口类
*/
namespace PureMVC.Patterns{
public class Facade : IFacade{
protected IController m_controller;
protected IModel m_model;
protected IView m_view;
protected static volatile IFacade m_instance;
protected static readonly object m_staticSyncRoot = new object();

protected Facade() {
InitializeFacade();
}

public static IFacade Instance{
get{
if (m_instance == null){
lock (m_staticSyncRoot){
if (m_instance == null) m_instance = new Facade();
}
}
return m_instance;
}
}

static Facade(){}

protected virtual void InitializeFacade(){
InitializeModel();
InitializeController();
InitializeView();
}

public virtual void RegisterProxy(IProxy proxy){
m_model.RegisterProxy(proxy);
}

public virtual IProxy RetrieveProxy(string proxyName){
return m_model.RetrieveProxy(proxyName);
}
public virtual IProxy RemoveProxy(string proxyName){
return m_model.RemoveProxy(proxyName);
}

public virtual bool HasProxy(string proxyName){
return m_model.HasProxy(proxyName);
}

public virtual void RegisterCommand(string notificationName, Type commandType){
m_controller.RegisterCommand(notificationName, commandType);
}

public virtual void RemoveCommand(string notificationName){
m_controller.RemoveCommand(notificationName);
}

public virtual bool HasCommand(string notificationName){
return m_controller.HasCommand(notificationName);
}

public virtual void RegisterMediator(IMediator mediator){
m_view.RegisterMediator(mediator);
}

public virtual IMediator RetrieveMediator(string mediatorName){
return m_view.RetrieveMediator(mediatorName);
}

public virtual IMediator RemoveMediator(string mediatorName){
return m_view.RemoveMediator(mediatorName);
}

public virtual bool HasMediator(string mediatorName){
return m_view.HasMediator(mediatorName);
}

public virtual void NotifyObservers(INotification notification){
m_view.NotifyObservers(notification);
}

public virtual void SendNotification(string notificationName){
NotifyObservers(new Notification(notificationName));
}

public virtual void SendNotification(string notificationName, object body){
NotifyObservers(new Notification(notificationName, body));
}

public virtual void SendNotification(string notificationName, object body, string type){
NotifyObservers(new Notification(notificationName, body, type));
}

protected virtual void InitializeController(){
if (m_controller != null) return;
m_controller = Controller.Instance;
}

protected virtual void InitializeModel(){
if (m_model != null) return;
m_model = Model.Instance;
}

protected virtual void InitializeView(){
if (m_view != null) return;
m_view = View.Instance;
}
}
}























/***
* 简单命令类
*/
namespace PureMVC.Patterns{
public class SimpleCommand : Notifier, ICommand, INotifier{
public virtual void Execute(INotification notification){}
}
}
/*
* 大量命令类
*/
namespace PureMVC.Patterns{
public class MacroCommand : Notifier, ICommand, INotifier{
private IList<Type> m_subCommands;

public MacroCommand(){
m_subCommands = new List<Type>();
InitializeMacroCommand();
}

public virtual void Execute(INotification notification){
while (m_subCommands.Count > 0){
Type commandType = m_subCommands[0];
object commandInstance = Activator.CreateInstance(commandType);

if (commandInstance is ICommand){
((ICommand) commandInstance).Execute(notification);
}

m_subCommands.RemoveAt(0);
}
}

protected virtual void InitializeMacroCommand(){}

protected void AddSubCommand(Type commandType){
m_subCommands.Add(commandType);
}
}
}




/***
* 视图类
*/
namespace PureMVC.Patterns{
public class Mediator : Notifier, IMediator, INotifier{
protected string m_mediatorName;
protected object m_viewComponent;
public const string NAME = "Mediator";

public virtual string MediatorName{
get { return m_mediatorName; }
}
public virtual object ViewComponent{
get { return m_viewComponent; }
set { m_viewComponent = value; }
}

public Mediator()
: this(NAME, null){}
public Mediator(string mediatorName)
: this(mediatorName, null){}
public Mediator(string mediatorName, object viewComponent){
m_mediatorName = (mediatorName != null) ? mediatorName : NAME;
m_viewComponent = viewComponent;
}
public virtual IList<string> ListNotificationInterests(){
return new List<string>();
}

public virtual void HandleNotification(INotification notification){}
public virtual void OnRegister(){}
public virtual void OnRemove(){}

}
}









/*
通知类
*/
namespace PureMVC.Patterns{
public class Notification : INotification{
private string m_name;
private string m_type;
private object m_body;
public virtual string Name{
get { return m_name; }
}
public virtual object Body{
get{
return m_body;
}
set{
m_body = value;
}
}
public virtual string Type{
get{
return m_type;
}
set{
m_type = value;
}
}
public Notification(string name)
: this(name, null, null){ }
public Notification(string name, object body)
: this(name, body, null){ }
public Notification(string name, object body, string type){
m_name = name;
m_body = body;
m_type = type;
}
public override string ToString(){
string msg = "Notification Name: " + Name;
msg += "\nBody:" + ((Body == null) ? "null" : Body.ToString());
msg += "\nType:" + ((Type == null) ? "null" : Type);
return msg;
}
}
}
/*
通知者类
*/

using System;
using PureMVC.Interfaces;
using PureMVC.Patterns;

namespace PureMVC.Patterns
{
public class Notifier : INotifier
{
private IFacade m_facade = PureMVC.Patterns.Facade.Instance;

protected IFacade Facade{
get { return m_facade; }
}

public virtual void SendNotification(string notificationName) {
m_facade.SendNotification(notificationName);
}
public virtual void SendNotification(string notificationName, object body){
m_facade.SendNotification(notificationName, body);
}

public virtual void SendNotification(string notName, object body, string type){
m_facade.SendNotification(notName, body, type);
}
}
}














/* 观察者类 */
namespace PureMVC.Patterns{
public class Observer : IObserver{
private string m_notifyMethod; //通知方法名称
private object m_notifyContext; //通知上下文
protected readonly object m_syncRoot = new object(); //锁定
public virtual string NotifyMethod{
private get{
return m_notifyMethod;
}
set{
m_notifyMethod = value;
}
}
public virtual object NotifyContext{
private get{
return m_notifyContext;
}
set{
m_notifyContext = value;
}
}
public Observer(string notifyMethod, object notifyContext){
m_notifyMethod = notifyMethod;
m_notifyContext = notifyContext;
}
public virtual void NotifyObserver(INotification notification){
object context;
string method;
lock (m_syncRoot){
context = NotifyContext;
method = NotifyMethod;
}
Type t = context.GetType();
BindingFlags f = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase;
MethodInfo mi = t.GetMethod(method, f);
mi.Invoke(context, new object[] { notification });
}
public virtual bool CompareNotifyContext(object obj){
lock (m_syncRoot){
return NotifyContext.Equals(obj);
}
} }}
/*
代理类
*/

using System;
using PureMVC.Interfaces;
using PureMVC.Patterns;

namespace PureMVC.Patterns{
public class Proxy : Notifier, IProxy, INotifier{
protected string m_proxyName;
protected object m_data;
public static string NAME = "Proxy";

public virtual string ProxyName{
get { return m_proxyName; }
}

public virtual object Data{
get { return m_data; }
set { m_data = value; }
}

public Proxy()
: this(NAME, null){}
public Proxy(string proxyName)
: this(proxyName, null){}
public Proxy(string proxyName, object data){
m_proxyName = (proxyName != null) ? proxyName : NAME;
if (data != null) m_data = data;
}

public virtual void OnRegister(){}
public virtual void OnRemove(){}
}
}
------------------------------------------(接口)--------------------------------------------
namespace PureMVC.Interfaces
{
public interface ICommand
{
void Execute(INotification notification);
}
}
namespace PureMVC.Interfaces{
public interface IProxy
{
string ProxyName { get; }
object Data { get; set; }
void OnRegister();
void OnRemove();
}
}
namespace PureMVC.Interfaces{
public interface IView{
void RegisterObserver(string notificationName, IObserver observer);
void RemoveObserver(string notificationName, object notifyContext);
void NotifyObservers(INotification note);
void RegisterMediator(IMediator mediator);
IMediator RetrieveMediator(string mediatorName);
IMediator RemoveMediator(string mediatorName);
bool HasMediator(string mediatorName);
}
}
namespace PureMVC.Interfaces{
public interface IObserver{
string NotifyMethod { set; }
object NotifyContext { set; }
void NotifyObserver(INotification notification);
bool CompareNotifyContext(object obj);
}
}
namespace PureMVC.Interfaces{
public interface INotifier{
void SendNotification(string notificationName);
void SendNotification(string notificationName, object body);
void SendNotification(string notificationName, object body, string type);
}
}
namespace PureMVC.Interfaces{
public interface INotification{
string Name { get; }
object Body { get; set; }
string Type { get; set; }
string ToString();
}
}

namespace PureMVC.Interfaces{
public interface IModel{
void RegisterProxy(IProxy proxy);
IProxy RetrieveProxy(string proxyName);
IProxy RemoveProxy(string proxyName);
bool HasProxy(string proxyName);
}
}
namespace PureMVC.Interfaces{
public interface IMediator{
string MediatorName { get; }
object ViewComponent { get; set; }
IList<string> ListNotificationInterests();
void HandleNotification(INotification notification);
void OnRegister();
void OnRemove();
}
}
namespace PureMVC.Interfaces{
public interface IFacade : INotifier{
void RegisterProxy(IProxy proxy);
IProxy RetrieveProxy(string proxyName);
IProxy RemoveProxy(string proxyName);
bool HasProxy(string proxyName);
void RegisterCommand(string notificationName, Type commandType);
void RemoveCommand(string notificationName);
bool HasCommand(string notificationName);
void RegisterMediator(IMediator mediator);
IMediator RetrieveMediator(string mediatorName);
IMediator RemoveMediator(string mediatorName);
bool HasMediator(string mediatorName);
void NotifyObservers(INotification note);
}
}
namespace PureMVC.Interfaces{
public interface IController{
void RegisterCommand(string notificationName, Type commandType);
void ExecuteCommand(INotification notification);
void RemoveCommand(string notificationName);
bool HasCommand(string notificationName);
}
}