2006 年 01 月 23日, 星期一
How to use design patterns(ZZ)
How to Use Design PatternsA Conversation with Erich Gamma, Part I
by Bill Venners
May 23, 2005
SummaryAmong developers, design patterns are a popular way to think about design, but what is the proper way to think about design patterns? In this interview, Erich Gamma, co-author of the landmark book, Design Patterns, talks with Bill Venners about the right way to think about and use design patterns.
Erich Gamma lept onto the software world stage in 1995 as co-author of the best-selling book Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1995) [see Resources]. This landmark work, often referred to as the Gang of Four (GoF) book, cataloged 23 specific solutions to common design problems. In 1998, he teamed up with Kent Beck to produce JUnit [see Resources], the de facto unit testing tool in the Java community. Gamma currently is an IBM Distinguished Engineer at IBM's Object Technology International (OTI) lab in Zurich, Switzerland. He provides leaderships in the Eclipse community, and is responsible for the Java development effort for the Eclipse platform [see Resources].
On October 27, 2004, Bill Venners met with Erich Gamma at the OOPSLA conference in Vancouver, Canada. In this interview, which will be published in multiple installments in the Leading-Edge Java on Artima Developer, Gamma gives insights into software design. In this first installment, Gamma describes gives his opinion on the appropriate ways to think about and use design patterns, and describes the difference between patterns libraries, such as GoF, and an Alexandrian pattern language.
The real value of design patterns
Bill Venners: Bruce Eckel and I teach design classes, and we've found that people really want to know the Gang of Four (GoF) patterns. Patterns help sell seminars. There's a lot of marketing hype around design patterns.
Erich Gamma: Still, after 10 years?
Bill Venners: Yes. People want to know patterns, and I suspect a great deal of that is because "patterns" is still a buzzword. I'd like to cut through the hype and find out what you think people should actually do with patterns. What should their attitude be about patterns? How can people use patterns to do a better job? What is the real value?
Erich Gamma: I think patterns as a whole can help people learn object-oriented thinking: how you can leverage polymorphism, design for composition, delegation, balance responsibilities, and provide pluggable behavior. Patterns go beyond applying objects to some graphical shape example, with a shape class hierarchy and some polymorphic draw method. You really learn about polymorphism when you've understood the patterns. So patterns are good for learning OO and design in general.
Then on top of that, each individual pattern has a different characteristic to help you in some place where you need more flexibility or need to encapsulate an abstraction, or need to make your code less coupled. This is a really big issue in a large system. How do you preserve your layers? How do you avoid up calls or circular dependencies? The GoF patterns provide you with little tools that help you with these problems. They do so not by giving a pat solution but by explaining trade-offs. Even though patterns are abstracted from concrete uses, they also provide you valuable implementation hints. From my perspective it is the fact that patterns are implementable that makes them so valuable.
Patterns are distilled from the experiences of experts. They enable you to repeat a successful design done by someone else. By doing so you can stand on the shoulders of the experts and do not have to re-invent the wheel. However, since patterns enable many implementation variations you still have to keep the brain turned on. Finally, since patterns provide you with names for design building blocks they provide you with a vocabulary to describe and discuss a particular design.
The other question was how we should teach patterns. Not that I know exactly what you should do, but I think what you should not do is have a class and just enumerate the 23 patterns. This approach just doesn't bring anything. You have to feel the pain of a design which has some problem. I guess you only appreciate a pattern once you have felt this design pain.
Bill Venners: What pain?
Erich Gamma: Like realizing your design isn't flexible enough, a single change ripples through the entire system, you have to duplicate code, or the code is just getting more and complex. If you then apply a pattern in such a messy situation it can happen that the pain goes away and you feel good afterwards. It's an eye opener to realize that oh, actually this pattern, factory or strategy, is a solution to my problem. And I think that's the really interesting way to teach.
When I started teaching it was really boring, because I was just enumerating the patterns. I found it far more interesting to try to motivate with real examples how to apply patterns. In other words, you really need to present the problem in a realistic context—synthetic examples do not fly. At OOPSLA I received a Heads First Design Patterns book [see Resources]. It's a great book, not only because it is fun to read but also because they are able to communicate the essence of design patterns in a novel and highly visual way.
Bill Venners: Is the value of patterns, then, that in the real world when I feel a particular kind of pain I'll be able to reach for a known solution?
Erich Gamma: This is definitely the way I'd recommend that people use patterns. Do not start immediately throwing patterns into a design, but use them as you go and understand more of the problem. Because of this I really like to use patterns after the fact, refactoring to patterns. One comment I saw in a news group just after patterns started to become more popular was someone claiming that in a particular program they tried to use all 23 GoF patterns. They said they had failed, because they were only able to use 20. They hoped the client would call them again to come back again so maybe they could squeeze in the other 3.
Trying to use all the patterns is a bad thing, because you will end up with synthetic designs—speculative designs that have flexibility that no one needs. These days software is too complex. We can't afford to speculate what else it should do. We need to really focus on what it needs. That's why I like refactoring to patterns. People should learn that when they have a particular kind of problem or code smell, as people call it these days, they can go to their patterns toolbox to find a solution.
Bill Venners: That's funny, because my second question was that I have observed that often people feel the design with the most patterns is the best. In our design seminar, I have the participants do a design project, which they present to the others at the end of the seminar. Almost invariably, the presenters want to show off how many patterns they used in their design, even though I try to tell them the goal is a clean, easy to understand API, not to win an I-used-the-most-patterns contest. I just heard you say the same thing, that that's not the right way to think about patterns. If not, what is the proper justification for using patterns in designs?
Erich Gamma: A lot of the patterns are about extensibility and reusability. When you really need extensibility, then patterns provide you with a way to achieve it and this is cool. But when you don't need it, you should keep your design simple and not add unnecessary levels of indirection. One of our Eclipse mottos is that we want extensibility where it matters. Actually, if you are interested in how we use patterns in Eclipse I did an attempt to capture their uses in a chapter in the Contributing to Eclipse book [see Resources]. In this chapter I used design patterns to explain pieces of the Eclipse architecture.
Bill Venners: By extensibility, what do you mean?
Erich Gamma: That you can customize behavior without having to touch existing code—one of the classical OO themes. You can reuse something adapted to your particular problem.
Bill Venners: In an article you wrote with Kent Beck, called "JUnit: A Cook's Tour," [see Resources] you walk the reader through the design of JUnit by, as you wrote, "starting with nothing and applying patterns, one after another, until you have the architecture of the system." I thought perhaps this approach may be inspired by Christopher Alexander, whose work on patterns in architecture inspired the software patterns movement. Do you feel that layering one pattern on top of another until you're done is an effective way to design?
Erich Gamma: The Cook's tour is kind of synthetic. We reconstructed the design we did on JUnit. However, we didn't develop JUnit in such a pattern driven way, instead we did it in a strict test-driven way. What is true in JUnit is that there is a core abstraction for a test, and around that core abstraction you see several other design points emerge, which in turn are materialized by pattern instances. That's something you can often observe in mature designs. There are some key abstractions you often see as a design center, and around those key abstractions you want to achieve various things. So you see patterns growing out of such a center. But I wouldn't use this as quality criteria.
Bill Venners: Is that what you're referring to when you say, "pattern density?"
Erich Gamma: Yes, exactly, patterns popping-up around some central abstraction.
Bill Venners: You said TestCase is the core abstraction in JUnit.
Erich Gamma: Actually it is the Test interface which is implemented by TestCase, but yes we started with TestCase and expanded from there.
Bill Venners: And then, could you define density? The number of patterns around it? You said the JUnit Cook's Tour was kind of synthetic.
Erich Gamma: Synthetic in the sense that the cooks tour is what is left over when you strip out all the test activity that happened during our test-driven development. Therefore it is a very compressed presentation. The density shows up in the patterns codified around Test.
We didn't just string patterns together when we designed JUnit. We did it test-driven, starting with a test that we wanted to succeed and once it passed we looked into how we could improve the code. Developing a test framework in test-driven way isn't without its challenges, but once you have the basics working it goes surprisingly smoothly. You see, Kent and I were fluent in patterns when we designed JUnit. So of course, we'd say things like, "Hey, that's composite." Composite is a pattern in JUnit. We also use template method. That's a basic one. We have command. This is of course a key one. We started with test and said, "Oh, this is a command. Oh, this is a template." Because we were fluent in patterns, our conversation was going really fast, enabling a high-velocity design.
This actually illustrates nicely how patterns provide us with design vocabulary. Similarly when you look at a UML diagram, then you see boxes and arrows, but they don't really tell you the meaning behind these relationships. But once you know the pattern then it explains what these relationships are about. If it's observer, it's really clear why there is a link between these two classes. It's because this guy observes that guy. You know exactly what's going on. And I guess that's the key point. Patterns give us a language to talk about design. Actually, the JUnit journey isn't over yet and Kent and I are currently working on JUnit 4. We are continuing to evolve JUnit in a test-driven way. One of our themes is to lower the barriers to entry. To do so we are leveraging J2SE 5 features like annotations to make JUnit easier to use.
Pattern languages
Bill Venners: What is a pattern language, in the Alexandrian sense?
Erich Gamma: Alexander had a very ambitious goal which was to create architectures that improve the quality of life. To achieve this Alexander developed a pattern language. This is a set of patterns that build on each other. A pattern language guides a designer's application of individual patterns to the entire design. When we started design patterns we were not that ambitious. We used a more bottom-up approach based on micro-architectures.
Bill Venners: What do you mean by bottom up?
Erich Gamma: Let me step back a little and describe how I got into patterns. I think that will answer your question. I was working with Andre Weinand on ET++, a comprehensive class library and framework for C++. As I reflected on ET++, it became apparent that a mature framework contains recurring design structures that give you properties like extensibility, decoupling, and last but not least, elegance. Such structures can be considered micro-architectures that contribute to an overall system architecture. I ended up documenting a dozen or so such micro-architectures in my thesis. This approach to patterns differs from pattern languages: Rather than coming up with a set of interwoven patterns top-down, micro-architectures are more independent patterns that eventually relate to each other bottom-up. A pattern language guides you through the whole design, whereas we have these little pieces, bites of engineering knowledge. I confess that this is less ambitious, but still very important and useful.
Bill Venners: Is a pattern language like having a context free grammar, and from which you can make a whole bunch of programs?
Erich Gamma: There are some similarities at an abstract level. In the same way as a grammar can define a whole bunch of programs a pattern language can generate a bunch of solutions. The way Christopher Alexander describes it is that his patterns describe a solution so that it can be applied many times without ever being the same. But in my opinion at this level the commonality ends.
Bill Venners: By generate, what does he mean? If I have a context free grammar, it doesn't generate the programs. I still have to write them.
Erich Gamma: You still have to make the decisions, but a pattern language provides you more guidance and it has some flow. Say you want to design a room in which you are comfortable. He says, first put lights on two sides. OK, now that you have done lights on two sides, what comes next? How do you place the windows? There are other patterns that describe a solution to this problem. He basically guides you through the space. This kind of connection is what differentiates a library of patterns as we have described in the GoF book from a pattern language. What we have found is that our micro-architectures are also no islands. They are related. We sketched these relationships on the inside of the book cover, and this is what Alexander enthusiasts consider the only valuable part of our book.
Bill Venners: It sounds almost like a design methodology. You go this way, do this, this, and this, and you end up with a beautiful, comfortable to sit in room.
Erich Gamma: Yes, when you follow Alexander's patterns approach you follow the patterns in some sequence. We don't prescribe a particular order. If you have a problem, we have the solution for that, but we don't have the next step. We don't give you hints on what to do next. Alexander is way more thorough in this regard. JUnit has a bit of this pattern language approach, because it can help you write a test case. In the JUnit documentation, Kent and I wrote a mini pattern language on how to implement a test. You start with a test, then you want to factor out common setup code, then you want to group tests together and so on.
2005 年 06 月 29日, 星期三
Eclipse3.1正式发布了!
祝贺祝贺!Eclipse首先是一种思想,然后才是IDE。发布PNG Distiller 1.0.0
在做手机应用的时候,经常会碰到二进制格式的图片,而且有的是多个图片放在一个文件中(这样可以减小应用的大小,对于终端编程来说非常有用),但是有时却需要将这些图片提取出来,生成一个个的*.png图片文件,此程序就是干这个的,不过仅限于普通的格式。
下载其中用到了文章http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=232和http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=233中所提到的源代码,在此表示感谢!
2005 年 03 月 26日, 星期六
[转载]我泪长流:沉痛悼念清华水木BBS
我泪长流:沉痛悼念清华水木BBS
时间:2005年03月17日 00:34
来源:马帅 原创-IT
永远记住这个日子:2005年3月16日星期三。在这一天的下午,在中国,乃至世界青年华人群体中享有盛誉的清华水木BBS(202.112.58.200/www.smth.org)死去了:在一小撮人的强令下,清华水木BBS被活活地缠上裹尸布,在众多互联网公民,尤其是广大青年网民的睽睽众目之下,揉捏成一个只对校内开放,而且必须是实名制的行尸走肉似的普通公告板。这个同时有2万多人在线的富于文化价值、富于技术价值、富于交流沟通价值、富于中国教育形象价值、富于中国互联网事业招牌形象价值,同时也富于商业价值的,中国最著名、历史最悠久的网站之一被敢于逆历史潮流的一小撮人给毁掉了!
我泪长流啊!在这个陷阱遍地,内容低俗、污水横流、人心叵测的互联网环境里,清华水木一直是我心目中最圣洁的净土。我1995年的第一次上网,就是从水木清华BBS开始的,也认识了以Ace, Ming, Alex等中国第一批富于创新思维的互联网精英,更认识了一大批也许今生不会谋面但在线上亲热得你死我活的朋友。更是借助清华水木BBS,我熟识了一个女孩子,而这个女孩子最终成为我的发妻。在清华水木BBS上,我是美食版的食神,我也是电脑版的专家,同时是数码产品的粉丝,可忽而又是军事和历史版的拥趸,在特快版上也没少留下我的手迹,更有在电视和电影版上的若干帖子直上十大热门话题。在LOVE版和家庭版上,我也没少给兄弟姐妹们支招。清华水木BBS已经成为我生活的第二个地球
我泪长流啊!清华水木BBS对我的成长所起的作用是我的老师甚至父母无法比拟的。在这里,永远没有难题,永远有人能够帮助你,也永远有人需要你,在这个其乐融融的宝库式家庭里,有数不清的兄弟姐妹能够向你提供解决问题的方法和窍门,对你的决策提出善意的建议,或者向你指出一条自己打破脑袋也可能找不到的明路。我已经养成了一个本来终此一生也不会改变的习惯:就是有什么想法、有什么收获、有什么问题、有什么建议、有什么资源,第一要做的就是赶快帖在水木BBS上与众多的网友共担、共享、共论甚至共吵。有了清华水木BBS,我在这个世界上就有了一个重要的依靠,无论遇到什么问题,我都相信水木BBS一定能够给我一个答案。可是,可是,现在水木BBS死了,我该怎么办?朝夕十年的依靠就这样消失掉了,人世之悲啊!
我泪长流啊!清华水木BBS是中国宣扬三个代表重要思想的重要表征呀!清华水木BBS不仅代表先进的生产力,代表先进的文化,更是代表着人民群众利益。每天有几万人通过清华水木BBS了解、学习着先进的科技,汲取并消化着中国和世界的历史及现代文化,同时清华水木BBS也为数不清的有需求的人解决着就业问题、消费问题、婚嫁问题及其他各类各样的问题。清华水木BBS要是一个人的话,他所积累的阴德已经足以使他成为一个得道的高僧!但就这样一个得道高僧,居然被一小撮人一纸令下给谋杀了!我想谋杀他的人有没有想过后果,有没有想过来世将变成什么?
together for eclipse 7.0
Eclipse的UML插件也不少了,但我一直感觉Borland为Eclipse开发的together插件是最好用的,也是功能最强大的(有可能是因为我一直使用Togehter Control Center的原因),但有一个缺点啊,不是开源的,也不是免费的,:)呵呵,毕竟人家也要赚钱的嘛,但是咱们做开发的一般也不会拿它来用于商业目的,只是作为一个开发工具来使用,所以就出现了对它的破解啊(说明好用啊,呵呵),下面是在Eclipse3.0中使用Together插件的方法:
1. 到Borland网站去下TOGETHER_ECLIPSE_7.exe,这是一个Trial版,不过功能都有了,安装之
2. 到这里下载keygen.jar,在命令行执行:java -jar keygen.jar,会开启一个UI,选择上一步所安装的目录下的ttec.slip(具体在哪个目录下自己找吧),选择之,点确定,然后关闭就可以了
3. 开始你的UML Design之旅吧。。。
2005 年 01 月 18日, 星期二
教育成为暴利行业是国耻!!!
这段时间快忙死了,但再忙也还要看看新闻,听说现在的学费水涨船高,真是气愤之极,教育行业完全成为某些人的摇钱树,真是国耻啊!!!2004 年 12 月 30日, 星期四
关于插件的热部署
现在Eclipse在重新安装一个插件之后,必须重新启动平台,才能使用新安装的插件,包括删除,如果插件正在使用,是不允许删除的,这都给插件的使用带来了不方便。我现在的想法是,可以单独开一个线程,专门负责插件的管理,随时监测plugins目录下的目录结构并动态更新plugin registries(好像实现起来有难度),在插件拷贝(安装)完毕后给所扩展的application发一个插件更新消息,这样application会自己去做更新的工作(比如Workbench)。还有一种方法是使用JMX的架构,动态注册Plugins,这样平台不必重新启动就可以使用新安装的插件。
新的OSGi特性有可能已经包含这样的功能,只是目前还没有使用,研究中。。。
只是一些想法。。。
2004 年 12 月 27日, 星期一
换一种方式进入Eclipse的世界
其实,Eclipse是一个可以进行非常灵活配置的系统,除了以缺省的方式启动以外,还可以指定各种参数来定制启动方式。在参考了一些资料之后,我总结了一些比较常用的启动时Command Arguments,如果有不正确的地方希望大家予以指出。-arch [processor architecture]
描述:指定所使用的处理器的类别
举例:eclipse -arch x86或eclipse -arch sparc
-application [id]
描述:指定要运行的应用,id为扩展org.eclipse.core.applications扩展点的插件id加扩展id
举例:例如有个插件id为edu.sdu.app,扩展id为myapp,则eclipse -application edu.sdu.app.myapp,就会执行你的扩展应用
-clean
描述:清空插件缓存内容
举例:eclipse -clean,有时插件显示不出来是因为Eclipse将插件进行了缓存以加速启动过程,若指定此参数则会清空缓存,从头加载
-configuration [cofigfile location]
描述:指定配置文件的位置,在启动时使用此目录下的配置文件config.ini来启动
举例:eclipse -configuration d:/eclipse/configuration
-data [workspace location]
描述:指定启动时的Workspace位置
举例:例如Workspace位置设在D:/myworkspace,则eclipse -data D:/myworkspace
-debug [option file]
描述:以Debug状态启动Eclipse,所有的Debug开关在.options文件中指定
举例:eclipse -debug d:/eclipse/.options
-dev [classpath entry]
描述:以开发状态启动Eclipse,这会添加所有指定的路径作为每个插件的Classpath
举例:例如eclipse -dev bin,会将产生在bin目录下的所有类加载到类路径中,这在开发插件时非常有用
-nosplash
描述:指定启动时不显示闪屏
举例:eclipse -nosplash
-vm [jre path]
描述:指定启动时所使用的Java虚拟机
举例:例如要使用自己的Java虚拟机,则eclipse -vm D:/j2sdk1.4.2_04/jre/bin/java.exe,这样还有一个好处,就是可以开启一个Console,能够显示控制台信息,当然若使用eclipse -vm D:/j2sdk1.4.2_04/jre/bin/javaw.exe则不会再显示控制台
-vmargs [Java VM arguments]
描述:指定启动时要使用的Java虚拟机参数
举例:例如要指定使用的内存容量,则eclipse -vmargs "-Xms256m -Xmx1024m"
注:此参数一定要放在所有参数变量的最后面
参考文章:
1.Eclipse Help
2.用 Runtime Spy 调整 Eclipse 的启动性能,IBM DeveloperWorks
2004 年 12 月 24日, 星期五
Merry Christmas to All!!!
祝大家平安夜玩得开心!!!2004 年 12 月 23日, 星期四
RCP-Rich Client Platform
RCP确实是个好东西啊,使构建大型客户端应用越来越容易,其实早就想将Eclipse的Workbench单独分离出来了,没想到人家早就已经开始做了http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-ui-home/rcp/index.html