ANDROID 中设计模式的采用--行为模式



1 职责链模式

      职责链模式的意图为:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。职责链模式的结构图如下:

 

    在ANDROID的输入管理系统中提交输入事件到视图时使用了职责链模式,其类图所示:





     类图中的ViewRootImpl类的内部类EarlyPostImeInputStageNativePostImeInputStageViewPostImeInputStageSyntheticInputStage构成一个输入事件责任处理链,用来分阶段处理输入事件,如果本阶段对事件没有处理,则传递到下一个对象进行处理,直至事件被处理。


2、命令模式

     命令模式的意图为:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。命令模式的结构图如下:

   


   ANDROID系统中命令模式用的也比较多,如在事件输入系统中,在InputDispatcher对象转发事件过程中就采用了命令模式:把每一个输入事件封装为类型为NotifyArgs的对象,不同的事件对应NotifyArgs类的不同子类,如按键事件对应NotifyKeyArgs类,触摸事件对应NotifyMotionArgs类,而NotifyArgs命令的接收对象为InputDispatcher,因此通过事件命令的执行把事件本身转发给InputDispatcher对象,实现事件的提交。相关模式类图如下:

         


3  解释器模式

    解释器模式的意图为:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。解释器模式的结构图如下:

    

 

      在android系统中,包管理服务对应用包的解析使用了解释器模式。

      包管理服务采用PackageParser类来负责应用包的解析,PackageParser类使用了解释器模式对一个应用包进行解释,对于应用包中的每种语法结构都创建了对应的类,来分别搜集应用包中的相应信息。类结构图如下:

        图中除了ResourcesXmlPullParser两个类外其余的类都是PackageParser类的内部类,应用包中的每个语法结构对应的类都派生自componet类且属于componet类的内部成员,Package类(一个包一个Package对象)是一个聚合类,用来把解析出来的一个应用包中的componet信息聚合到Package类中进行统一管理,PackageParser类将解析出的每个componet信息添加到Package


4 、迭代器模式


     迭代器模式的意图为:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。迭代器模式的结构图如下:

    

        迭代器模式是个普遍使用的模式,JAVA的集合类库(列表,集合,映射、字典,有序集,字符串等)都以不同的形式提供了迭代器,用来对集合类中的元素进行遍历


5、中介者模式

      中介者模式的意图为:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式的结构图如下:

     

 

     ANDROID系统中keyguard的功能实现采用了中介者模式,用来中介keyguard相关的请求,包括查询keyguard的状态,影响keyguard应当显示和复位的电源管理事件,以及当keyguard显示时对窗口管理的通知事件和来自keyguard视图本身的关于keyguard是否成功unlocked的事件等。相关UML类图如下:

     

      其中KeyguardViewMediator作为中介者角色,与电源管理、用户管理、报警管理、声音管理、状态条管理、KeyguardViewManagerKeyguardDisplayManagerKeyguardUpdateMonitor等服务或对象交互, 读取相关状态,执行和触发keyguard事件相关的功能等 ,而KeyguardViewManagerKeyguardHostViewKeyguardUpdateMonitor类通过相关回调向KeyguardViewMediator传送Keyguard视图本身和keyguard有关状态更新方面的事件, 另外KeyguardService服务也是通过KeyguardViewMediator查询keyguard的状态 并通过IKeyguardService接口对外提供keyguard的状态信息。


6 备忘录模式

     备忘录模式的意图为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。备忘录模式的结构图如下:

     


      在ANDROID系统中有不少采用备忘录模式的例子,如ACTIVITY活动状态的保存和恢复就是采用备忘录模式的一个例子。

      在一个活动暂停或停止时调用活动的onSaveInstanceState(Bundle outState)函数把ACTIVITY的当前状态保存到Bundle对象中,活动恢复或重新启动时调用活动的onRestoreInstanceState(Bundle savedInstanceState)函数恢复到原先状态。


7、观察者模式

      观察者模式的意图为:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式的结构图如下:

     

 

      观察者模式也称发布-订阅者模式,可以实现目标和多个观察者间的松散耦合,并支持广播通信,是最常用的设计模式之一。  

       在ANDROID系统中观察者模式也是普遍采用,观察者模式提供了ANDROD架构连接件的基础,在系统提供的广播组件及内容提供者组件、通知服务中以及视图控件和底层事件监听、UI事件输入等许多方面普遍采用。

       观察者模式也是MVC模式的实现基础,M VC中的M o d e l类担任目标的角色,Vi e w担任观察者的角色。


8、状态模式

     状态模式的意图为:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。状态模式的结构图如下:

    

 

      状态模式在ANDROID系统中用的也比较多,尤其在数据连接、WIFI、蓝牙等网络连接和状态管理方面。

      如在WIFI管理方面,就提供了WifiStateMachineP2pStateMachineWifiControllerWifiApConfigStoreWifiWatchdogStateMachine五个状态机来管理WIFI相关功能的不同状态。每个状态机对象在状态模式中起到Context作用,用来汇聚相关状态,启动状态执行等。

     ANDROID系统中每个状态机管理的状态都派生自State类,State类是IState接口的实现。

     WifiApConfigStore管理的状态图如下:

    


9、策略模式

      策略模式的意图为:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。策略模式的结构图如下:

  

   策略模式也是经常使用的模式,在ANDROID系统的几乎每个子系统中都有策略模式使用的影子,如窗口管理服务中提供窗口管理相关策略的WindowManagerPolicy接口对象;输入管理系统中提供输入事件读取和提交策略的InputReaderPolicyInterfacePointerControllerPolicyInterface接口对象,以及输入事件映射算法等;声音相关服务中提供声音输入和输出配置和激活策略的AudioPolicyInterface接口对象;网络管理相关服务中提供网络统计匹配策略的NetworkPolicy对象等。


10、模板方法模式

       模板方法模式的意图为:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Te m p l a t e M et h o d使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法模式的结构图如下:

    

 

      模板方法模式和观察者模式一样也是最常用的设计模式之一,模板方法非常基本,几乎可以在任何一个抽象类中找到。工厂方法也是采用模板模式创建对象的特例。

      在ANDROID系统中模板方法模式更是作为整个系统框架的基础和核心,为应用程序组件运行(包括ACTIVITYSERVICEBroadcastreceiver提供了大的运行骨架,应用程序只需在应用组件的派生类中重新实现钩子函数(模板方法),即可以实现应用程序的客制化功能,这样既可以实现多样化的应用,又能够使应用程序开发遵循同样的框架API


11、访问者模式

       访问者模式意图为:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式的结构图如下:

    


 

      访问者模式在ANDROID系统中也有使用,如输入管理服务中在调用getKeyboardLayout(String keyboardLayoutDescriptor)函数来获得键盘布局时,就使用了访问者模式。getKeyboardLayout函数调用visitKeyboardLayout(StringkeyboardLayoutDescriptor,KeyboardLayoutVisitor visitor)函数通过包管理服务来查询每个包,在应用包中发现keyboard-layout元素时, 就调用访问者的visitKeyboardLayout函数来根据发现的keyboard-layout元素创建一个KeyboardLayout键盘布局对象。


                                版权所有,请转载时清楚注明链接和出处,谢谢!




















分析MFC的设计模式-----行为模式

07-26

这篇文章时,试图查阅一些中文资料,结果却很令人失望,我几乎找不到一篇介绍mfc设计模式的文章,所以,我写了以下的这些内容,还望批评指正。rn 职责链在MFC中的应用rn 在mfc中,消息如果是从子类流向父类(纵向流动),那么事情再简单不过,整个Message Map消息映射表已规划出十分明确的路线。但MFC 之中用来处理消息的C++ 类别并不呈单线发展,作为application framework 的重要结构之一的文档/视图结构,也具有处理消息的能力,因此,消息应该有横向流动的机会。MFC 对于消息循环的规定是:rn 1.如果是一般的Windows 消息(WM_xxx),一定是由派生类别流向基础类别,没有旁流的可能。rn 2.如果是命令讯息WM_COMMAND,就有奇特的路线了,这个路线将会在下面结合Chain of Resposibility(职责链)予以介绍。rn MFC中,命令的映射就是一个Chain of Resposibility(职责链)。在MFC中,用户接口命令是以命令消息的形式被处理的。CcmdTarget类是所有可以接受和处理消息的类的父类。它提供消息映射表接口,可以把映射的消息ID对应于相关的消息处理器。一个命令消息在职责链中的类传递,直到其中一个为她提供了处理器为止。rn 在MFC中,先由CwinApp类获得消息,并且把它们分派到适合的窗口。大多数的命令消息被发送给应用程序的主桢窗口类来处理。传送的不同顺序是根据不同的消息类型由类库预先确定的。rnStandard Command Route in MFC:(图形无法输入)rnrnrn例如,在一个多文档应用程序中,一个菜单命令被选中,则消息沿着以下的链传递:rn1. 主桢窗口rn2. 主桢窗口传递消息到当前活动的多文档的子窗口rn3. 多文档子窗口在检查她自己的消息映射表前把消息传送给她所对应的视图类,4. 看是否有相应的处理器。rn5. 视图类检查她自己的消息映射表,6. 如果没有对应的处理器则她把消息返回给她所对应的文档类。rn文档/视图模式的标准信息传递rn7. 文档类检查她自己的消息映射表,8. 如果没有对应的处理器则将消息返回给她所对应的文档模版。rn9. 文档类模版如果仍然不10. 能处理,11. 则返回消息倒视图类模版,12. 如果还不13. 能处理,14. 则依次返回到主桢窗口类和应用程序。rn当消息一找到他所对应的消息处理器时,她就结束消息传递。rn待续!

分析MFC的设计模式-----行为模式(2)

07-31

很高兴那么多人回复。的确,mfc确实不是一个很好的应用程序框架,毕竟它出现的比较早,但是它应用的最广泛,所以我们需要研究它,然后将这些模式应用于利用mfc进行软件开发中,可以让自己写的代码和应用程序框架融为一个整体,一就是说有一样的风格,这样很好。我还要说的是我分析的是行为模式,其他模式一样道理分析,只是要求你对mfc的运行及实现机制很熟悉才可以。的确,深入浅出里有很多东西属于设计模式的,应该是侯隽解用的设计模式,而不是设计模式利用的侯俊杰的技术吧。rn今天我想顺着上一篇再占写东西,还往指正rn迭代器(Iterator)rn2.2.1迭代器简介rn1. 意图rn提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。rn2.结构(无法输入图)rn6. 参与者rnI t e r a t o r(迭代器)rn— 迭代器定义访问和遍历元素的接口。rnC o n c r e t e I t e r a t o r(具体迭代器)rn— 具体迭代器实现迭代器接口。rn— 对该聚合遍历时跟踪当前位置。rnA g g r e g a t e(聚合)rn— 聚合定义创建相应迭代器对象的接口。rnC o n c r e t e A g g r e g a t e(具体聚合)rnrn— 具体聚合实现创建相应迭代器的接口,该操作返回C o n c r e t e I t e r a t o r的一个适当的实例。rn2.2.2迭代器在MFC中的应用rnMFC具有以下聚集类:rnCArray----用于构成任意类型数组的模版类rnCList------用于构成任意类型线性表的模版类rnCMap------用于构成任意类型图的模版类rnCTypedPtrArray----用于构成安全类型的数组指针的模版类rnCTypedPtrarray-----用于构成安全类型的线性表指针的模版类rnCTypedPtrmap-----用于构成安全类型的图指针的模版类。rn例子:rn用成员函数GetAt实现用索引数字来重新表示数组的代码:rnCTypedPtrArray myArray;rnfor( int i = 0; i < myArray.GetSize();i++ )rnrn CPerson* thePerson = myArray.GetAt( i );rn ...rnrn用成员函数GetHeadPosition和GetNext来重新表述线性表的代码:rnCTypedPtrList myList;rnPOSITION pos = myList.GetHeadPosition();rnwhile( pos != NULL )rnrn CPerson* thePerson = myList.GetNext( pos );rn ...rnrn用成员函数GetStartPosition来得到图的开始节点,用成员函数GetNextAssoc 得到当前节点相邻的数个节点。代码如下所示::rnCMap myMap;rnPOSITION pos = myMap.GetStartPosition();rnrnwhile( pos != NULL )rnrn CPerson* pPerson;rn CString string;rn // Get key ( string ) and value ( pPerson )rn myMap.GetNextAssoc( pos, string, pPerson );rn // Use string and pPersonrnrn这一模式的关键思想是将对列表的访问和遍历从列表对象中分离出来并放入一个迭代器对象中,以上代码充分说明了MFC正是这样做的。

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试