PureMvc个人笔记

来源:互联网 发布:mac 使用oracle 编辑:程序博客网 时间:2024/06/12 23:51

学习资料: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
原创粉丝点击