博客归档

Akin’s Laws of Spacecraft Design

Nice engineering tips.

译文:航天飞机设计定律


Akin’s Laws of Spacecraft Design

Date here Author here

1. Engineering is done with numbers. Analysis without numbers is only an opinion.

2. To design a spacecraft right takes an infinite amount of effort. This is why it’s a good idea to design them to operate when some things are wrong .

3. Design is an iterative process. The necessary number of iterations is one more than the number you have currently done. This is true at any point in time.

4. Your best design efforts will inevitably wind up being useless in the final design. Learn to live with the disappointment.

5. (Miller’s Law) Three points determine a curve.

6. (Mar’s Law) Everything is linear if plotted log-log with a fat magic marker.

7. At the start of any design effort, the person who most wants to be team leader is least likely to be capable of it.

8. In nature, the optimum is almost always in the middle somewhere. Distrust assertions that the optimum is at an extreme point.

9. Not having all the information you need is never a satisfactory excuse for not starting the analysis.

10. When in doubt, estimate. In an emergency, guess. But be sure to go back and clean up the mess when the real numbers come along.

11. Sometimes, the fastest way to get to the end is to throw everything out and start over.

12. There is never a single right solution. There are always multiple wrong ones, though.

13. Design is based on requirements. There’s no justification for designing something one bit “better” than the requirements dictate.

14. (Edison’s Law) “Better” is the enemy of “good”.

15. (Shea’s Law) The ability to improve a design occurs primarily at the interfaces. This is also the prime location for screwing it up.

16. The previous people who did a similar analysis did not have a direct pipeline to the wisdom of the ages. There is therefore no reason to believe their analysis over yours. There is especially no reason to present their analysis as yours.

17. The fact that an analysis appears in print has no relationship to the likelihood of its being correct.

18. Past experience is excellent for providing a reality check. Too much reality can doom an otherwise worthwhile design, though.

19. The odds are greatly against you being immensely smarter than everyone else in the field. If your analysis says your terminal velocity is twice the speed of light, you may have invented warp drive, but the chances are a lot better that you’ve screwed up.

20. A bad design with a good presentation is doomed eventually. A good design with a bad presentation is doomed immediately.

21. (Larrabee’s Law) Half of everything you hear in a classroom is crap. Education is figuring out which half is which.

22. When in doubt, document. (Documentation requirements will reach a maximum shortly after the termination of a program.)

23. The schedule you develop will seem like a complete work of fiction up until the time your customer fires you for not meeting it.

24. It’s called a “Work Breakdown Structure” because the Work remaining will grow until you have a Breakdown, unless you enforce some Structure on it.

25. (Bowden’s Law) Following a testing failure, it’s always possible to refine the analysis to show that you really had negative margins all along.

26. (Montemerlo’s Law) Don’t do nuthin’ dumb.

27. (Varsi’s Law) Schedules only move in one direction.

28. (Ranger’s Law) There ain’t no such thing as a free launch.

29. (von Tiesenhausen’s Law of Program Management) To get an accurate estimate of final program requirements, multiply the initial time estimates by pi, and slide the decimal point on the cost estimates one place to the right.

30. (von Tiesenhausen’s Law of Engineering Design) If you want to have a maximum effect on the design of a new engineering system, learn to draw. Engineers always wind up designing the vehicle to look like the initial artist’s concept.

31. (Mo’s Law of Evolutionary Development) You can’t get to the moon by climbing successively taller trees.

32. (Atkin’s Law of Demonstrations) When the hardware is working perfectly, the really important visitors don’t show up.

33. (Patton’s Law of Program Planning) A good plan violently executed now is better than a perfect plan next week.

34. (Roosevelt’s Law of Task Planning) Do what you can, where you are, with what you have.

35. (de Saint-Exupery’s Law of Design) A designer knows that he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.

36. Any run-of-the-mill engineer can design something which is elegant. A good engineer designs systems to be efficient. A great engineer designs them to be effective.

37. (Henshaw’s Law) One key to success in a mission is establishing clear lines of blame.

38. Capabilities drive requirements, regardless of what the systems engineering textbooks say.

39. The three keys to keeping a new manned space program affordable and on schedule:
       1)  No new launch vehicles.
       2)  No new launch vehicles.
       3)  Whatever you do, don’t decide to develop any new launch vehicles.

40. Space is a completely unforgiving environment. If you screw up the engineering, somebody dies (and there’s no partial credit because most of the analysis was right…)


*I’ve been involved in spacecraft and space systems design and development for my entire career, including teaching the senior-level capstone spacecraft design course, for ten years at MIT and now at the University of Maryland for more than a decade. These are some bits of wisdom that I have gleaned during that time, some by picking up on the experience of others, but mostly by screwing up myself. I originally wrote these up and handed them out to my senior design class, as a strong hint on how best to survive my design experience. Months later, I get a phone call from a friend in California complimenting me on the Laws, which he saw on a “joke-of-the-day” listserve. Since then, I’m aware of half a dozen sites around the world that present various editions of the Laws, and even one site which has converted them to the Laws of Certified Public Accounting. (Don’t ask…) Anyone is welcome to link to these, use them, post them, send me suggestions of additional laws, but I do maintain that this is the canonical set of Akin’s Laws…

The minimum of a team

Comment here,


The minimum of a team

Date N/A Gediminas Bukauskas

@Jason Programming Follows industry evolution: first cars and airplanes were constructed by 1-2 persons. Do you think that Boeing 737 could be built by one very good master? I agree with Hal Levy: it is impossible to find a person who knows every aspect of .NET – object is too wide.

I wrote – times of standalone programming genius are over, you need team for building enterprise applications. OK, I shall repeat here, you will need:

1. Professional designer that knows GUI building principals, knows and loves working with graphical editors,

1. Front-end programmer for moving picture to HTML, XAML; he must know CSS3, HTML5, XAML, one of JavaScript environments; there are many different JavaScript libraries and nobody knows all of them,

1. Back-end programmer like me; this person will be responsible for mapping your business ideas to database tables, creating business rules, transmitting data from client side to database and back.

1. Tests designer – this person must think day and night about making the system full, write scripts for doing that and launch the scripts on every new release of the application.

1. Project manager – person who knows object of automation, contacts with customer and maps customer’s dream into collection of diagrams (UML).

Don’t start programming at all once you could not collect this absolutely minimal set of employees – your project will fail.

大师的结晶:宫本茂游戏设计的“三原则”

简单接触,些许变化,再次调整,最终形态。

—————————————————————————————————

大师的结晶:宫本茂游戏设计的“三原则”

Date: N/A  Source: N/A

文章主要回顾过去几十年来的游戏设计杰作,从中抽取可供大家进行借鉴的有趣技巧。本文将尽量列举具体范例。第一个是来自宫本茂的设计概念,我将其称作“三原则”。这是个实际的关卡设计技巧,将玩家逐步引入新挑战中。以下是它的运作模式:

在你向玩家发布新功能挑战前,你首先以3个简单的不同情景显示内容。

这一技巧倍受宫本茂青睐,令他的作品在80年代的众多复杂NES游戏中脱颖而出。但这一策略无法令你的游戏变得“更简单”。相反,它会促使游戏变得具有“习得性”(游戏邦注:让玩家在迎接真正挑战前做好准备)。它的最大优点是,你无法通过乏味的指南做到这点。你必须通过玩法。正如Raph Koster所述,玩家通过玩乐进行学习。

这属于实际游戏设计,因此我将通过实例进行阐述。下面就来看看原生《超级马里奥兄弟》,看看游戏如何引出Goomba。

步骤1 – 简单接触

1519442309-1

初次看到Goomba时,它径直向我们走来。没什么花招,没什么特别之处:它只是缓慢向我们走来。

注意这是基于Goomba挑战玩家的最简单方式。

在我们多数人看来,这没有太大问题。将其踩扁,或直接跳过,你都会完好无事。但回到1986年,这是很多人都玩过的首款电子游戏,很多玩家可能会被第一个出现的Goomba消灭。但这没什么关系——丧失生命,从头开始,不会丧失任何进展。只需再次进行尝试。

此外,若没有掌握游戏基本技能——跳跃,我们完全无法避开游戏的首个Goomba。这意味游戏设计师可以做出此假设:任何通过这一初始点的玩家都知道如何进行跳跃。

通过这一挑战,设计师告诉玩家:“游戏存在Goomba这类元素”。

首个Goomba被玩家顺利跳过。向右移动一小段距离后,我们遇到第二个Goomba。

步骤2 – 些许变化

151944JS-2

它在两个管道之间来回跳跃,我们处在某个管道上。

这比最简单的Goomba挑战更进一步。但更重要的是,这带来全新Goomba。在玩家需要踩扁Goomba或进行跳跃前,暂时将其置于一旁。现在我们看到不同的情境:当它击中管道时会持续来回跳跃。这一密闭空间改变了挑战的性质。

通过这一挑战,设计师告诉玩家:“Goomba周围的空间可以呈现不同模式。”

但这个挑战也不是很困难,玩家可以很快完成这一关卡。只要玩家通过这一节点,设计师就可以做出此假设,玩家已把握前两次的经验。

接着,我们会看到如下画面:

步骤3 – 再次调整

1519442317-3

基于之前的挑战做出调整,这里是两个更宽阔的管道,同时有两个goomba正在来回跳跃。

这一挑战颇具趣味,因为相比上个挑战,这变得更简单,也更复杂。它变得更简单是因为管道存在更多空间,更复杂是因为goomba的数量翻倍,所以即使你逃过一个,你也依然有被消灭的可能。

逃过这一挑战,设计师告诉玩家:“Goomba并不总是单独出现。”

解决这三个挑战只需10秒钟,但玩家从中充分把握游戏的首个敌人类型。我们学到应对挑战需要的基本技能(游戏邦注:即跳跃),我们快速把握Goomba的各种出现形式。

这也许有些过于简单,但在很多游戏中,玩家并没有在迎接新挑战前“做好充分准备”。相反,玩家在初次遇到新挑战时,就直接被出奇不意地击败。这不仅颇令人沮丧,而且还无法让玩家从中进行学习。三原则是这一问题的最佳解决方案。

所以,回到《超级马里奥兄弟》。现在宫本茂已向我们呈现Goomba元素,接下来会发生什么?

步骤4 – 最终形态

151944DR-4

这里Goomba会从平台上降落,威胁从天而降的玩家。Goomba首次在游戏中变成具有挑战性的威胁元素。想想如果这是你初次体验游戏时遇到的场景会是怎样。当然如今具备多年游戏经验的硬核玩家在此毫无问题,但我可以想象在1989年只有5岁的孩子定会因此而感到非常沮丧。当年,这个简单的10秒玩法让我能够做好充分准备,应对这一情境,这对如今的玩家来说也是如此。

这对关卡晋级来说非常重要。从根本来说,你其实是向玩家提供学习课程。你在升级内容前,先单独呈现挑战,这样玩家就能够首先学习个别技能,而这随后将组合成更复杂的技能。

三原则适用众多范围,包括关卡内和关卡外。《超级马里奥兄弟》的各个游戏空间由3个初级关卡构成,然后是一个富有挑战性的“城堡”关卡。这样三原则就贯穿于整个《超级马里奥兄弟》结构中。

看看你首次遇到Koopa前,游戏第一个城堡的最后一个走廊:

1519441056-5

Koopa准备

游戏并没有让玩家立即应对Koopa,然后迅速遭遇死亡,玩家会受到短暂的火球训练。首先,火球会单独出现在你面前。然后游戏地形会发生改变,火球会从不同高度进行袭击。最后,火球会以更快速度出现。这样在战斗开始前,玩家就做好迎接战斗的“准备”。

显然,这里的数字“三”没有什么奇特之处。这觉得这是个不错的经验法则——只要你在不同情境中向玩家呈现内容三次以上,你就有理由地将内容混合起来。

游戏邦注:原文发布于2010年4月3日,文章叙述以当时为背景。

一些软件设计的原则

From: http://coolshell.cn/articles/4535.html

2011年4月25日 陈皓

以前本站向大家介绍过一些软件开发的原则,比如优质代码的十诫Unix传奇(下篇)中所以说的UNIX的设计原则。相信大家从中能够从中学了解到一些设计原理方面的知识,正如我在《再谈“我是怎么招聘程序”》中所说的,一个好的程序员通常由其操作技能、知识水平,经验层力和能力四个方面组成。在这里想和大家说说设计中的一些原则,我认为这些东西属于长期经验总结出来的知识。这些原则,每一个程序员都应该了解。但是请不要教条主义,在使用的时候还是要多多考虑实际情况。其实,下面这些原则,不单单只是软件开发,可以推广到其它生产活动中,甚至我们的生活中。

Don’t Repeat Yourself (DRY)

DRY 是一个最简单的法则,也是最容易被理解的。但它也可能是最难被应用的(因为要做到这样,我们需要在泛型设计上做相当的努力,这并不是一件容易的事)。它意 味着,当我们在两个或多个地方的时候发现一些相似的代码的时候,我们需要把他们的共性抽象出来形一个唯一的新方法,并且改变现有的地方的代码让他们以一些 合适的参数调用这个新的方法。

参考:http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

Keep It Simple, Stupid (KISS)

KISS原则在设计上可能最被推崇的,在家装设计,界面设计 ,操作设计上,复杂的东西越来越被众人所BS了,而简单的东西越来越被人所认可,比如这些UI的设计和我们中国网页(尤其是新浪的网页) 者是负面的例子。“宜家”(IKEA)简约、效率的家居设计、生产思路;“微软”(Microsoft)“所见即所得”的理念;“谷歌”(Google) 简约、直接的商业风格,无一例外的遵循了“kiss”原则,也正是“kiss”原则,成就了这些看似神奇的商业经典。而苹果公司的iPhone/iPad 将这个原则实践到了极至。

把一个事情搞复杂是一件简单的事,但要把一个复杂的事变简单,这是一件复杂的事。

参考:http://en.wikipedia.org/wiki/KISS_principle

Program to an interface, not an implementation

这是设计模式中最根本的哲学,注重接口,而不是实现,依赖接口,而不是实现。接口是抽象是稳定的,实现则是多种多样的。以后面我们会面向对象的SOLID原则中会提到我们的依赖倒置原则,就是这个原则的的另一种样子。还有一条原则叫 Composition over inheritance(喜欢组合而不是继承),这两条是那23个经典设计模式中的设计原则。

Command-Query Separation (CQS)  – 命令-查询分离原则

  • 查询:当一个方法返回一个值来回应一个问题的时候,它就具有查询的性质;
  • 命令:当一个方法要改变对象的状态的时候,它就具有命令的性质;

通常,一个方法可能是纯的Command模式或者是纯的Query模式,或者是两者的混合体。在设计接口时,如果可能,应该尽量使接口单一化,保证 方法的行为严格的是命令或者是查询,这样查询方法不会改变对象的状态,没有副作用,而会改变对象的状态的方法不可能有返回值。也就是说:如果我们要问一个 问题,那么就不应该影响到它的答案。实际应用,要视具体情况而定,语义的清晰性和使用的简单性之间需要权衡。将Command和Query功能合并入一个 方法,方便了客户的使用,但是,降低了清晰性,而且,可能不便于基于断言的程序设计并且需要一个变量来保存查询结果。

在系统设计中,很多系统也是以这样原则设计的,查询的功能和命令功能的系统分离,这样有则于系统性能,也有利于系统的安全性。

参考:http://en.wikipedia.org/wiki/Command-query_separation

You Ain’t Gonna Need It (YAGNI)

这个原则简而言之为——只考虑和设计必须的功能,避免过度设计。只实现目前需要的功能,在以后您需要更多功能时,可以再进行添加。

  • 如无必要,勿增复杂性。
  • 软件开发先是一场沟通博弈。

以前本站有一篇关于过度重构的文章,这个示例就是这个原则的反例。而,WebSphere的设计者就表示过他过度设计了这个产品。我们的程序员或是架构师在设计系统的时候,会考虑很多扩展性的东西,导致在架构与设计方面使用了大量折衷,最后导致项目失败。这是个令人感到讽刺的教训,因为本来希望尽可能延长项目的生命周期,结果反而缩短了生命周期。

参考:http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It

Law of Demeter – 迪米特法则

迪米特法则(Law of Demeter),又称“最少知识原则”(Principle of Least Knowledge),其来源于1987年荷兰大学的一个叫做Demeter的项目。Craig Larman把Law of Demeter又称作“不要和陌生人说话”。在《程序员修炼之道》中讲LoD的那一章叫作“解耦合与迪米特法则”。关于迪米特法则有一些很形象的比喻:

  • 如果你想让你的狗跑的话,你会对狗狗说还是对四条狗腿说?
  • 如果你去店里买东西,你会把钱交给店员,还是会把钱包交给店员让他自己拿?

和狗的四肢说话?让店员自己从钱包里拿钱?这听起来有点荒唐,不过在我们的代码里这几乎是见怪不怪的事情了。

对于LoD,正式的表述如下:

对于对象 ‘O’ 中一个方法’M’,M应该只能够访问以下对象中的方法:

  1. 对象O;
  1. 与O直接相关的Component Object;
  1. 由方法M创建或者实例化的对象;
  1. 作为方法M的参数的对象。

在《Clean Code》一书中,有一段Apache framework中的一段违反了LoD的代码:

final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();

这么长的一串对其它对象的细节,以及细节的细节,细节的细节的细节……的调用,增加了耦合,使得代码结构复杂、僵化,难以扩展和维护。

在《重构》一书中的代码的环味道中有一种叫做“Feature Envy”(依恋情结),形象的描述了一种违反了LoC的情况。Feature Envy就是说一个对象对其它对象的内容更有兴趣,也就是说老是羡慕别的对象的成员、结构或者功能,大老远的调用人家的东西。这样的结构显然是不合理的。 我们的程序应该写得比较“害羞”。不能像前面例子中的那个不把自己当外人的店员一样,拿过客人的钱包自己把钱拿出来。“害羞”的程序只和自己最近的朋友交 谈。这种情况下应该调整程序的结构,让那个对象自己拥有它羡慕的feature,或者使用合理的设计模式(例如Facade和Mediator)。

参考:http://en.wikipedia.org/wiki/Principle_of_Least_Knowledge

面向对象的S.O.L.I.D 原则

一般来说这是面向对象的五大设计原则,但是,我觉得这些原则可适用于所有的软件开发。

Single Responsibility Principle (SRP) – 职责单一原则

关于单一职责原则,其核心的思想是:一个类,只做一件事,并把这件事做好,其只有一个引起它变化的原因。单一职 责原则可以看作是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。职责过多,可能引起它变化的原 因就越多,这将导致职责依赖,相互之间就产生影响,从而极大的损伤其内聚性和耦合度。单一职责,通常意味着单一的功能,因此不要为一个模块实现过多的功能 点,以保证实体只有一个引起它变化的原因。

  • Unix/Linux是这一原则的完美体现者。各个程序都独立负责一个单一的事。
  • Windows是这一原则的反面示例。几乎所有的程序都交织耦合在一起。

Open/Closed Principle (OCP) – 开闭原则

关于开发封闭原则,其核心的思想是:模块是可扩展的,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

  • 对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
  • 对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

对于面向对象来说,需要你依赖抽象,而不是实现,23个经典设计模式中的“策略模式”就是这个实现。对于非面向对象编程,一些API需要你传入一个 你可以扩展的函数,比如我们的C 语言的qsort()允许你提供一个“比较器”,STL中的容器类的内存分配,ACE中的多线程的各种锁。对于软件方面,浏览器的各种插件属于这个原则的 实践。

Liskov substitution principle (LSP) – 里氏代换原则

软件工程大师Robert C. Martin把里氏代换原则最终简化为一句话:“Subtypes must be substitutable for their base types”。也就是,子类必须能够替换成它们的基类。即:子类应该可以替换任何基类能够出现的地方,并且经过替换以后,代码还能正常工作。另外,不应该 在代码中出现if/else之类对子类类型进行判断的条件。里氏替换原则LSP是使代码符合开闭原则的一个重要保证。正是由于子类型的可替换性才使得父类 型的模块在无需修改的情况下就可以扩展。

这么说来,似乎有点教条化,我非常建议大家看看这个原则个两个最经典的案例——“正方形不是长方形”和“鸵鸟不是鸟”。通过这两个案例,你会明白 《墨子 小取》中说的 ——“娣,美人也,爱娣,非爱美人也….盗,人也;恶盗,非恶人也。”——妹妹虽然是美人,但喜欢妹妹并不代表喜欢美人。盗贼是人,但讨厌盗贼也并不代表 就讨厌人类。这个原则让你考虑的不是语义上对象的间的关系,而是实际需求的环境。

在很多情况下,在设计初期我们类之间的关系不是很明确,LSP则给了我们一个判断和设计类之间关系的基准:需不需要继承,以及怎样设计继承关系。

Interface Segregation Principle (ISP) – 接口隔离原则

接口隔离原则意思是把功能实现在接口中,而不是类中,使用多个专门的接口比使用单一的总接口要好。

举个例子,我们对电脑有不同的使用方式,比如:写作,通讯,看电影,打游戏,上网,编程,计算,数据等,如果我们把这些功能都声明在电脑的抽类里 面,那么,我们的上网本,PC机,服务器,笔记本的实现类都要实现所有的这些接口,这就显得太复杂了。所以,我们可以把其这些功能接口隔离开来,比如:工 作学习接口,编程开发接口,上网娱乐接口,计算和数据服务接口,这样,我们的不同功能的电脑就可以有所选择地继承这些接口。

这个原则可以提升我们“搭积木式”的软件开发。对于设计来说,Java中的各种Event Listener和Adapter,对于软件开发来说,不同的用户权限有不同的功能,不同的版本有不同的功能,都是这个原则的应用。

Dependency Inversion Principle (DIP) – 依赖倒置原则

高层模块不应该依赖于低层模块的实现,而是依赖于高层抽象。

举个例子,墙面的开关不应该依赖于电灯的开关实现,而是应该依赖于一个抽象的开关的标准接口,这样,当我们扩展程序的时候,我们的开关同样可以控制 其它不同的灯,甚至不同的电器。也就是说,电灯和其它电器继承并实现我们的标准开关接口,而我们的开关产商就可不需要关于其要控制什么样的设备,只需要关 心那个标准的开关标准。这就是依赖倒置原则。

这就好像浏览器并不依赖于后面的web服务器,其只依赖于HTTP协议。这个原则实在是太重要了,社会的分工化,标准化都是这个设计原则的体现。

参考:http://en.wikipedia.org/wiki/Solid_(object-oriented_design)

Common Closure Principle(CCP)– 共同封闭原则

一个包中所有的类应该对同一种类型的变化关闭。一个变化影响一个包,便影响了包中所有的类。一个更简短的说法是:一起修改的类,应该组合在一起(同 一个包里)。如果必须修改应用程序里的代码,我们希望所有的修改都发生在一个包里(修改关闭),而不是遍布在很多包里。CCP原则就是把因为某个同样的原 因而需要修改的所有类组合进一个包里。如果2个类从物理上或者从概念上联系得非常紧密,它们通常一起发生改变,那么它们应该属于同一个包。

CCP延伸了开闭原则(OCP)的“关闭”概念,当因为某个原因需要修改时,把需要修改的范围限制在一个最小范围内的包里。

参考:http://c2.com/cgi/wiki?CommonClosurePrinciple

Common Reuse Principle (CRP) – 共同重用原则

包的所有类被一起重用。如果你重用了其中的一个类,就重用全部。换个说法是,没有被一起重用的类不应该被组合在一起。CRP原则帮助我们决定哪些类 应该被放到同一个包里。依赖一个包就是依赖这个包所包含的一切。当一个包发生了改变,并发布新的版本,使用这个包的所有用户都必须在新的包环境下验证他们 的工作,即使被他们使用的部分没有发生任何改变。因为如果包中包含有未被使用的类,即使用户不关心该类是否改变,但用户还是不得不升级该包并对原来的功能 加以重新测试。

CCP则让系统的维护者受益。CCP让包尽可能大(CCP原则加入功能相关的类),CRP则让包尽可能小(CRP原则剔除不使用的类)。它们的出发点不一样,但不相互冲突。

参考:http://c2.com/cgi/wiki?CommonReusePrinciple

Hollywood Principle – 好莱坞原则

好莱坞原则就是一句话——“don’t call us, we’ll call you.”。意思是,好莱坞的经纪人们不希望你去联系他们,而是他们会在需要的时候来联系你。也就是说,所有的组件都是被动的,所有的组件初始化和调用都 由容器负责。组件处在一个容器当中,由容器负责管理。

简单的来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:

  1. 不创建对象,而是描述创建对象的方式。
  1. 在代码中,对象与服务没有直接联系,而是容器负责将这些联系在一起。

控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。

好莱坞原则就是IoC(Inversion of Control)或DI(Dependency Injection )的基础原则。这个原则很像依赖倒置原则,依赖接口,而不是实例,但是这个原则要解决的是怎么把这个实例传入调用类中?你可能把其声明成成员,你可以通过 构造函数,你可以通过函数参数。但是 IoC可以让你通过配置文件,一个由Service Container 读取的配置文件来产生实际配置的类。但是程序也有可能变得不易读了,程序的性能也有可能还会下降。

参考:

High Cohesion & Low/Loose coupling & – 高内聚, 低耦合

这个原则是UNIX操作系统设计的经典原则,把模块间的耦合降到最低,而努力让一个模块做到精益求精。

  • 内聚:一个模块内各个元素彼此结合的紧密程度
  • 耦合:一个软件结构内不同模块之间互连程度的度量

内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。

参考:

Convention over Configuration(CoC)– 惯例优于配置原则

简单点说,就是将一些公认的配置方式和信息作为内部缺省的规则来使用。例如,Hibernate的映射文件,如果约定字段名和类属性一致的话,基本 上就可以不要这个配置文件了。你的应用只需要指定不convention的信息即可,从而减少了大量convention而又不得不花时间和精力啰里啰嗦 的东东。配置文件很多时候相当的影响开发效率。

Rails 中很少有配置文件(但不是没有,数据库连接就是一个配置文件),Rails 的fans号称期开发效率是 java 开发的 10 倍,估计就是这个原因。Maven也使用了CoC原则,当你执行mvn -compile命令的时候,不需要指源文件放在什么地方,而编译以后的class文件放置在什么地方也没有指定,这就是CoC原则。

参考:http://en.wikipedia.org/wiki/Convention_over_Configuration

Separation of Concerns (SoC) – 关注点分离

SoC 是计算机科学中最重要的努力目标之一。这个原则,就是在软件开发中,通过各种手段,将问题的各个关注点分开。如果一个问题能分解为独立且较小的问题,就是 相对较易解决的。问题太过于复杂,要解决问题需要关注的点太多,而程序员的能力是有限的,不能同时关注于问题的各个方面。正如程序员的记忆力相对于计算机 知识来说那么有限一样,程序员解决问题的能力相对于要解决的问题的复杂性也是一样的非常有限。在我们分析问题的时候,如果我们把所有的东西混在一起讨论, 那么就只会有一个结果——乱。

我记得在上一家公司有一个项目,讨论就讨论了1年多,项目本来不复杂,但是没有使用SoC,全部的东西混为一谈,再加上一堆程序员注入了各种不同的观点和想法,整个项目一下子就失控了。最后,本来一个1年的项目做了3年。

实现关注点分离的方法主要有两种,一种是标准化,另一种是抽象与包装。标准化就是制定一套标准,让使用者都遵守它,将人们的行为统一起来,这样使用 标准的人就不用担心别人会有很多种不同的实现,使自己的程序不能和别人的配合。Java EE就是一个标准的大集合。每个开发者只需要关注于标准本身和他所在做的事情就行了。就像是开发镙丝钉的人只专注于开发镙丝钉就行了,而不用关注镙帽是怎 么生产的,反正镙帽和镙丝钉按标来就一定能合得上。不断地把程序的某些部分抽像差包装起来,也是实现关注点分离的好方法。一旦一个函数被抽像出来并实现 了,那么使用函数的人就不用关心这个函数是如何实现的,同样的,一旦一个类被抽像并实现了,类的使用者也不用再关注于这个类的内部是如何实现的。诸如组 件,分层,面向服务,等等这些概念都是在不同的层次上做抽像和包装,以使得使用者不用关心它的内部实现细节。

说白了还是“高内聚,低耦合”。

参考:http://sulong.me/archives/99

Design by Contract (DbC) – 契约式设计

DbC的核心思想是对软件系统中的元素之间相互合作以及“责任”与“义务”的比喻。这种比喻从商业活动中“客户”与“供应商”达成“契约”而得来。例如:

  • 供应商必须提供某种产品(责任),并且他有权期望客户已经付款(权利)。
  • 客户必须付款(责任),并且有权得到产品(权利)。
  • 契约双方必须履行那些对所有契约都有效的责任,如法律和规定等。

同样的,如果在程序设计中一个模块提供了某种功能,那么它要:

  • 期望所有调用它的客户模块都保证一定的进入条件:这就是模块的先验条件(客户的义务和供应商的权利,这样它就不用去处理不满足先验条件的情况)。
  • 保证退出时给出特定的属性:这就是模块的后验条件——(供应商的义务,显然也是客户的权利)。
  • 在进入时假定,并在退出时保持一些特定的属性:不变式。

契约就是这些权利和义务的正式形式。我们可以用“三个问题”来总结DbC,并且作为设计者要经常问:

  • 它期望的是什么?
  • 它要保证的是什么?
  • 它要保持的是什么?

根据Bertrand Meyer氏提出的DBC概念的描述,对于类的一个方法,都有一个前提条件以及一个后续条件,前提条件说明方法接受什么样的参数数据等,只有前提条件得到 满足时,这个方法才能被调用;同时后续条件用来说明这个方法完成时的状态,如果一个方法的执行会导致这个方法的后续条件不成立,那么这个方法也不应该正常 返回。

现在把前提条件以及后续条件应用到继承子类中,子类方法应该满足:

  1. 前提条件不强于基类.
  1. 后续条件不弱于基类.

换句话说,通过基类的接口调用一个对象时,用户只知道基类前提条件以及后续条件。因此继承类不得要求用户提供比基类方法要求的更强的前提条件,亦 即,继承类方法必须接受任何基类方法能接受的任何条件(参数)。同样,继承类必须顺从基类的所有后续条件,亦即,继承类方法的行为和输出不得违反由基类建 立起来的任何约束,不能让用户对继承类方法的输出感到困惑。

这样,我们就有了基于契约的LSP,基于契约的LSP是LSP的一种强化。

参考:http://en.wikipedia.org/wiki/Design_by_contract

Acyclic Dependencies Principle (ADP) – 无环依赖原则

包之间的依赖结构必须是一个直接的无环图形,也就是说,在依赖结构中不允许出现环(循环依赖)。如果包的依赖形成了环状结构,怎么样打破这种循环依 赖呢?有2种方法可以打破这种循环依赖关系:第一种方法是创建新的包,如果A、B、C形成环路依赖,那么把这些共同类抽出来放在一个新的包D里。这样就把 C依赖A变成了C依赖D以及A依赖D,从而打破了循环依赖关系。第二种方法是使用DIP(依赖倒置原则)和ISP(接口分隔原则)设计原则。

无环依赖原则(ADP)为我们解决包之间的关系耦合问题。在设计模块时,不能有循环依赖。

参考:http://c2.com/cgi/wiki?AcyclicDependenciesPrinciple

————————————————————————————

上面这些原则可能有些学院派,也可能太为理论,我在这里说的也比较模糊和简单,这里只是给大家一个概貌,如果想要了解更多的东西,大家可以多google一下。

不过这些原则看上去都不难,但是要用好却并不那么容易。要能把这些原则用得好用得精,而不教条,我的经验如下:(我以为这是一个理论到应用的过程)

  1. 你可以先粗浅或是表面地知道这些原则。
  1. 但不要急着马上就使用。
  1. 在工作学习中观察和总结别人或自己的设计。
  2. 再回过头来了回顾一下这些原则,相信你会有一些自己的心得。
  3. 有适度地去实践一下。
  4. Goto第 3步。

我相信可能还会有其实一些原则,欢迎大家提供。

(全文完)

Interactive Application Architecture Patterns

 

——————————————————————————————————————————

Clipped on 29-December-2011, 2:33 PM from Interactive Application Architecture Patterns

——————————————————————————————————————————

On August 25, 2007, in Uncategorized, by derekgreer

Introduction

The MVC, MVP, and PAC patterns are each intended to address the needs of interactive applications by separating the concerns assigned to different components within their respective architectures. While similar, each of these patterns differs slightly in their motivations and applicability to various design goals. This article discusses each pattern along with its history and design motivations to encourage the correct understanding and application of these patterns.

In discussing architecture patterns in general, it is helpful to understand that patterns in this class are often motivated by design considerations which were formed within the context of specific development environments. As such, platform specific motivations and the pattern’s implementation details are often incorporated into the formal description of the pattern.For instance, the Model-View-Controller pattern had the primary design motivation of separating presentation from domain concerns. The division between the input and output of the application (which resulted in the concept of the Controller component), was really a byproduct of addressing complexities inherent to the host platform.

Today’s development environments have come a long way in shielding developers from such complexities making divisions between device input and output at the application level unnecessary. In such environments, an application of the Model-View-Controller pattern may result in an approach which adheres to the intent of the pattern while not following its original form, or adheres to its original form without following its original intent.

Within many development environments, the original goals of the Model-View-Controller pattern can be accomplished today by merely separating an application’s Forms and associated Controls from its domain model. The formalizing of a Controller for intercepting user input is unnecessary in platforms which natively provide this functionality. When attempting to follow the original form of the Model-View-Controller pattern within such development environments, the resulting architecture may fall somewhere between a strict implementation of MVC which goes against the grain of the hosting environment and an implementation which assigns different responsibilities to the original components. From this observation it can be deduced that the Model-View-Controller pattern isn’t adequately distilled into pattern language. That is to say, the components prescribed by the MVC pattern are not agnostic of the assumed development environment, and most descriptions do not make this explicit. This often results in a misappropriation of the pattern.

Another suggestion when studying and considering the use of interactive design patterns is to take the whole subject with a grain of salt. Many base patterns, such as those presented in the seminal work Design Patterns – Elements of Reusable Object-Oriented Software by Gamma, etc. al. are well distilled patterns which describe solutions to common problems in a implementation-agnostic way. Because of the nature of these patterns, scores of competing constructs aren’t generally found purporting to address the same concern. However, when entering the realm of compound patterns such as interactive application patterns, models, styles, etc., the study of such constructs can feel a bit like watching a documentary of the history of airplanes.

1

It’s best to think of architecture patterns as being as much in the realm of art as science. Interactive architecture patterns aren’t the computer science equivalent of Newton’s Law of Gravity. They merely represent our ever evolving attempt to apply the best approach for application development. Finally, when considering use of these patterns remember that their application should be considered for their applicability to the problem, not so one can proudly proclaim: “I use the such-and-such pattern”. Use of design patterns should be the result of having started with a problem for which an existing pattern was known or found to be applicable, not the result of starting with a pattern for which a problem was sought out or invented in order to use the pattern.

The Model–View-Controller Pattern

Overview

The Model-View-Controller pattern is a methodology for separating the concerns of an application’s domain, presentation, and user input into specialized components.

Origins and Motivation

The MVC pattern was originally conceived in 1978-79 by Trygve Reenskaug and had the primary goal of providing an interface for users to manipulate multiple views of data as if working with real world entities. The pattern was first referred to as the Thing-Model-View-Editor before Reenskaug and his colleges settled on the name Model-View-Controller (1). A modified version of Dr. Reenskaug’s design was later implemented as part of the Xerox PARC Smalltalk-80 class library. A description of this implementation can be found in the work: Applications Programming in Smalltalk-80(TM): How to use Model-View-Controller (MVC).

Structure

The following diagram depicts the structure of the Model-View-Controller pattern:

2

Note: While some descriptions of the MVC pattern show an indirect association from the View to the Controller, the original implementation of MVC in Smalltalk-80 coupled View to Controller, and vice-versa (2).

Components

The Model refers to the data and business functionality of the application. This is often represented by a Domain Model where objects are used to model real world entities and processes by representing their properties and behavior. The View is the visual representation of the Model and is comprised of the screens and widgets used within an application. The Controller is a component which responds to user input such as data entry and commands issued from a keyboard or mouse. Its responsibility is to act as a bridge between the human and the application, allowing the user to interact with the screen and data.

Collaborations

Within the MVC pattern, a Model-View-Controller triad exists for each object intended to be manipulated by a user. The Model represents the state, structure, and behavior of the data being viewed and manipulated by the user. The Model contains no direct link to the View or Controller, and may be modified by the View, Controller, or other objects with the system. When notification to the View and Controller are necessary, the Model uses the Observer Pattern to send a message notifying observing objects that its data has changed. The View and Controller components work together to allow the user to view and interact with the Model. Each View is associated with a single Controller, and each Controller is associated with a single View. Both the View and Controller components maintain a direct link to the Model.

Note: Within the Smalltalk-80 implementation, both the View and Controller maintained a direct link to one another, though the link from the View to the Controller was largely a byproduct of its implementation rather than an inherent part of the MVC pattern. The link was not maintained to delegate user input intercepted by the View to the Controller as is the case with the Dolphin Smalltalk Model-View-Presenter pattern to be discussed later, but was rather used by the View to initialize the controller with an instance of itself, and by a top level Controller to locate the active Controller within a View hierarchy.

The View’s responsibility can be seen as primarily dealing with output while the Controller’s responsibility can be seen as primarily dealing with input. It is the shared responsibility of both the View and the Controller to interact with the Model. The Controller interacts with the Model as the result of responding to user input, while the View interacts with the Model as the result of updates to itself. Both may access and modify data within the Model as needed. As data is entered by the user, the Controller intercepts the user’s input and responds appropriately. Some user actions will result in interaction with the Model, such as changing data or invoking methods, while other user actions may result in visual changes to the View, such as the collapsing of menus, the highlighting of scrollbars, etc.

MVC Misconceptions

One common misconception about the relationship between the MVC components is that the purpose of the Controller is to separate the View from the Model. While the MVC pattern does decouple the application’s domain layer from presentation concerns, this is achieved through the Observer Pattern, not through the Controller. The Controller was conceived as a mediator between the end user and the application, not between the View and the Model.

Pattern Variations and Derivatives

The classic Model-View-Controller pattern is largely no longer used today in its original form, though it has given rise to a number of variations adapted to newer development platforms. The next section will discuss a derivative of the pattern adapted for use with Web development.

The Model-View-Controller Pattern for Web Applications

Overview

Since the advent of the Web, an analog to the original Model-View-Controller pattern has emerged for use with Web applications. Similar to the original pattern, the Web-based MVC pattern aids in separating the concerns of an application’s domain, client-side presentation, and server side input processing into specialized components.

Origins

The Web-based MVC pattern emerged somewhat naturally as object-oriented design was applied to the stateless nature of the HTTP protocol and HTML presentation. Web applications provide the ability to serve up dynamic content to Web clients by processing inbound HTTP requests through server-side components.

As various approaches to Web development emerged, the need for processing and routing inbound requests generally led to to the creation of infrastructure code which served the same logical purpose as the original Smalltalk-80 controllers … directing the application in response to signals from an end-user.

The text-based nature of HTML also led to template-based approaches to separating content from application logic, especially for localized applications. As these techniques were applied in the context of object-oriented applications, a pattern emerged similar to that of the original MVC pattern. The pattern eventually became associated with Java’s “Model 2″ architecture.

From the mid to late 1990′s, Web applications were predominately developed using the Common Gateway Interface (CGI) standard. CGI applications can take the form of compiled or interpreted code and are spawned as separate processes by a Web server to process inbound HTTP requests. In 1997, Sun Microsystems published the Java Servlet 1.0 specification to improve upon CGI-based applications by processing HTTP requests as separate threads within a hosted Java Virtual Machine (JVM). In 1999, Sun further built upon their framework by introducing the Java Server Pages (JSP) 1.0 specification. Similar in concept to Microsoft’s Active Server Pages (ASP) introduced in December of 1996, Java Server Pages provided an abstraction to the creation of Servlets by enabling developers to create specialized HTML templates embedded with Java “scriptlets” which were compiled to Java Servlets when accessed.

The first draft of the JSP specification included guidance for two approaches to using the new technology. The first was effectively a Model-View separation where requests were routed directly to JSPs which would in turn interact with the application’s model (“JavaBeans” in Java parlance). The second approach, recommended for more complex applications, was effectively a Model-View-Controller separation where requests were routed to Java Servlets which interacted with the model and subsequently transferred control to a JSP for rendering the view back to the browser. An updated draft of the JSP specification referred to these approaches as Model 1 and Model 2 respectively. While no association with the Smalltalk-80 MVC pattern was made within the specification, the similarity was noted in an article appearing in Java World magazine on December of the same year, stating that the Model 2 architecture could be seen as a “server-side implementation of the popular Model-View-Controller (MVC) design pattern” (17). While introduced by Sun as the Model 2 architecture, the credit for the mainstream adoption of a Web-based Model-View-Controller pattern rightly belongs to Craig R. McClanahan for his creation of the Struts framework and its donation to the Apache Foundation in June of 2000. Struts was introduced as an MVC framework and became widely adopted in the Java development community upon its release as well as the catalyst for the development of a plethora of frameworks in the following years.

Structure

While no canonical structure exists, the following diagram is a depiction of how the MVC pattern is often adapted for Web development:

3

Components

With Web applications, a Front Controller is often introduced to handle common infrastructure concerns as well as dispatching requests to individual Controllers. This might take the form of a Servlet in Java-based applications, or an IHttpHandler in ASP.Net-based applications. Examples of common concerns handled by a Front Controller might include security, session state management, or dependency injection resolution of the handling Controller. As with the Smalltalk-80 MVC pattern, the Model encapsulates the data and business functionality of the application and is typically represented by a Domain Model. In Web applications, the View is the content (generally HTML and associated client-side script) returned to the Web client. Depending on the implementation, Views may be text-based templates which are rendered by a view processor, or they may be objects compiled from templates which encapsulate the content to be rendered. Also similar to the original Smalltalk-80 MVC pattern, the Controller is a component which responds to user input. What differs is that rather than receiving signals directly from hardware devices such as the keyboard, mouse, etc., Web-based MVC Controllers process delegated HTTP requests (or information derived from the request depending upon the specific implementation).

Collaborations

Upon receiving an HTTP request, the Front Controller executes any common behavior and then uses information derived from the request to locate the concerned Controller. After a Controller is located, the request is delegated for further handling. Once the Controller receives the specific request, the appropriate operations are performed upon the Model and control is transferred to the View. Due to the fact that Web applications are stateless, Views are rendered anew upon each request. As such, the Observer Pattern is not used in the process of updating the View. To render the View with the appropriate state, the Controller makes the required state available in the form of a Model, a Presentation Model, or some more rudimentary form such as a bag of name/value pairs. Depending upon the implementation, the View then renders the output stream or is parsed by a separate processor to render the output stream based upon the view state made available by the Controller. In the following section, another derivative of the Model-View-Controller pattern will be discussed which largely resulted as an adaptation for use with the Microsoft Windows development platform. This pattern is known as the Model-View-Presenter pattern.

The Model-View-Presenter Pattern

The Model-View-Presenter pattern is a variation on the Model-View-Controller pattern, and similarly separates the concerns of an application’s domain, presentation, and user input into specialized components. The definition and distinctive characteristics of this pattern are not easily summarized due to the fact that there are several patterns commonly accepted under the name “Model-View-Presenter” which do not share the same distinctive qualities over their MVC predecessor. For this reason, this article will discuss the original Model-View-Presenter pattern along with some of its more popular variations and derivatives.

The Taligent Model-View-Presenter Pattern

Overview

The Taligent Model-View-Presenter pattern separates the application concerns of data, data specification, data manipulation, application coordination, user interaction, and presentation into specialized components (whew, that’s a mouthful).

Origins and Motivation

The MVP pattern was based on the Taligent programming model, which itself was influenced by the original Smalltalk-80 MVC pattern. The pattern was first formally described by Mike Potel in 1996 while working for Taligent, Inc.. Taligent was started by Apple Computer, Inc. as a joint venture with IBM (and later joined by Hewlett Packard) before becoming the wholly owned subsidiary of IBM in late 1995. Many of the elements of the original MVP pattern began taking form at Apple under the management of Larry Tesler, who formerly worked at Xerox PARC where he was one of the contributors of the design and implementation of Smalltalk. While the main elements of the pattern were already being utilized at Taligent between 1992 and 1994, it wasn’t until after Taligent, Inc. was purchased by IBM in 1995 that Mike Potel first suggested the name “Model-View-Presenter” to describe the architecture found within the Taligent programming model. Dr. Potel credits Arn Schaeffer, Dave Anderson, and David Goldsmith as leading contributors to the Taligent programming model from which the MVP pattern was derived (3).

Structure

The following diagram depicts the structure of the Taligent Model-View-Presenter pattern:

 

Com4ponents

The Model refers to the data and business functionality of the application. Selections are components which specify what portion of the data within the Model is to be operated upon. Examples would be selections which define rows, columns, or individual elements which meet specific criteria. Commands are components which define the operations which can be performed on the data. Examples might be deleting, printing, or saving data within the Model. The View is the visual representation of the Model and is comprised of the screens and widgets used within an application. Interactors are components which address how user events are mapped onto operations performed on the Model, such as mouse movements, keyboard input, and the selection of checkboxes or menu items. The Presenter is a component which orchestrates the overall interaction of the other components within the application. Its roles include the creation of the appropriate Models, Selections, Commands, Views, and Interactors, and directing the workflow within the application.

Collaborations

The most notable collaborative differences between the Taligent Model-View-Presenter pattern and the Model-View-Controller pattern are found within the Presenters and Interactors. The Presenter acts as an overall manager for a particular subsystem within an application. It maintains the lifecycle and relationships between the Views, Interactors, Commands, Selections, and Model. The responsibility for intercepting user events is governed by Interactors; therefore Presenters are not needed for each widget on a given View as were Smalltalk-80 Controllers. There is generally a single Presenter per View, though in some cases a Presenter may manage multiple logically related Views. Interactors are somewhat analogous to Smalltalk-80 Controllers. They are the components which respond to user events and in turn call the appropriate Commands and Selections of the Model.

The Dolphin Smalltalk Model-View-Presenter Pattern

Overview

The Dolphin Smalltalk Model-View-Presenter pattern separates an application’s concerns of domain, presentation, and presentation logic into the specialized components of Model, View, and Presenter. The Dolphin Smalltalk team simplified the Taligent MVP pattern by eliminating Interactors, Commands, and Selections from the pattern’s formal description. This in turn simplified the role of the Presenter, changing it from a subsystem controller to a component which mediated updates to the Model on behalf of the View.

Origins and Motivation

The Dolphin Smalltalk Model-View-Presenter pattern was adapted from the Taligent Model-View-Presenter pattern to address flexibility issues the Dolphin development team was having in its approach to view/domain separation. One of the team’s early considerations included a variation on the MVC pattern used by ParcPlace Systems’ VisualWorks. While the Dolphin team considered the VisualWorks MVC design initially, they later became disenchanted with its prescribed Application Model whose complexity at times tempted developers to allow the model to access the view directly. They also found that the MVC concept of a Controller, whose primary purpose was to respond to user events, didn’t mesh well with more current development platforms whose native widgets handled user events directly. After encountering the Taligent MVP pattern, the Dolphin team concluded it was more applicable for achieving their design goals. While they saw benefits in the Taligent MVP pattern, they mistakenly believed that Taligent derived their pattern from the VisualWorks’ MVC implementation and had eliminated the use of an Application Model by moving presentation logic concerns from the Model to the Presenter. They described this as “Twisting the Triad”, though this does not accurately portray the differences between the Taligent MVP pattern and the original Smalltalk-80 MVC pattern. Due to this misunderstanding, they viewed the Presenter component as being a replacement of the Application Model within VisualWorks’ MVC rather than an evolution of the Controller component within the Smalltalk-80 MVC. The resulting pattern implemented by the Dolphin Smalltalk team was void of most of the components which gave the original MVP its distinctiveness from MVC, though it introduced distinctive qualities of its own.

Structure

The following diagram depicts the structure of the Dolphin Smalltalk Model-View-Presenter pattern:

5

Components

The Model refers to the data and business functionality of the application. The View is the visual representation of the Model and is comprised of the screens and widgets used within an application. The Presenter is a component which contains the presentation logic which interacts with the Model.

Collaborations

Within the Dolphin MVP pattern, Views intercept the initial user events generated by the operating system. This choice was primarily the result of development on the Microsoft Windows operating system whose native widgets already handled most controller functionality. In a few cases the View responded to user events by updating the Model directly, but in most cases user events were delegated to the Presenter. Implied by the Dolphin Smalltalk description is that Views only delegated events when updates to the Model were required, thus leaving all other presentation logic within the View. As with the Taligent MVP pattern, there is usually a single Presenter which handles updates to the Model for a specific View. As with the Model-View-Controller pattern, the View is notified of any changes to the Model using the Observer Pattern and responds by updating the relevant portions of the screen.

Dolphin Smalltalk MVP vs. Smalltalk-80 MVC

On the surface, the differences between the Dolphin Smalltalk MVP pattern and the Smalltalk-80 MVC pattern are difficult to discern. Both of the patterns contain a triad. Both of the patterns contain a Model and View which are virtually identical in function. Both the Smalltalk-80 Controller and the Dolphin Smalltalk Presenter are involved in updating the Model. Both of the patterns use the Observer Pattern to update the View when changes occur to the Model. With all these similarities, it is clear why so much confusion surrounds understanding how the Model-View-Presenter pattern sets itself apart from the Model-View-Controller pattern. The key is in understanding the primary functions which Presenters and Controllers play within their respective triads. Within the original Model-View-Controller pattern, the primary purpose of the Controller was to intercept user input. The Controller’s role of updating the Model was largely a byproduct of this function rather than an inherent part of its purpose. Conversely, within the Dolphin Smalltalk Model-View-Presenter pattern, the primary purpose of the Presenter was to update the Model. The Presenter’s role of intercepting events delegated by the View was largely a byproduct of this function rather than an inherent part of its purpose. Part of the original idea leading to the development of the MVC pattern was a separation between the representation of a user’s mental idea of the data (i.e. the Model), and the logic which allowed the user to interact with that representation (i.e. the Editor). This was considered Model/Editor separation (4). Because the tasks involved in displaying data on the screen were technically very different from the tasks involved in interpreting the user’s input from devices such as the keyboard and the mouse, the combination of these tasks into a single object resulted in unnecessary complexity. Therefore, the concerns of input and output were separated into Views and Controllers. Because Controllers were assigned the input responsibility of the Editor, it naturally followed that they took on the responsibility of updating the Model when input was received from the user. Within the Dolphin Smalltalk MVP pattern, the role of intercepting the user’s input was moved to the View. This effectively eliminated the original need for Controllers or Interactors altogether. While the original idea of the Presenter was seen by the Taligent team as a Controller elevated to an application level, the Dolphin team mistakenly considered it a replacement of the VisualWorks’ Application Model and maintained the Presenter as a mediating component within the triad. So then, while the Dolphin Smalltalk MVP and the Smalltalk-80 MVC patterns may appear similar on the surface, Presenters and Controllers differ in the purposes they were conceived to address.

The Fowler Patterns

During his research and preparation of material on presentation layer patterns in 2006 for an upcoming book, Martin Fowler decided that the treatment given to the design intensions behind today’s use of the Model-View-Presenter pattern be divided under the names Supervising Controller and Passive View. This distinction was made around the level of responsibility the Presenter/Controller component of the pattern takes on for presentation layer logic. The Supervising Controller and Passive View patterns are well distilled constructs which deal with the concerns of presentation logic apart from any specific domain logic strategy. This distilment renders patterns which describe solutions not specific to the Model-View-Presenter pattern, and are an excellent example of how patterns come about. While discussed here within the context of the Model-View-Presenter pattern, these patterns are best understood as facilitating patterns (as with the Observer Pattern) rather than variations of the Model-View-Presenter pattern.

The Supervising Controller Pattern

Overview

The Supervising Controller pattern separates an application’s concerns of presentation and presentation logic into the specialized components of View and Controller, with the View assigned the responsibility of simple presentation logic and the Controller assigned the responsibilities of responding to user input and handling complex presentation logic.

Structure

The following diagram depicts the structure of the Supervising Controller pattern:

6

Note: The model is shown with reduced emphasis to denote its peripheral role to the pattern description.

Components

The View is the visual components used within an application such as screens and widgets. The Controller is a component which processes user events and the complex presentation logic within an application.

Collaborations

Within the Supervising Controller pattern, Views delegate user events to the Controller which in turn interacts with the business domain of the application. For simple presentation logic, the View uses data binding techniques and the Observer Pattern to update itself when changes occur within the application. Complex presentation logic, particularly any logic one desires to unit test, is delegated to the Presenter.

The Passive View Pattern

Overview

The Passive View pattern separates an application’s concerns of presentation and presentation logic into the specialized components of View and Controller, with the Controller taking on the responsibility for responding to user events and presentation logic.

Structure

The following diagram depicts the structure of the Passive View pattern:

7

Note: The model is shown with reduced emphasis to denote its peripheral role to the pattern description.

Components

The View is the visual components used within an application such screens and widgets. The Controller is a component which processes user events and the presentation logic within an application.

Collaborations

Within the Passive View pattern, Views delegate user events to the Controller which in turn interacts with the business domain of the application and/or updates the View. The View maintains no link to the domain layer and relies solely on the Controller for all presentation related logic. Controllers within this pattern take on a mediating role between the Views and domain logic strategy used. This formalizes a role often erroneously ascribed to Controllers within the Model-View-Controller pattern.

The Presentation-Abstraction-Control Pattern

Overview

The Presentation-Abstraction-Control pattern is an architecture which separates the concerns of an application into a hierarchy of cooperating components, each of which are comprised of a Presentation, Abstraction, and Control. The PAC pattern seeks to decompose an application into a hierarchy of abstractions, and to achieve a consistent framework for constructing user interfaces at any level of abstraction within the application.

Origins and Motivation

The PAC pattern was conceived by Joëlle Coutaz in 1987. The goal of the pattern was to provide a model for developing interactive applications which bridges the gap between theoretical models for human/computer interaction and the practical concerns of building user interfaces. The original pattern description can be found in the publication: “PAC, and Object Oriented Model for Dialog Design”. In her article, Coutaz sets forth that the PAC model more closely follows the cognitive organization of human knowledge. That is to say, the human mind doesn’t perceive the world in layers, but rather in an interconnected web of abstract ideas.

Structure

The following diagram depicts the structure of the Presentation-Abstraction-Control pattern:

8

Components

The Presentation is the visual representation of a particular abstraction within the application. It is responsible for defining how the user interacts with the system. The Abstraction is the business domain functionality within the application. The Control is a component which maintains consistency between the abstractions within the system and their presentation to the user in addition to communicating with other Controls within the system. Note: Later descriptions generally use the term “agent” to describe each Presentation-Abstraction-Control triad.

Collaborations

Conceptually, the Presentation-Abstraction-Control pattern approaches the organization of an application as a hierarchy of subsystems rather than layers of responsibility (e.g. Presentation Layer, Domain Layer, Resource Access Layer, etc.). Each system within the application may depend on zero or more subsystems to accomplish its function. Each subsystem presents a finer grained view of an aspect of the overall system. By organizing systems into a hierarchy of subsystems, each of which are composed of the same PAC components, any level of granularity of the system can be inspected while maintaining the same architectural model. While interaction between the user and the application occurs through the Presentation components, interaction within the Presentation-Abstraction-Control pattern is accomplished exclusively through the Control element of each triad. The Control exists to bridge the gap between the presentation and the abstraction and maintains extensive knowledge about both components (6). Its responsibilities include updating the view, accessing the abstraction, maintaining state, thread management, flow control, and interaction with parent and child Controls. There exists no direct link between the Presentation and Abstraction within a PAC object (7).

Pattern Variations and Derivatives

From 1989 through 1995, the Commission of the European Communities funded two Human Computer Interface research projects under the names Amodeus and Amodeus-2 (8). Amodeus was an acronym for “Assimilating Models of Designers, Users and Systems”. During Amodeus-2, a researcher named Laurence Nigay, working under the supervision of Joëlle Coutaz, created the PAC-Amodeus Model. PAC-Amodeus is a model which blends the software components advocated by the Arch Model and the multi-agent model prescribed by the Presentation-Abstraction-Control pattern (9). The Arch Model was proposed by Len Bass at a UIMS Tool Developers’ Workshop in 1991 as a way to accommodate rapidly changing UI requirements (10) and itself was a derivative of the Seeheim Model developed in 1985. In many ways the Arch Model was similar to the Taligent Model which was to follow only a few years later. It prescribed a central Dialog Controller which mediated the interaction between the presentation and domain layer components, and used explicit components to define the interaction between the controller, presentation, and domain components. While the Arch Model prescribed specific components to accomplish its goal of flexibility and reuse, the underlying principle at work was its adherence to a layered organization of the application. While PAC provided a highly organized and uniform pattern for decomposing the tasks performed by an application, its insistence on a homogeneous design led to tightly coupled components which were difficult to maintain and reuse. The benefits of the layered approach were appreciated in the Arch Model, but the prescribed Dialog Controller was seen as too vague and all encompassing. It was therefore decided to use the Arch Model as the foundational model, but organize the tasks accomplished by the Dialog Controller into a series of PAC agents whose Presentation and Abstraction components mapped into other layered components within the Arch Model. Another derivative of PAC, by way of PAC-Amodeus, is PAC*. PAC* was developed by Gaelle Calvary, Laurence Nigay, and Joëlle Coutaz around 1997 (11). PAC* follows the PAC-Amodeus style of using the Arch Model as the base architecture with a dialog controller organized as PAC agents, but also incorporates concepts found within a model named Dewan’s Generic Architecture for addressing layer replication within multi-user applications. Full discussions of the PAC-Amodeus and PAC* are beyond the scope of this article, but a good summary of the Seeheim, Arch, PAC, PAC-Amodeus, and PAC* models among others can be found in a technical report by W. Greg Phillips entitled: “Architectures for Synchronous Groupware”. Another pattern worthy of note is the Hierarchical-Model-View-Controller pattern. While not a direct derivative of the PAC family of patterns, the HMVC pattern is often associated with PAC due to its similarities. The HMVC pattern was first described in an article which appeared in JavaWorld Magazine in July of 2000. Developed by Jason Cai, Ranjit Kapila and Gaurav Pal, the HMVC pattern is a prescription for organizing Model-View-Controller triads into a hierarchy for organizing the presentation layer of a rich client application such as Java Swing applications. While its organization of MVC triads into a hierarchy is similar to PAC, it differs in that Model and View components maintain the same observer relationship as within MVC, and more notably that it seeks only to address the presentation layer of an application rather than addressing the entire application architecture. While derived from the Model-View-Controller pattern, Controllers within the HMVC pattern are described as fulfilling a mediating role within the triad similar to the Supervising Controller pattern. Views receive the initial events generated by the user and decide which actions to delegate to the Controller. For this reason, the HMVC pattern is more similar to the Dolphin MVP pattern than with either the original Model-View-Controller or Presentation-Abstraction-Control patterns.

Pattern Comparisons

The following chart presents a quick comparison of the components represented in the various patterns presented in this article with a brief description of its role within the architecture.

Pattern Domain Presentation Control
Smalltalk-80 Model-View-Controller Model – domain objects within an application View- Visual presentation to the user Controller – human to Model connector; Intercepts user input
Taligent Model-View-Presenter Same as above Same as above Presenter – subsystem component connector; manages application subsystems
Dolphin Model-View-Presenter Same as above Same as above Presenter – presentation to domain connector; manages access to Model updates
Passive View N/A Same as above Controller – manages presentation logic
Supervising Controller N/A Same as above Controller – assists with presentation logic
Presentation-Abstraction-Control Abstraction – domain objects within an application Presentation – interactive component within the application Control – Presentation to Abstraction connector

Conclusion

The Model-View-Controller, Model-View-Presenter, and Presentation-Abstraction-Control patterns are similar in many ways, but have each evolved to address slightly different concerns. By becoming familiar with these patterns and other related architecture models, developers and architects will be better equipped in choosing an appropriate solution in their next design endeavor, or possibly in the creation of future architecture design patterns.

References

1. Reenskaug, Trygve. The original MVC reports. Trygve Reenskaug Home Page. [Online] May 12, 1979. [Cited: July 07, 2007.] http://heim.ifi.uio.no/~trygver/2007/MVC_Originals.pdf.

2. Steve Burbeck, Ph. D. Applications Programming in Smalltalk-80(TM): How to use Model-View-Controller (MVC). The UIUC Smalltalk Archive. [Online] March 4, 1997. [Cited: July 7, 2007.] http://st-www.cs.uiuc.edu/users/smarch/st-docs/mvc.html.

3. Potel, Mike. [interv.] Derek Greer. July 18, 2007.

4. Reenskaug, Trygve. The Model-View-Controller (MVC) Its Past and Present. Trygve Reenskaug Home Page. [Online] August 20, 2003. [Cited: July 7, 2007.] http://heim.ifi.uio.no/~trygver/2003/javazone-jaoo/MVC_pattern.pdf.

5. Fowler, Martin. Patterns of Enterprise Application Architecture . s.l. : Addison-Wesley Professional, 2002. 978-0321127426.

6. PAC, an Object Oriented Model for Dialog Design. Coutaz, Joëlle. [ed.] H-J. Bullinger and B. Shackel. North-Holland : Elsevier Science Publishers, 1987. Interact’87.

7. Calvary, Gaëlle, Coutaz, Joëlle and Nigay, Laurence. From Single-User Architectural Design to PAC*: a Generic Software Architecture Model for CSCW. [http://www1.acm.org/sigs/sigchi/chi97/proceedings/paper/jcc.htm] Grenoble, France : s.n., 1997.

8. AMODEUS-2 – Multidisciplinary HCI Modelling. http://kmi.open.ac.uk. [Online] 1997. [Cited: August 20, 2007.] http://kmi.open.ac.uk/people/sbs/amodeus.html.

9. Nigay, L. and Coutaz, J. Software Architecture Modelling: Bridging Two Worlds Using Ergonomics and Software Properties. http://iihm.imag.fr/. [Online] [Cited: August 20, 2007.] Software Architecture Modelling: Bridging Two Worlds Using Ergonomics and Software Properties.

10. Sheppard, Sylvia. REPORT ON THE CHI ’91 UIMS TOOL DEVELOPERS’ WORKSHO P. SIGCHI Bulletin. January 1992, Vol. 24, 1.

11. Coutaz, Joëlle. Correspondance with Joëlle Coutaz. [Email]. August 20, 2007.

12. Fowler, Martin. GUI Architectures. http://www.martinfowler.com. [Online] July 18, 2006. [Cited: July 03, 2007.] http://www.martinfowler.com/eaaDev/uiArchs.html.

13. —. Supervising Controller. http://www.martinfowler.com. [Online] June 19, 2006. [Cited: July 03, 2007.] http://www.martinfowler.com/eaaDev/SupervisingPresenter.html.

14. —. Passive View. http://www.martinfowler.com. [Online] July 18, 2006. [Cited: July 3, 2007.] http://www.ibm.com/developerworks/java/library/j-mvp.html.

15. Potel, Mike. MVP: Model-View-Presenter – The Taligent Programming Model for C++ and Java. http://www.wildcrest.com. [Online] 1996. [Cited: July 15, 2007.] http://www.wildcrest.com/Potel/Portfolio/mvp.pdf/.

16. Phillips, W. Greg. Architectures for Synchronous Groupware. Kingston, Ontario, Canada : s.n., May 6, 1999. ISSN 0836-0227-1999-425.

17. A metamodel for the runtime architecture of an interactive system: the UIMS tool developers workshop. 1, New York, NY : ACM Press, January 1992, ACM SIGCHI Bulletin, Vol. 24, pp. 32-37. ISSN 0736-6906.

18. Understanding JavaServer Pages Model 2 architecture. http://www.javaworld.com. [Online] December 29, 1999. [Cited: February 8, 2010.] http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html.

MVC模式理解——当年给我一个browser多好

 

————————————————————————————————————

来源:http://www.cppblog.com/darkdestiny/archive/2009/01/13/71944.aspx

————————————————————————————————————

以前一直无法舒坦的理解,MVC模式是怎样实际应用到一个程序上的。

这两天因为工作google出一幅图,然后恍然大悟。

图1.

mvc-rails

问题就出在以前所看过的文章上根本没有提过browser这层。导致我无法正确理解view的责任、controller的责任,以及两者明明是分层的,为什么却是循环依赖。

我将browser介入其中,重新思考MVC模式究竟如何部署到程序结构上。

图2.

mvc

计算机前的用户,只会和browser打交道,也就是整个应用程序的界面部署,各种窗口,包括菜单、按钮、子对话框等等。

我把整个界面部署的代码,全部放置到browser模块下。此时无需model、view、controller,仅有browser的代码,我们就可以给用户显示这个界面。

接下来我引入model模块,这个模块的代码和窗口无关、和控件无关、和HWND无关。就是一个后台运行的东西,不需要面向任何用户。

model包含了业务的本质数据结构和逻辑流程。

然后我引入view模块,view模块代码的责任就是,如何利用browser显示model的内容。

这个责任有两个潜在意义:

1. browser模块的代码不会去访问model模块的内容,并显示在browser相应的窗口上。

2. 在没有controller的情况下——用户不能操作程序界面上的任何菜单、按钮,只能看不能摸,view模块能够在browser上给用户显示model的内容。

因此,view模块在MVC模式中所能做的就是:

1. 访问model模块,获取内容。

2. 访问browser模块,修改窗口。

最后引入controller模块。

用户在计算机前看着browser,浏览业务数据,他肯定会做一些操作,比如按下按钮,选个菜单或者其他什么的。

用户修改model模块的每一个决定性操作,就映射在controller模块的一个接口上。controller模块的责任是,代表用户的每一个动作,并分解为多个view做什么,model做什么的调用。这个动作必须有操作model或者view的代码,不然这个动作放在browser模块下就可以了。

现在合起来分析个例子,用户通过browser向model添加一个任务。

按下确定按钮后,browser读取其他子窗口的输入数据,当做参数传递给controller模块对应的调用。

l controller模块不会主动的从browser中的控件中读取数据。如果用户的动作足够简单,controller有可能就仅仅作为一个中间层调用model模块。

controller模块将用户的动作分解为一些更细致的调用:

1. 让model添加新任务。(不关心model怎么做)

2. 从model中获取新任务的信息。

3. 将新任务的信息传递给view,让他在browser显示出来。(不关心view怎么做)

从controller的动作分解中可以看出:

l 和之前view直接访问model获取数据不一样,这里controller从model获取数据,并交给view。仅由controller访问model是有好处的,使得view和model没有了耦合。

l 这里有一个微妙的循环依赖关系,browser依赖于controller,controller依赖于view,view又依赖于browser。

l 解开这一依赖的方法1,提取一个view interface,让controller依赖于他,而不是依赖于view。提取controller interface也是同理。

l 方法2,controller不依赖于view,让view自己负责根据model的状态改变显示,即controller负责修改model,view负责读取model。

l 不过,view和model之间通过controller传递数据是有好处的,除了耦合之外,另一个关键的地方是,可以在controller中过滤数据,而不用修改model。

l 这两个方法没有最好,只有根据具体的情况选择最合适的做法。在程序足够小的情况下,其实是不需要把模块划分得那么清楚的。

My ten development principles

——————————————————————————————————————————

来源:http://www.makinggoodsoftware.com/2010/03/13/my-ten-development-principles/

After several years developing software, I have acquired a very a strong opinion on how software should be developed, I actually have come to the conclusion that everything boils down to 10 principles, that if well implemented, will make any software development successful.

1.- Customer first.

“If we don’t take care of the customer… somebody else will.”

Customer first means focusing from a customer perspective on real value for the product being developed, other aspects as: contracts, requirements, technologies… should take a secondary role in the project.

Not focusing on the customer in one the top 5 five non technical mistakes made by programmers.

2.- Code quality.

Even though code quality is something very subjective, (all code is crap), it drives many important aspects as: how hard is to maintain the application or how hard is to take on board a new developer.

In my opinion, the main indicators for code quality are: simplicity, readability, robustness and testability. Other qualities as performance or extensibility, if not required, will over engineer your application.

3.- Empowerment.

People are the most valued resource in software development, not the technologies. They are the ones that make the difference between a mediocre product and an excellent product, but they need to be empowered

Empowerment is the process where people is encouraged to be proactive and take decisions. Some of the most effective mechanisms to empower are: coaching, pairing or delegating.

There is an excellent article from Tony Morgan explaining the difference between a classic delegation approach and empowerment.

empowerment

4.- Continuous integration.

Integration is, from my experience, a major issue in software development. Waiting to integrate at the end of the project or after a big chunk of functionality is completed, is always a traumatic process.

Continuous integration is the process that guarantees that every piece of code committed is automatically integrated in the system. Remember that continuous integration goes beyond continuous compilation.

This article from Martin Fowler, is one of the best references online about continuous integration.

5.- Iterations.

Iterations provide continuous feedback. Continuous feedback is important because it reduces the amount of uncertainty in software development.

While iterations are usually only related to agile methodologies, it is important to remember that there are other methodologies as RUP which also use iterations and they are not part of the agile family.

6.- Automated testing.

Allows refactoring and iterations, provides confidence and if well implemented, enhances the correctness of the final product. To automate tests you may consider some facts about testing and some advices on how to write a good test suite.

7.- Refactoring.

No matter how much care you put on coding, on your first attempt, you are going to be wrong. Refactoring is the practice by which we keep changing the code to meet the changes necessary to introduce in the system.

8.- Informal architecture.

Big design upfront (BDUF), unless you are NASA and can expend 50-60% percent of your project time on it, is a complete waste, but so it is coding without any preparation. Informal architecture is a compromise solution where architecture is discussed in an ongoing basics and is persisted in light documents, boards or similar.

9.- Communication.

Software development is ONLY about communication. The customer explains to the software development team what he wants to accomplish so that the software development team can explain it through code to a computer.

requirements-communication

10.- Avoid waste.

Waste accounts is one of the major productivity killers in software development: unnecessary meetings, unnecessary requirements, unnecessary process, unnecessary documentation, being some of the most common and dangerous.

寻找小强——数据传输故障调查实例

太长了,而且萨苏的博客应该会非常稳定,不会出现“你所访问的文章已经被移除”“该地址不存在”如此之类的情况,就不全文迁移了。这篇文章是08年的时候看,当时没仔细看。今天翻出来发现,倒是一篇非常好的critical issue素材。

————————————————————————————————————————

此部分用于搜索引擎站内搜索:

萨苏,数据传输故障,数据包,服务器缓冲,pool,分布式,

————————————————————————————————————————

寻找小强——数据传输故障调查实例(一)

http://blog.sina.com.cn/s/blog_476745f60100a2am.html

寻找小强——数据传输故障调查实例(二)

http://blog.sina.com.cn/s/blog_476745f60100a2b8.html

寻找小强——数据传输故障调查实例(三)

http://blog.sina.com.cn/s/blog_476745f60100a2rd.html

寻找小强——数据传输故障调查实例(四)

http://blog.sina.com.cn/s/blog_476745f60100a4fv.html

寻找小强——数据传输故障调查实例(五)

http://blog.sina.com.cn/s/blog_476745f60100a4tx.html

追MM与23种设计模式

来源:不明

创建型模式

1、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory

工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。

2、BUILDER—MM最爱听的就是“我爱你”这句话了,见到不同地方的MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语 言都有一个按键,见到MM我只要按对应的键,它就能够用相应的语言说出“我爱你”这句话了,国外的MM也可以轻松搞掂,这就是我的“我爱 你”builder。(这一定比美军在伊拉克用的翻译机好卖)

建造模式:将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。

3、FACTORY METHOD—请MM去麦当劳吃汉堡,不同的MM有不同的口味,要每个都记住是一件烦人的事情,我一般采用Factory Method模式,带着MM到服务员那儿,说“要一个汉堡”,具体要什么样的汉堡呢,让MM直接跟服务员说就行了。

工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

4、PROTOTYPE—跟MM用QQ聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,需要时只要copy出来放到QQ里面就行了,这就是我的情话prototype了。(100块钱一份,你要不要)

原始模型模式:通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。原始模型模式允许动态的增加或减 少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构。缺点是每一个类都必须配备一个克隆方法。

5、SINGLETON—俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Sigleton,她们只要说道“老公”,都是指的同一个人,那就是我(刚才做了个梦啦,哪有这么好的事)

单例模式:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。

结构型模式

6、ADAPTER—在朋友聚会上碰到了一个美女Sarah,从香港来的,可我不会说粤语,她不会说普通话,只好求助于我的朋友kent了,他作为我和Sarah之间的Adapter,让我和Sarah可以相互交谈了(也不知道他会不会耍我)

适配器(变压器)模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。

7、BRIDGE—早上碰到MM,要说早上好,晚上碰到MM,要说晚上好;碰到MM穿了件新衣服,要说你的衣服好漂亮哦,碰到MM新做的发型,要说你的头发好漂亮哦。不要问我“早上碰到MM新做了个发型怎么说”这种问题,自己用BRIDGE组合一下不就行了

桥梁模式:将抽象化与实现化脱耦,使得二者可以独立的变化,也就是说将他们之间的强关联变成弱关联,也就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以独立的变化。

8、COMPOSITE—Mary今天过生日。“我过生日,你要送我一件礼物。”“嗯,好吧,去商店,你自己挑。”“这件T恤挺漂亮,买,这条裙子好看, 买,这个包也不错,买。”“喂,买了三件了呀,我只答应送一件礼物的哦。”“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻烦你包起 来。”“……”,MM都会用Composite模式了,你会了没有?

合成模式:合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。

9、DECORATOR—Mary过完轮到Sarly过生日,还是不要叫她自己挑了,不然这个月伙食费肯定玩完,拿出我去年在华山顶上照的照片,在背面写 上“最好的的礼物,就是爱你的Fita”,再到街上礼品店买了个像框(卖礼品的MM也很漂亮哦),再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起 来……,我们都是Decorator,最终都在修饰我这个人呀,怎么样,看懂了吗?

装饰模式:装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。动态给一个对象增加功能,这些功能可以再动态的撤消。增加由一些基本功能的排列组合而产生的非常大量的功能。

10、FACADE—我有一个专业的Nikon相机,我就喜欢自己手动调光圈、快门,这样照出来的照片才专业,但MM可不懂这些,教了半天也不会。幸好相 机有Facade设计模式,把相机调整到自动档,只要对准目标按快门就行了,一切由相机自动调整,这样MM也可以用这个相机给我拍张照片了。

门面模式:外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。每一个子系统只有一个门面类,而且此门面类只有一个实例,也就是说它是一个单例模式。但整个系统可以有多个门面类。

11、FLYWEIGHT—每天跟MM发短信,手指都累死了,最近买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上 MM的名字就可以发送了,再不用一个字一个字敲了。共享的句子就是Flyweight,MM的名字就是提取出来的外部特征,根据上下文情况使用。

享元模式:FLYWEIGHT在拳击比赛中指最轻量级。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴 状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享 的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被 共享的对象。享元模式大幅度的降低内存中对象的数量。

12、PROXY—跟MM在网上聊天,一开头总是“hi,你好”,“你从哪儿来呀?”“你多大了?”“身高多少呀?”这些话,真烦人,写个程序做为我的Proxy吧,凡是接收到这些话都设置好了自动的回答,接收到其他的话时再通知我回答,怎么样,酷吧。

代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情 况下,客户不想或者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以 并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,这时候代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色代为创建并传入。

行为模式

13、CHAIN OF RESPONSIBLEITY—晚上去上英语课,为了好开溜坐到了最后一排,哇,前面坐了好几个漂亮的MM哎,找张纸条,写上“Hi,可以做我的女朋友 吗?如果不愿意请向前传”,纸条就一个接一个的传上去了,糟糕,传到第一排的MM把纸条传给老师了,听说是个老处女呀,快跑!

责任链模式:在责任链模式中,很多对象由每一个对象对其下家的引用而接

起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。客户并不知道链上的哪一个对象最终处理这个请求,系统可以在不影响客户端的情 况下动态的重新组织链和分配责任。处理者有两个选择:承担责任或者把责任推给下家。一个请求可以最终不被任何接收端对象所接受。

14、COMMAND—俺有一个MM家里管得特别严,没法见面,只好借助于她弟弟在我们俩之间传送信息,她对我有什么指示,就写一张纸条让她弟弟带给我。 这不,她弟弟又传送过来一个COMMAND,为了感谢他,我请他吃了碗杂酱面,哪知道他说:“我同时给我姐姐三个男朋友送COMMAND,就数你最小气, 才请我吃面。”,

命令模式:命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。命令模式允许请求的一方和 发送的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否执行,何时被执行以及是怎么被执行的。系统 支持命令的撤消。

15、INTERPRETER—俺有一个《泡MM真经》,上面有各种泡MM的攻略,比如说去吃西餐的步骤、去看电影的方法等等,跟MM约会时,只要做一个Interpreter,照着上面的脚本执行就可以了。

解释器模式:给定一个语言后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。解释器模 式将描述怎样在有了一个简单的文法后,使用模式设计解释这些语句。在解释器模式里面提到的语言是指任何解释器对象能够解释的任何组合。在解释器模式中需要 定义一个代表文法的命令类的等级结构,也就是一系列的组合规则。每一个命令对象都有一个解释方法,代表对命令对象的解释。命令对象的等级结构中的对象的任 何排列组合都是一个语言。

16、ITERATOR—我爱上了Mary,不顾一切的向她求婚。

Mary:“想要我跟你结婚,得答应我的条件”

我:“什么条件我都答应,你说吧”

Mary:“我看上了那个一克拉的钻石”

我:“我买,我买,还有吗?”

Mary:“我看上了湖边的那栋别墅”

我:“我买,我买,还有吗?”

Mary:“我看上那辆法拉利跑车”

我脑袋嗡的一声,坐在椅子上,一咬牙:“我买,我买,还有吗?”

……

迭代子模式:迭代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起形成的总体称之为聚集,聚集对象是能够包容一组对象的容 器对象。迭代子模式将迭代逻辑封装到一个独立的子对象中,从而与聚集本身隔开。迭代子模式简化了聚集的界面。每一个聚集对象都可以有一个或一个以上的迭代 子对象,每一个迭代子的迭代状态可以是彼此独立的。迭代算法可以独立于聚集角色变化。

17、MEDIATOR—四个MM打麻将,相互之间谁应该给谁多少钱算不清楚了,幸亏当时我在旁边,按照各自的筹码数算钱,赚了钱的从我这里拿,赔了钱的也付给我,一切就OK啦,俺得到了四个MM的电话。

调停者模式:调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散偶合。当某些对象之间的作用发生改变时,不会 立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的相互作用转化为一对多的相互作用。调停者模式将对象的行为和协 作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。

18、MEMENTO—同时跟几个MM聊天时,一定要记清楚刚才跟MM说了些什么话,不然MM发现了会不高兴的哦,幸亏我有个备忘录,刚才与哪个MM说了什么话我都拷贝一份放到备忘录里面保存,这样可以随时察看以前的记录啦。

备忘录模式:备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。

19、OBSERVER—想知道咱们公司最新MM情报吗?加入公司的MM情报邮件组就行了,tom负责搜集情报,他发现的新情报不用一个一个通知我们,直接发布给邮件组,我们作为订阅者(观察者)就可以及时收到情报啦

观察者模式:观察者模式定义了一种一队多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

20、STATE—跟MM交往时,一定要注意她的状态哦,在不同的状态时她的行为会有不同,比如你约她今天晚上去看电影,对你没兴趣的MM就会说“有事情 啦”,对你不讨厌但还没喜欢上的MM就会说“好啊,不过可以带上我同事么?”,已经喜欢上你的MM就会说“几点钟?看完电影再去泡吧怎么样?”,当然你看 电影过程中表现良好的话,也可以把MM的状态从不讨厌不喜欢变成喜欢哦。

状态模式:状态模式允许一个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一样。状态模式把所研究的对象的行为包装在不同的状态对 象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统 可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。

21、STRATEGY—跟不同类型的MM约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,有的去海边浪漫最合适,单目的都是为了得到MM的芳心,我的追MM锦囊中有好多Strategy哦。

策略模式:策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况 下发生变化。策略模式把行为和环境分开。环境类负责维持和查询行为类,各种算法在具体的策略类中提供。由于算法和环境独立开来,算法的增减,修改都不会影 响到环境和客户端。

22、TEMPLATE METHOD——看过《如何说服女生上床》这部经典文章吗?女生从认识到上床的不变的步骤分为巧遇、打破僵局、展开追求、接吻、前戏、动手、爱抚、进去八 大步骤(Template method),但每个步骤针对不同的情况,都有不一样的做法,这就要看你随机应变啦(具体实现);

模板方法模式:模板方法模式准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类 可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。

23、VISITOR—情人节到了,要给每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个人的特点,每张卡片也要根据个人的特点来挑,我一 个人哪搞得清楚,还是找花店老板和礼品店老板做一下Visitor,让花店老板根据MM的特点选一束花,让礼品店老板也根据每个人特点选一张卡,这样就轻 松多了;

访问者模式:访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。访问者模式 适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。访问者模式使得增加新的操作变的很 容易,就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。当使用访问者模式时,要将尽可能多的对 象浏览逻辑放在访问者类中,而不是放到它的子类中。访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。