PureMvc个人笔记

学习资料:pureMv中文指南,C++ puremvc代码



根据图示,顺着信息流动的途径,应该从facede入手,接着controller,控制command,command操控proxy与mediation,形成一个信息闭环。书籍参考指南的顺序很难给读者一个清晰的框架认识,个人如此认为。指南从基础的view,model,controller等基础开始,并没有从整体勾勒。个人认为应该先从整体大概把握整体架构,比如:主体循环如何执行,如何将三个核心部分组合,如何将组件结合,顺着线索,步步深入代码如何执行。

一、PureMvc结构

在PureMVC实现的经典MVC元设计模式中,这三部分由三个单例模式类管理,分别是Model、View和Controller。PureMVC中还有另外一个单例模式类——Façade,Façade提供了与核心层通信的唯一接口。

进入代码:

1.Facade代码

遇到explicit

http://www.cnblogs.com/cutepig/archive/2009/01/14/1375917.html

facade为单例模式

<span style="font-family:Microsoft YaHei;font-size:10px;">        public:
            /**
             * Facade Multiton Factory method
             *
             * @return the Multiton instance of the Facade
             */
            static IFacade& getInstance(std::string const& key = Facade::DEFAULT_KEY);
</span>
在facade代码中初始化等函数都放入project进行保护,习惯很好,注意学习。

对Core中的三个核心部分保持引用

<span style="font-family:Microsoft YaHei;font-size:10px;">        protected:
            // References to Model, View and Controller
            IController* _controller;
            IModel* _model;
            IView* _view;
            // Message Constants
            static char const* const MULTITON_MSG;
</span>
使用的是面对接口编程。

代码中基本定义的是后面子类需要定义的函数,后面使用的时候,用的是“I”文件代码,具体的实现的类调用的是虚函数,虚函数在具体类中实现,这样就进行了解耦。

2.model代码

其中再次遇到multiton多例模式,http://blog.csdn.net/hsyj_0001/article/details/648033

类似于facade同样采用的是多例模式的做法。

<span style="font-family:Microsoft YaHei;font-size:10px;">IModel& Model::getInstance(std::string const& key)
{
    IModel* result = puremvc_model_instance_map.find(key) ;
    if (result == NULL)
    {
        result = new Model(key);
        puremvc_model_instance_map.insert(std::make_pair(key, result));
    }
    return *result;
}
</span>
同时保留对proxy的引用

<span style="font-family:Microsoft YaHei;font-size:10px;">            // Mapping of proxyNames to IProxy instances
            ProxyMap _proxy_map;</span>
Proxy负责操作数据模型,与远程服务通信存取数据。具体作用细则还需看源代码。

3.View代码

<span style="font-family:Microsoft YaHei;font-size:10px;">            typedef std::tr1::unordered_map<std::string, IMediator*> MediatorMap;
            typedef std::tr1::unordered_multimap<std::string, IObserver*> ObserverMap;
</span>

View保存对Mediator对象的引用。

在注册mediation中,调用代码

    while(iter->moveNext())
    {
        // Register Mediator as Observer for its list of Notification interests
        // Create Observer referencing this mediator's handlNotification method
        IObserver *observer = createObserver(&IMediator::handleNotification, mediator);
        puremvc_observer_instance_map.insert(observer);
        registerObserver(iter->getCurrent(), observer);
    }

同时也会在mediation_map中进行注册。

需要仔细阅读view registerobserved函数,其中observ注册函数采用多维map。

4.control代码

基本类型与模式都与其他核心模块一样,核心模块部分都采取一样的架构。

总结下,保持的引用的用处不明,虽有说明,但是脉络依旧不清晰。



5.Observer 与 Notification

采用的是观察者模式,观察者模式的定义是:有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

http://www.cnblogs.com/wangjq/archive/2012/07/12/2587966.html

6.Mediation

        protected:
            // the mediator name
            std::string _mediator_name;
            // The view component
            void const* _view_component;
        public:
            static char const* const NAME;
保留了view的引用。
继承于
            : public virtual IMediator
            , public virtual INotifier
            , public Notifier

7.转化View Component类型

跟随源代码可以看到,从mediator存入的component组件都是void指针形式,可以自主定义方法get,使用类型转换获取正确的类型,方便获取。

8.Proxy

Proxy从本质上来说是Model对外的接口,与外界操作剥离,实现数据部分独立。所有的proxy都存储在model中的map中,方便facade自由存取,facade获取proxy之后就能很方便的使用proxy提供的方法进行操作了。下面我还会在消息机制中提供一张图,里面有proxy存取的路径,可以参考一下。每个proxy可以设置一个void指针,用来专门存储数据指针,setdata或者在构造函数中添加。Proxy管理的是域逻辑操作,比如说游戏中球的位置,速度,加速度变化,与其他物体碰撞等等域逻辑都应该放在proxy中,属于域模型中的规则体现。

8.关于消息机制

这里快接近尾声了,总结一下学习这个框架的经验,其实直接看书的效率不高,最适合的方法是结合源代码边看书边看代码实现,成效居高,基本一遍过大概,两遍开始通,三四遍后。。。。。

PureMVC文档到后面部分主要就是消息机制的内容,跟随代码,注册与通知大体结构.


二、代码解释

1.Pattern

Observer:

Notification 消息,相当于信封中存放的信,包含需要传输的信息。

class Notification : public INotification
{

    public:

        /**
         * 构造函数
         * 
         * @param name name of the <code>Notification</code> instance. (required)
         * @param body the <code>Notification</code> body. (optional)
         * @param type the type of the <code>Notification</code> (optional)
         */
		explicit Notification(Notification const& arg);

		Notification(std::string const& name, void const* body = NULL, std::string const& type = "");

        /**
         * 获取notifacation的名字,在每次生成时都有对应的名字。
         * 
         * @return the name of the <code>Notification</code> instance.
         */
       virtual std::string getName() const; 

        /**
         * 获取notification上所绑定的void指针,用于传递任意对象。
         */
        virtual void setBody( void* body );

        /**
         * Get the body of the <code>Notification</code> instance.
         * 
         * @return the body object. 
         */
        virtual void*  getBody();

        /**
         * Set the type of the <code>Notification</code> instance.
         */
        virtual void setType( const std::string & type);

        /**
         * Get the type of the <code>Notification</code> instance.
         * 
         * @return the type  
         */
        virtual std::string getType();

        /**
         * Get the string representation of the <code>Notification</code> instance.
         * 
         * @return the string representation of the <code>Notification</code> instance.
         */
        virtual std::string toString() const;

		Notification& operator=(Notification const &arg);

		virtual ~Notification();
    private:
        // the name of the notification instance
        std::string m_name;
        // the type of the notification instance
        std::string m_type;
        // the body of the notification instance
        void*  m_body;
};


Notifier  传输者


class Notifier : public virtual INotifier
{
    /**
     * 创造并且发送Notification 消息
     * 
     * <P>
     * Keeps us from having to construct new INotification 
     * instances in our implementation code.
     * @param notificationName the name of the notiification to send
     * @param body the body of the notification (optional)
     * @param type the type of the notification (optional)
     */ 
    public:
		explicit Notifier();
        virtual ~Notifier();
<span style="white-space:pre">		</span>// 创造并发送消息
		virtual void sendNotification(std::string const& notification_name, void const* body = NULL, std::string const& type = "");
	
// 		virtual void sendNotificationTo(const INotification& ,ObserverMediators&) 
// 		{
// 
// 		}

		virtual void initializeNotifier(std::string const& key);
	
		virtual std::string const& getMultitonKey(void) const;

		Notifier& operator=(Notifier const& arg);

        // Local reference to the Facade Singleton
    protected:
		IFacade& getFacade();

        IFacade * m_facade ;

		std::string _multiton_key;

};

Observer 观察者 用于接收消息,当消息被发送之后,就去遍历观察者数组。其中存储了关注的消息被触发后需要执行的函数,执行函数的主体,内容。

template<typename _Method ,typename _Context>
class Observer : public IObserver
{


    /**
     * Constructor. 
     * 
     * <P>
     * The notification method on the interested object should take 
     * one parameter of type <code>INotification</code></P>
     * 
     * @param notifyMethod the notification method of the interested object
     * @param notifyContext the notification context of the interested object
     */
    public:
<span style="white-space:pre">		</span>explicit Observer(Observer const &atg)
<span style="white-space:pre">			</span>:IObserver()
<span style="white-space:pre">			</span>,_notify_method(arg._notify_method)
<span style="white-space:pre">			</span>,_notify_context(arg._notify_context)
<span style="white-space:pre">		</span>{}


<span style="white-space:pre">		</span>explicit Observer(_Method notify_method, _Context* notify_context)
<span style="white-space:pre">			</span>: IObserver()
<span style="white-space:pre">			</span>, _notify_method(notify_method)
<span style="white-space:pre">			</span>, _notify_context(notify_context)
<span style="white-space:pre">		</span>{ }


        virtual ~Observer(){}
        /**
         * Set the notification method.
         * 
         * <P>
         * The notification method should take one parameter of type <code>INotification</code>.</P>
         * 
         * @param notifyMethod the notification (callback) method of the interested object.
         */
<span style="white-space:pre">		</span>virtual void notifyObserver(INotification const& notification)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>if (_notify_context == NULL)
<span style="white-space:pre">				</span>throw std::runtime_error("Notify context is null.");
<span style="white-space:pre">			</span>if (_notify_method == NULL)
<span style="white-space:pre">				</span>throw std::runtime_error("Notify method is null.");
<span style="white-space:pre">			</span>(*_notify_context.*_notify_method)(notification);
<span style="white-space:pre">		</span>}


        /**
         * Set the notification context.
         * 
         * @param notifyContext the notification context (this) of the interested object.
         */
<span style="white-space:pre">		</span>virtual bool compareNotifyContext(void const* object) const
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>return _notify_context == object;
<span style="white-space:pre">		</span>}


<span style="white-space:pre">		</span>Observer& operator=(Observer const& arg)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>_notify_method = arg._notify_method;
<span style="white-space:pre">			</span>_notify_context = arg._notify_context;
<span style="white-space:pre">			</span>return *this;
<span style="white-space:pre">		</span>}








    private :
<span style="white-space:pre">		</span>_Method _notify_method;
<span style="white-space:pre">		</span>_Context* _notify_context;
};


        /**
         * Create new observer.
         */
        template<typename _Method, typename _Context>
        inline IObserver* createObserver(_Method notify_method, _Context* notify_context)
        {
            return new Observer<_Method, _Context>(notify_method, notify_context);
        }


        /**
         * Make an observer.
         */
        template<typename _Method, typename _Context>
        inline Observer<_Method, _Context> makeObserver(_Method notify_method, _Context* notify_context)
        {
            return Observer<_Method, _Context>(notify_method, notify_context);
        }

Command:

simpleCommand 简单的命令,其中只存储了命令被触发时需要执行的函数execute。

class SimpleCommand :public virtual INotifier,public  virtual ICommand ,public Notifier 
{
    public:

        /**
         * Fulfill the use-case initiated by the given <code>INotification</code>.
         * 
         * <P>
         * In the Command Pattern, an application use-case typically
         * begins with some user action, which results in an <code>INotification</code> being broadcast, which 
         * is handled by business logic in the <code>execute</code> method of an
         * <code>ICommand</code>.</P>
         * 
         * @param notification the <code>INotification</code> to handle.
         */
        virtual void execute( const INotification & notification);

		virtual ~SimpleCommand(){}
};

macrocommand :一种比较复杂的命令,可以存储一系列简单的命令,macrocommand被触发后,依次执行所存储的simplecommand。

// 添加simplecommand到数组列表中        
virtual void addSubCommand( ICommand *pCmd );

        /** 
         * Execute this <code>MacroCommand</code>'s <i>SubCommands</i>.
         * 
         * <P>
         * The <i>SubCommands</i> will be called in First In/First Out (FIFO)
         * order. 
         * 
         * @param notification the <code>INotification</code> object to be passsed to each <i>SubCommand</i>.
         */
// 依次执行数组中的simplecommand
        virtual void execute(INotification const& notification);


Mediator

class Mediator : public virtual IMediator ,public virtual INotifier ,public Notifier
{
    public:

        /**
         * Constructor.
         */

		explicit Mediator(Mediator const& arg);

		Mediator(const std::string & mediatorName="", void * viewComponent=NULL ); 

		virtual ~Mediator();

        /**
         *每个mediator都有各自的名字
         * @return the Mediator name
         */		
		virtual std::string getName();
        /**
         * Set the <code>IMediator</code>'s view component.
         * 
         * @param Object the view component
         */
        void setViewComponent( void * viewComponent );
        /**
         * 设置mediator组件
         * 
         * 
         * @return the view component
         */		
        void *  getViewComponent();

        /**
         * 返回Mediator所关心的信息
         * <code>Mediator</code> is interested in being notified of.
         * 
         * @return Array the list of <code>INotification</code> names 
         */
        Interests listNotificationInterests();

        /**
         * 当所关心的信息被触发时 执行的函数。
         * 
         */ 
        virtual void handleNotification( const INotification & notification) ;

        /**
         * 当被注册的时候,调用
         */ 
        virtual void onRegister( );

        /**
         * 当被移除的时候调用
         */ 
        virtual void onRemove( );

		Mediator& operator=(Mediator const& arg);


        // the mediator name
    protected:

        std::string m_mediatorName;

        // The view component
        void * m_viewComponent;

};








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值