- 浏览: 13426810 次
- 性别:
- 来自: 大连
-
文章分类
最新评论
-
sanrenxing_1:
GoEasy 实时推送支持IE6-IE11及大多数主流浏览器的 ...
WindowsPhone消息推送服务 -
张砚辉:
两侧照片绕Y轴旋转后有锯齿,请问锯齿解决方案,很长时间没解决
自定义带倒影和偏转的超炫Gallery -
knight_black_bob:
能不能把你自己的博客整理下分类下,写了这么多 ,都不知道怎么查 ...
Android_View,ViewGroup,Window之间的关系 -
jeasonyoung:
你这个代码实现在iOS8下应该是滑不动的
UISlider 滑块控件—IOS开发 -
wx_hello:
如果能写个可运行的java程序,不胜感激。。。
rs232串口通信原理
运行时看常用的几种设计模式——Design Patterns in Run-time View
运行时看常用的几种设计模式
——Design Patterns in Run-time View
田海立,系统分析师
<chsdate isrocdate="False" islunardate="False" day="7" month="11" year="2005" w:st="on"><span lang="EN-US">2005</span><span style="font-family: 宋体;">年</span><span lang="EN-US">11</span><span style="font-family: 宋体;">月</span><span lang="EN-US">7</span><span style="font-family: 宋体;">日</span></chsdate>
摘要
设计模式是软件设计智慧的结晶,但是它们也有应用前提和使用限制。本文从运行时的视角,分析了多进程环境下使用几种常用设计模式的注意点。
关键词:设计模式,运行时,单例模式,侦听者模式
Keywords: Design Patterns, Run-time, Singleton Pattern, Listener Pattern
目 录
摘要... <!--[if supportFields]><span style='mso-bookmark:_Toc114228448'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Toc114228448'><span lang=EN-US style='color:windowtext; display:none;mso-hide:screen;mso-no-proof:yes;text-decoration:none;text-underline: none'> PAGEREF _Toc119238574 /h </span></span><span style='mso-bookmark:_Toc114228448'><span lang=EN-US style='color:windowtext;mso-no-proof:yes;text-decoration:none; text-underline:none'><span style='display:none;mso-hide:screen'><span style='mso-element:field-separator'></span></span></span></span><![endif]-->1<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100310039003200330038003500370034000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='mso-bookmark: _Toc114228448'></span><span style='mso-element:field-end'></span><![endif]--><!--[if supportFields]><span style='mso-bookmark:_Toc114228448'></span><span style='mso-element:field-begin'></span><span style='mso-bookmark:_Toc114228448'><span lang=EN-US><span style='mso-spacerun:yes'></span>TOC /o "1-3" /h /z /u <span style='mso-element:field-separator'></span></span></span><![endif]-->
<!--[if supportFields]><span style='mso-bookmark:_Toc114228448'></span><span style='mso-element:field-end'></span><![endif]-->
一、设计模式
设计模式是什么?对不起,我也不记得它的确切定义,也许本来就没打算记住。即便有它“官方的”定义,看那定义半天也不一定能准确理解它的含义,过后不记得它也就很正常了。不过《Software Architect Bootcamp》上对关于它的“rule of three”描述我却记得非常清楚:解决某个特定问题所采取的设计,‘一次出现是偶然现象,两次是巧合,三次出现就是一个模式了’。所以用我的话说,就可以这么理解设计模式了,设计模式就是前人(当然是一头牛或者是一群牛了,比如GOF)对某个特定问题所经常采用的解决方案的总结,而这个设计是被实践反复证明合理的。因为设计模式是由权威的大师提出来,并被业界普遍接受,所以它也就成了交流的手段,在双方都很好地理解设计模式的情况下,对设计的交流就只需只言片语,而不是长篇大论还可能有交流的误区。
参考资料中GOF的著作是设计模式领域当之无愧的“圣经”,经过十年岁月的洗礼,现在仍然是亚马逊网上书店销量榜上的亚军(资料来源:《程序员》2005年11期,笔者并未进行证实)。设计模式在现在的软件系统中被普遍采用,你要看最近出现的软件的框架之类的东西,如果不懂设计模式恐怕是进行不下去的。我这里不赘述那些设计模式,而从进程视角(Process View是RUP中的概念,不过一般的软件架构模型中也都有类似的概念,可能的名字有Siemens常用架构的PIPE View或者CMU/SEI的Component-Connector View),探讨一下常用设计模式应用时应该注意的地方,这些模式在嵌入式系统多进程环境中被普遍采用,但应该注意这种环境下的特殊性。
二、运行时看常用设计模式
2.1 Singleton(单例)模式
单例模式设计的意图(Intent)是“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”为了保证Singleton实例的唯一性,Singleton里定义一个类成员(有些实现语言不是这个概念)uniqueInstance,而把构造函数的修饰符声明成private或者protected(为了派生),使得别人无法通过它构造出一个新实例,而要得到一个Singleton的实例的话,必须通过Singleton暴露的getInstance()方法。
<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600"
o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f"
stroked="f">
<v:stroke joinstyle="miter"/>
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0"/>
<v:f eqn="sum @0 1 0"/>
<v:f eqn="sum 0 0 @1"/>
<v:f eqn="prod @2 1 2"/>
<v:f eqn="prod @3 21600 pixelWidth"/>
<v:f eqn="prod @3 21600 pixelHeight"/>
<v:f eqn="sum @0 0 1"/>
<v:f eqn="prod @6 1 2"/>
<v:f eqn="prod @7 21600 pixelWidth"/>
<v:f eqn="sum @8 21600 0"/>
<v:f eqn="prod @7 21600 pixelHeight"/>
<v:f eqn="sum @10 21600 0"/>
</v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
<o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:415.5pt;
height:121.5pt'>
<v:imagedata src="file:///C:/DOCUME~1/TIANHL~1/LOCALS~1/Temp/msohtml1/01/clip_image001.emz"
o:title=""/>
</v:shape><![endif]--><!--[if !vml]-->
<!--[endif]-->
上面简要介绍了Singleton模式的设计思想。如果Singleton只被一个进程调用,它能够很好地工作,但是因为uniqueInstance是类的成员,并不是getInstance()里的局部变量,多个进程同时调用Singleton.getInstance()时,会出现竞争资源问题。考虑下面情况,初始状态uniqueInstance是null;进程P1执行了语句1;此时调度程序允许进程P2执行,进程2进入getInstance(),并能够执行1、2、3,所以创建了一个Singleton的实例;现在进程1重新被调度为执行,P1会从语句2开始执行,这样就又实例化了一个对象,跟我们设计的意图相违背。
要解决这个问题,就要保证getInstance()的任一时刻的单一进程可入。在用Java语言做实现时,只需加入synchronized关键字,就可以保证对同一个Singleton对象的互斥访问,如下图所示。在其他语言做实现时,只需要加入保证多个进程对getInstance()互斥访问的语句即可。
<!--[if gte vml 1]><v:shape id="_x0000_i1026" type="#_x0000_t75"
style='width:415.5pt;height:135.75pt'>
<v:imagedata src="file:///C:/DOCUME~1/TIANHL~1/LOCALS~1/Temp/msohtml1/01/clip_image003.emz"
o:title=""/>
</v:shape><![endif]--><!--[if !vml]-->
<!--[endif]-->
2.2 Listener/Observer模式
Listener模式的意图(Intent)是“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。”
Listener模式是Client把自己实现的Listener接口通过Subject的addListener() / removeListener()方法注册/注销感兴趣的事件,当所注册的事件发生时,相应的通知机制会通过notify()来调用之前所注册的Listener中的方法——这里是handleEvent(),注意这个方法是由Listener所实现的。这个模式被广泛应用于各种异步事件处理机制中,如果你认为有些没有采用,那极有可能只是它没有显式的提出是这个模式而已。注册事件的时机有可能是隐式的,可能在创建实例的时候,也可能在编译阶段就已经注册了。而Listener的形式也可能是Observer,Subscriber,callback,所以这个模式也就有了Observer,Subscriber模式的名字,等。
<!--[if gte vml 1]><v:shape id="_x0000_i1027" type="#_x0000_t75"
style='width:419.25pt;height:127.5pt'>
<v:imagedata src="file:///C:/DOCUME~1/TIANHL~1/LOCALS~1/Temp/msohtml1/01/clip_image005.emz"
o:title=""/>
</v:shape><![endif]--><!--[if !vml]-->
<!--[endif]-->
Listener是由异步事件通知系统之外的程序来实现的,这一般是应用程序,从runtime来看,有一个Client的进程。要实现异步通知Client为感兴趣的事件,一般异步事件通知系统会有一个Service进程,负责事件的分发和处理,事件处理过程是通过系统内维护的Listeners列表,找到应用程序实现的Listener接口,然后调用Listener的相应方法实现。可能你已经注意到我所说的重点了——Listener中的方法虽然实现在系统之外,但是它们却运行在系统Service进程的进程上下文中,如下图所示。
<!--[if gte vml 1]><v:shape id="_x0000_i1028"
type="#_x0000_t75" style='width:285pt;height:336pt' o:ole="">
<v:imagedata src="file:///C:/DOCUME~1/TIANHL~1/LOCALS~1/Temp/msohtml1/01/clip_image007.emz"
o:title=""/>
</v:shape><![endif]--><!--[if !vml]-->
<!--[endif]--><!--[if gte mso 9]><xml>
<o:OLEObject Type="Embed" ProgID="Visio.Drawing.6" ShapeID="_x0000_i1028"
DrawAspect="Content" ObjectID="_1192980988">
</o:OLEObject>
</xml><![endif]-->
Listener接口中的方法是由系统调用运行在系统的进程上下文中的,你即不知道它们什么时候会被调用,也不知道它们会被谁(局部性原理,假设与不是你实现的东西都是通过协商一致并明确定义的接口来交互的)调用到,所以在写它的实现时要特别注意:1. 方法中用到Listener实现类的成员或者全局变量时,要注意对它们的临界访问问题;2. 方法中做到尽量快地完成返回,并且注意千万不要再在这些方法内调用可能引起系统内进程被重新调度的语句。
To be continued
三、总结
设计模式是软件设计中不断沉积演化的智慧的结晶,它是不断发展的。掌握现有的设计模式是我们设计出架构优美,结构清晰,表达明确的软件制品,以及保持与主流技术一致发展的前提。不过如果对它们一知半解,而没有全面理解其应用场景和范围以及设计时的限制和注意点,倒是还不如不知道这个概念,在没有设计模式概念之前,已经有实际采用了设计模式的优秀的软件作品。所以要用它学习消化它,就要尽可能全面掌握它,即便不能全面把握,限制和可能的不好的后果是首先要了解的。
参考资料
<!--[if !supportLists]-->1. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley / 机械工业,1995/2002.3<!--[endif]-->
<!--[if !supportLists]-->2. Raphael Malveau, Thomas J. Mowbray, Ph.D. Software Architect Bootcamp, Second Edition. Prentice Hall PTR, <chsdate year="2003" month="10" day="10" islunardate="False" isrocdate="False" w:st="on">2003-10-10</chsdate><!--[endif]-->
<!--[if !supportLists]-->3. Michael L. Scott著/裘宗燕译. Programming Language Pragmatics. Elsevier/电子工业出版社, 2005.3<!--[endif]-->
关于作者
田海立,系统分析师。主要兴趣方向:嵌入式软件架构,Java/Eclipse,Linux技术。您可以通过 haili.tian@gmail.com 或 tianhaili@nju.org.cn 与他联系,到 http://blog.csdn.net/thl789/ or http://spaces.msn.com/members/thl789/ 看他的文章。
相关推荐
**设计模式**(Design Patterns)是软件工程中的一个重要概念,它是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。本章节将从多个角度对设计模式进行深入探讨。 #### 二、设计模式的基本定义 ...
"Laracasts - design-patterns-in-php.torrent"则可能是一个BT种子文件,用于通过BitTorrent协议下载整个课程的大型数据包,这通常包括所有视频讲座和其他相关文件。 在课程"设计模式在PHP中"中,你可能会学到以下...
《大话设计模式》C++实现-design-patterns-cpp
《Kotlin设计模式实战解析》 在编程领域,设计模式是一种通用、可重用的...开源项目"Design-Patterns-In-Kotlin"则是一个很好的学习资源,它提供了各种设计模式在Kotlin中的具体实现,有助于开发者深入学习和实践。
本书《Design Patterns for Embedded Systems in C》作为嵌入式软件工程工具箱,作者Bruce Powell Douglass博士基于丰富的嵌入式软件工程经验,详细介绍了在嵌入式系统编程中使用C语言时可以运用的设计模式。...
Go Design Patterns for Real-World Projects 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Go Design Patterns for Real-World Projects 英文azw3 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
The topic of Design Patterns sounds dry, academically constipated and, in all honesty, done to death in almost every programming language imaginable—including programming languages such as JavaScript...
Go Design Patterns will provide readers with a reference point to software design patterns and CSP concurrency design patterns to help them build applications in a more idiomatic, robust, and ...
在编程领域,设计模式是一种被广泛接受的解决常见问题的最佳实践。它们是经过时间验证的...在"go-design-patterns-master"这个项目中,你将找到每个模式的具体实现示例,这对于学习和理解Go语言的设计模式非常有帮助。
https://github.com/kamranahmedse/design-patterns-for-humans 中文翻译,实例修改位JAVA代码
Data Structures and Algorithms with Object-Oriented Design Patterns in CSharp - Bruno R. Preiss
设计模式是软件工程领域中的重要概念,源自于1994年由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位杰出的软件工程师合著的经典书籍《设计模式:可复用面向对象软件的基础》(Design Patterns: ...
Reusable Approaches for Object-Oriented Software Design What You Will Learn Apply design patterns to modern C++ programming Use creational patterns of builder, factories, prototype and singleton ...
设计模式 中文版 Design Patterns 可复用面向对象软件基础 经典之作 内含23个设计模式