读《Expert One on One J2EE Development Without EJB》C2

1.j2ee提出了规范,给出了一个标准。On the other hand, I feel it has come up short on a number of measures.j2ee也确实降低了企业应用级项目的失败。
2.任何规范和特定的实现都没有一个技术思想重要。如同重构的时机一样:OO原则,针对接口编程;将任何特定的规范已经实现尽量隐藏一般特性之后,比如ejb的接口隐藏在pojo之后。
3.在我自己的技术选择中,几乎都是选择OpenSource社区的,很少受到规范驱动或者vendor驱动的影响。正好相反,也vendor driven才造就今天的我们。:)
4.项目成功,检验架构的标准:
simplicity
productivity
the fundamental importance of object orientation
the primacy of business requirements
the importance of empirical process
the importance of testability
5.一切皆来源于经验过程。spring比Expert One-on-One J2EE还要早。(没有working code就无法写出这本书。)springframework是Rod Johnson几个商业项目的经验而产生的。开发这个framework也应该是在模式大量复用中找到了突破点,如果一些模式大量的被复用,那么把这些模式的职责转嫁给framework来做,dry原则。当然,必须优先考虑模块化的原则,比方说对于log4j的如何集成到framework的方式。
6.Architecture and implementation should always be undertaken with clear goals in mind.

Productivity
1.framework不断抽象,不断重构产生的,framework与代码生成的转换:If we see a requirement for boring repetitive code, we should apply an OO solution and abstract it into a framework,rather than generate it and live with the resulting duplication.
2.代码生成技术在解决生产率中扮着十分重要的角色。在j2ee开发中涉及到代码生成的层次很多。从dll,database schema到jsp.
3.There shouldn’t be vast amounts of repetitive plumbing code in J2EE applications.Better architectural choices and better frameworks can virtually eliminate such code,meaning that nearly all application code can be hand-authored.(注:framework形成的时机之一。)I’m not saying that code generation is a bad technology in general—merely that,when properly designed and built on appropriate frameworks, most J2EE applications should not contain enough boilerplate code to justify it and outweigh its negatives.
4.关于代码生成以及MDA作者的观点:The natural path of our industry is toward higher levels of abstraction. Perhaps one day MDA-powered code generation will prove to be an appropriate abstraction. However, I feel that this is 10–15 years away, if it ever happens.
5.Better Solutions for Higher Productivity:
Architecture
Avoid unnecessary architectural complexity.
Avoid unnecessary use of EJB.
Use abstraction layers to hide the complexity of core J2EE and J2SE APIs.
If possible, use an O/R mapping product to simplify the persistence layer.
Use a good application framework.

Focus and methodology
Focus! Know what problems you should be solving, and concentrate on them.
Use a reference architecture and start from a template application.
Use an agile development process.

Use appropriate tools.
6.Different developers do the same thing in different ways, wasting
valuable development time and complicating maintenance.程序设计始终要做的就是不发生这样的事情。
7.Know What Problems to Solve 生产率即是知道要解决得是什么问题,将主要是domain problems而不是generic problems.
8.Use Reference Architectures and Templates一旦选择了技术,将着手reference architecture.begin work using a skeleton application that establishes the overall plumbing.
9.And remember that the more upfront effort before arriving at a working prototype, the greater the risk of inadequate performance or an unworkable architecture. 项目组也应该精化,微型化。
10.J2EE developers are fortunate in that all these requirements can be met by free, open source tools, such as Eclipse, JUnit, Ant, a good Eclipse XML plugin, CVS, and the standard Eclipse JUnit and CVS integration.

OO
1.本身OO是一种范式,是一个模型,在SICP中对于讲到代换模型的理论:In general, when modeling phenomena in science and engineering, we begin with simplified, incomplete models. As we examine things in greater detail, these simple models become inadequate and must be replaced by more refined models.关于OO的讨论算是一个检查考虑问题的讨论。
2.作者提出的实践中运用oo的四个方面:封装domains concepts;运用polymorphism将共性和差异分离;代码复用;extensibility.
3.j2ee应用的对象常常都是一些fake objects,即是不具备objects的某些特征:identity,state,behavior.
4.oo针对接口编程的优点和误区。

The importance of business requirements
1.这个问题因不同的角色而已。就我而言,如同我一样的普通程序员,对于generic technical problems常常都是难题,故而在这方面的需要长足的学习和提高的;对于我们而言,我们domain problems就是如何具备了generic technical方面的强大能力只是第一步。
The Importance of an Empirical Process
1.Always develop a vertical slice to validate your application’s architecture early in the project. Don’t trust our advice or anyone else’s without establishing that it’s appropriate to your needs.验证自己的想法。

Java对象之JavaBean

使用javabean已经很久了,但是很少去研究和使用jdk中的java.beans包和java.beans.beancontext包。
时间和空间这个计算机的永恒话题,也一直是设计的折衷话题。记得刚开始写javabean的时候,对象的set get都是一行一行代码的手写。一次几十个方法下来,而且复制粘贴,复杂,维护修改都很费力。
现在apache jakarta commons的子项目已经有一些解决方案了,主要在包org.apache.commons.beanutils中,使用可以参见Test Case和《Jakarta Commons Cookbook》。当然,有时候也需要我们自己根据自己的应用编写自己的处理javabean的代码。今天正好看到了一些java.beans的代码,罗列如下:
java.beans.Introspector
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))) {
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
java.beans.PropertyDescriptor
public PropertyDescriptor(String propertyName, Class beanClass) throws IntrospectionException {
if (propertyName == null || propertyName.length() == 0) {
throw new IntrospectionException(“bad property name”);
}
setName(propertyName);
String base = capitalize(propertyName);

// Since there can be multiple setter methods but only one getter
// method, find the getter method first so that you know what the
// property type is. For booleans, there can be “is” and “get”
// methods. If an “is” method exists, this is the official
// reader method so look for this one first.
try {
readMethod = Introspector.findMethod(beanClass, “is” + base, 0);
} catch (Exception getterExc) {
// no “is” method, so look for a “get” method.
readMethod = Introspector.findMethod(beanClass, “get” + base, 0);
}
Class params[] = { readMethod.getReturnType() };
writeMethod = Introspector.findMethod(beanClass, “set” + base, 1, params);
propertyType = findPropertyType(readMethod, writeMethod);
}
(注:代码格式为eclipse默认设置)
我没有读过javabean的规范,今天针对javabean的使用和操作随处可见,也算是Rod Johnson所说的fake object了。如果javabean的property命名不符合规范,就有可能出错,一旦这种错误被framework捕获了还没有throw给应用,那么发现这种命名错误就更困难了。

如今我会优先选择commons-beanutils和jdk的java.beans对java bean进行操作。

拓展训练

周末参加了一个公司的导师拓展训练。
地点:沈阳棋盘上附近一个基地。
感受几点:
1.个人能力是有限的,团队和自己的能力的发挥。
2.在我们面对或者挑战平日里看来可怕的或者根本不可能去做的事情,在环境被逼的去做,做完了反而觉得十分有刺激和具有挑战性。人是应该富于挑战的,包括不断的自我挑战。
3.一旦目标确定,一个team同心协力的去做一件非常是有挑战性的事情的时候,所有的人都愿意同心协力的去创造一个个奇迹。
4.人人都有很强的荣誉感,在面对荣誉的时候,如何抉择取舍。team与team之间的良性对比是十分必要的,也总是伴随着恶性事件的到来。:)
这是一张图片

读设计模式精解

读<<设计模式精解>>第一章笔记。

功能分解:
分析即是分解,分析的过程既是分解的过程。最常用的方式就是功能分解,功能分解仅是分析的一种方法。针对需求,功能分解难以为我们提供面向未来应对变化的策略。而需求中不变的就是变化(需求变化的来源大抵有三种:1。新的功能需求;2。开发者对于问题领域的理解发生了变化,通过开发来提高问题领域的自动化程度;3。开发环境的变迁。),需求中的变化总是对于已经分解好的功能结构产生致命的冲击。仅仅将注意力集中在功能上是不够的,必须对数据结构和过程进行抽象、封装等,促使已有的实现能灵活应对需求的变化。
模块化:
通常我们还会选择模块化来进一步进行设计,其精髓就是高内聚低耦合。模块化能让我们写出更容易理解、更容易维护的代码。但是模块没有完全提出代码实现的抽象和封装,没有进一步提供粒度较小的抽象、封装和复用,可能一个过程或者数据结构的变动,确对一些地方的代码造成了意料之外的影响。
结论:
仅仅能实现当前需求的代码远远是不够的,而且仅仅使用功能分解然后实现之的分析设计思路也是糟糕的,因为需求总是在变化。我们必须从这里走得更远,作者就引入乐面对对象范式。
OOP在由抽象、封装、模块化、分层组成的对象模型之概念框架下,在语言级粒度上提供了封装、继承、多态的支持;这是人类复用技术的进步,但是使用了oop并不代表就能完全运用了对象模型的核心思想。(TDD是当前应对代码变化的最好的开发方式。需求变化的最大承受者就是代码,富于变化和善于应对变化的代码才能存活下来。)

读《Berkeley Unix二十年》

16 May 2005
在unix的早期历史里面,没有策划,没有估计,没有进度表;在这个年代,硬件的代价是昂贵的,在硬件资源固定的情况下,所有的人都希望通过自己的努力进行优化,进行维护,进行调试,进行移植,进行集成。。。这时构建系统、发布系统还处于萌芽状态,大量的工作都是针对与操作系统的。(同也是编程语言狂热的年代。)这完全是个人表现,人类对于计算机一个个基本的需求解决的年代。理想也是满足自己的开发所需和硬件的平滑更换。经过暴风骤雨的成长发展,系统进入了分支期,这样路就越来越窄了,可以选择的空间似乎总是在缩小。NetBSD专注于支持多平台,FreeBSD专注于支持PC体系,OpenBSD专注于系统的安全性。
人才的流动,人才的流失对于一个team来说是一个损失,同时team有引进了新的人才。对于整个行业来说开始平衡的,人才的流动带给一个行业的是经验的互补,每一个人都各有所长。关键人才的流动带给系统的是新的特性切入点,同类型的系统也越来越有竞争力,火拼最激烈的时候正是新的力量可能诞生的时候。BSD的发展就是DARPA(Defense Advanced Research Projects Agency)给了它这个绝佳的机会。Bill Joy、Bob Fabry、Leffler…的离开,Leffler、Pauline Schwartz、Domenico Ferrari、Susan Graham、
Mike Karels…的介入。
早期的Unix开发者都是小范围的孤军奋战,而且也总是在增大交流的范畴,交流越广泛,对于系统的提高所起到的隐含动力越大。在系统的开发前行中,越来越多的贡献者希望代码的共享,常常会触及到版权的问题,这种共享缩短了个人和行业的发展历程。今天OpenSource已经深入到我们这些开发者的心灵之中,感谢这些先行者和贡献者。同样感受到,官事没有什么可怕的,足以证明这个系统、这个行业非常成熟了,有了越来越多的共利益者了,分蛋糕的人拼的热火朝天呢,大家在同一个级别上一较高下了。

转载:你注意过你的父母吗....

你注意过你的父母吗?(写给 30岁以上的人,让30岁以下的人思考)

如果有一天,你发现妈妈的厨房不再像以前那么干净
如果有一天,你发现家中的碗筷好像没洗干净
如果有一天,你发现母亲的锅子不再雪亮
如果有一天,你发现父亲的花草树木已渐荒废
如果有一天,你发现家中的地板衣柜经常沾满灰尘
如果有一天,你发现母亲煮的菜太咸太难吃
如果有一天,你发现父母经常忘记关瓦斯

如果有一天,你发现老父老母的一些习惯不再是习惯时, 就像他们不再想要天天洗澡时
如果有一天,你发现父母不再爱吃青脆的蔬果
如果有一天,你发现父母爱吃煮得烂烂的菜
如果有一天,你发现父母喜欢吃稀饭
如果有一天,你发现他们过马路行动反应都慢了
如果有一天,你发现在吃饭时间他们老是咳个不停 千万别误以为他们感冒或着凉,
(那是吞咽神经老化的现象)
如果有一天,你发觉他们不再爱出门…

如果有这么一天 我要告诉你,你要警觉父母真的已经老了
器官已经退化到需要别人照料了
如果你不能照料,
请你替他们找人照料
并请你请你千万千万要常常探望
不要让他们觉得被遗弃了

每个人都会老
父母比我们先老
我们要用角色互换的心情去照料他
才会有耐心、才不会有怨言
当父母不能料理自己的时候,
为人子女要警觉,
他们可能会大小便失禁、可能会很多事都做不好,
如果房间有异味,可能他们自己也闻不到,请不要嫌他脏或嫌他臭,
为人子女的只能帮他清理,并请维持他们的’自尊心’。

当他们不再爱洗澡时,
请抽空定期帮他们洗身体,
因为纵使他们自己洗也可能洗不干净。
当我们在享受食物的时候,
请替他们准备一份大小适当、容易咀嚼的一小碗,
因为他们不爱吃可能是牙齿咬不动了。
从我们出生开始,喂奶换尿布、生病的不眠不休照料、
教我们生活基本能力、供给读书、吃喝玩乐和补习,
关心和行动永远都不停歇。

如果有一天,
他们真的动不了了,角色互换不也是应该的吗?
为人子女者要切记,看父母就是看自己的未来,孝顺要及时。
如果有一天,
你像他们一样老时,你希望怎么过?
现在的你,
是在当单身寄生虫、还是已婚双料或多料寄生虫?
你留意过自己的父母吗 ?

JUnit实战

来自http://junit.sourceforge.net/doc/cookstour/Image6.gif

1.在这个composite模式之中,TestSuite与它的接口Test的聚合关系。这种关系完美的满足了客户代码自由自在的组装自己的测试用例结构。称为面对对象的递归组合。现在TestCase和TestSuite都具有良好的扩充性。
2.TestResult:如何进行职责的分配永远是对象的话题。TestCase直接面对符合测试框架规范的测试用例的每一个方法,每一个方法都会致使一个TestCase的对象构造出来,这样测试用例的方法之间就很好的隔离;每一个TestCase都是一个独立的测试单元,TestCase正是保证这种自主性。测试用例运行中的信息收集和信息积累。用例和信息积累都是潜在可能各自发生变化的,区别用例的执行和信息的收集就可以得到更多的灵活性和潜在复用性。用例和信息积累各自都又具有很好的通用性。TestResult正是测试执行信息积累而被封装的类(Test提供了信息积累的收集点:countTestCases),可以看到TestResult是作为访问者(Visitor)注册到Test中去的。对于测试执行信息的处理,向TestResult注册了estListener的Observer模式。
3.在TestResult通过接口Protectable将执行信息的处理优美的隔离到一个单独的方法中来:
public interface Protectable {

/**

  • Run the the following method protected.
    */
    public abstract void protect() throws Throwable;
    }

在TestResult中:
/**

  • Runs a TestCase.
    */
    protected void run(final TestCase test) {
    startTest(test);
    Protectable p= new Protectable() {
    public void protect() throws Throwable {
    test.runBare();
    }
    };
    runProtected(test, p);

    endTest(test);
    }

    /**

  • Runs a TestCase.
    */
    public void runProtected(final Test test, Protectable p) {
    try {
    p.protect();
    }
    catch (AssertionFailedError e) {
    addFailure(test, e);
    }
    catch (ThreadDeath e) { // don’t catch ThreadDeath by accident
    throw e;
    }
    catch (Throwable e) {
    addError(test, e);
    }
    }
    整个JUnit框架是功能完美而且精巧的。其中的核心代码也不过千余行而已,处处都能感觉到灵活和可扩充。

黄花菜

学名:Hemerocallis citrina Baroni
英文名:Citron Daylily
科名:百合科 Liliaceae
根常稍肥厚或末端膨大。基生叶深绿色,宽线形,通常宽l-2厘米或更宽,

较花茎短。花茎高1—2米;螺壳状聚伞花序排成圆锥状,花朵达几十朵,花午

后开放,次日午前凋萎,黄色,芳香,长8—16厘米;花被管长3—5厘米,外轮

裂片倒被针形,内轮长椭圆形。蒴果椭圆形,长约2.5厘米。花期8—10月。

产本省各地,野生山坡、山谷草丛中,也有栽培;分布我国秦岭以南各省

区,北方也有栽培。

花供食用;根有毒性,可作杀虫剂。

2004年年底总结

今年年末,回首过去,心里七上八下的。

首先感觉时间过的真快,不知道何以人生走完了2004年。一如既往的迷茫。

自从上了小学,就上了中学,接着是高中,然后是大学。在这一路上纵然是多姿多彩的。每一关口都不需
要我多少思虑抉择,好像人生的路就那么一条。大学毕业了,接着就是工作了,如今已经工作了一年半了。
这一切似乎自然而然的事情,不见我之力我之思改变了自己多少。当我们回首,又有多少刻骨铭心呢?心
情激动的时候我可以一件一件的数来,或许另外一个时刻我又去数落其他的事情。

随着10月份以来,烦躁的心绪越来越频繁,足以说明我无法很好的调节自己的心里。看来10月份是一年心
情的转折点,至少以后在9,10月份好好的轻松一下,疏解一下一年中的心情。
越来越发现自己的缺点太多太多了,就好像过程改进一样,在年末看到自己缩影的一部分。如果有人愿意
给我一些建议,简直是太好了。

在过去的学习中,很少做笔记,又少于记录心得。致使只见表皮,不见精髓的惯病。

缺乏与人交流,+深层次的交流。

接受新的思想比较少,吸收东西的能力亟需提高。

缺乏和人合作,现在不晓得如何和人合作。

知识支离破碎,没有形成自己的思维体系。

对软件开发本身认识甚少。

全局观很是浅薄。

想读的书很多,每一天安排在读书上的时间很少。

想读还没有读的书:
《计算机程序的解释与构造》
《UML与模式应用》
《Contributing to Eclipse》
《软件工艺》
《设计模式》
《测试驱动开发——实用指南》

“你必须习惯于一天用六个小时读代码,再用一个小时写代码--你会发现这样的一天效率同样高得惊人。”
——《Contributing to Eclipse》前言
“读书不二。一书未完,不看他书。东翻西阅,徒务外为人。”
“总要养得有胸次博大活泼,此后更当有长进也。”
——曾国藩
知难行更难。

EMF Build 之版本分类(EMF Build Type)

1.Releases
Releases是由开发团队公开发布的主要build版本,比如:”R1.0”。
这种builds是稳定的(stable)、经过测试的版本(tested release),但是它不会包含最近最
新的features和improvements。
Release Builds的版本号总是以”R”开头;Non-release builds一般都是build的日期来命名。
2.Stable Builds
Stable builds是能够确定满足大部分用户的integration builds版本(注:Stable builds首先是一个
integration builds,并有很好的稳定性,满足用户的基本需求)。经过短期的使用和评估(或者评审)
由architecture team把stable build从integration build中提取出来(原文:They are promoted from
integration build to stable build by the architecture team after they have been used for a
few days and deemed reasonably stable. )。
这种builds会紧紧跟随最新的开发进程,包含最新最新的features和bug fixes,当然同时可能会由许多
bug和缺陷。
开发团队希望能够发布这种builds来获取用户及时有价值的反馈。
3.Integration Builds
这是一个周期性的工作,各个component teams保证释放的component都处在了稳定、具有兼容性的状态。
每一个compenent必须在配置文件中配置下一次integration build中本component的版本号。在新的稳定
component版本release到build中,必须要进行build integration builds.Integration builds经过测试
之后就会成为Stable Builds.
4.Nightly Builds
over night build任何被release到the HEAD stream of the CVS repository的代码。
完全没有经过测试,存在大量的问题;一般情况下都不会很好的运行。
这一步为改项目的开发者而是实现的。
Note: Nightly builds are produced only as requested, and not necessarily every night,
by developers to build what was in HEAD.
5.Maintenance Builds
周期性的build,为了保持维护未来版本的发布的执行。Maintenance Builds并不一定是一个stable builds.
maintenance builds最后确定和release的时候,就成为了一个Release build.Maintenance builds的名字以
“M”开头,在稳定性方面仍然没有经过考验。如果一个版本是release candidate的时候(“RC”),那么
就是一个stable maintenance build.