忘记Scala,Qi4J是下一个 Java?

这段时间,围绕Evans DDD的DSL实现是一个大热门,有的从语言角度重新定义,比如Scala vs. Clojure
虽然Scala很象Java,但是语法比Java要复杂多,My experience with Scala (so far)认为,Scala功能要比Java强大,但是学习曲线不低。

Bruce Eckel这位编写"Java编程思想"一举成名的所谓大师,写了一篇Java: Evolutionary Dead End,认为Java是进化的死胡同,其实我个人对其书籍本身就有些反感,他并没有在书中写出Java的真正编程思想,是C语言思想的借尸还魂罢了,所以他的思维是有缺陷的,所以他写些大而化之的文章只是糊弄一下初学者罢了。

我一直认为,Java其实是很好理解易懂的语言,那么多人熟悉Java,而C不过是第二个Java,这么多人学会一种语言,难道它就不是世界语吗?就象英语因为讲得人多了,所以就成世界语,成为大家交流工具了,语言不过是交流工具,在语言和MF提倡的领域模型的“语法”之间不一定要划等号。

所以,基于Java的框架也实现解决DSL和面向语言编程模型的问题,果然,针对这位大师的忽悠,基于Java的原汁原味的Qi4J框架横空出世了,Qi4J the next Java? Forget Scala


Qi4j有下面几个特点:
1.Behavior depends on Context 依赖场景的行为
2.Decoupling is a virtue 解耦融入血液。
3.Business Rules matters more.业务规则更重要
4.Classes are dead, long live interfaces.类已经死亡,接口万岁。

依赖场景的行为
对象的生命周期相对简单的领域模型已经OO要比我们想象得复杂多,例如:
1.一个鸡蛋变成鸡,从而成为食物。
2.我是在工作的程序员,一个父亲+丈夫在家里,一宗交通意外,猎人在丛林中的受害者祈祷。
不仅如此,对象在不同时期的组合composition 变化更大,我们要持续不断面对变化,这些变化往往来自于业务领域,OOP把这些变化容易搞大,大得经常销毁大块模型甚至返工。小题大做的意思?

类的属性经常会增加变化,如果属性拓展变化得已经面目全非,不是原来的类了,那么我们是不是要给这个类改名呢?不改名,因为不是原来的类,改了,就导致很多依赖它的其他类变化太大,导致这个模块的模型都要返工重新设计。

Qi4j认为当前所谓OOP其实一点不是OOP,实际是面向类编程,不是真正面向对象编程,类是第一等公民,对象是从类中衍生出来的;而在Qi4j宣称的面向组合编程Composite Oriented Programming模式中,对象才是真正第一等公民,对象创建一个或多个类。很有魄力的见解。

解耦融入血液
在OOP以类为第一公民的世界中,类之间引用造成了耦合,紧耦合是重用的死敌,而Qi4j的面向组合编程模式最大目标就是重用,所以,传统的OOP并不能真正实现重用,虽然我们有各种消除依赖的模式。Qi4j采取的是将类在细分,划分为更细的碎片,分为下面几个部分:
1.Mixins: 代表状态 如Name, Person, Adress 值对象的意思?
2.Concerns: 无态功能,如事务安全e.g. TransactionWrapper, Security AOP的细化
3.Constraints: 约束,参数检查等Checking parameters, e.g. NotNullConstraint
4.SideEffects:专门管理边界影响 Managing side effects, e.g. sending Mail

下面是一个基于Qi4j框架的接口:


@Concerns({Security.class, Transaction.class})
@SideEffect({MailNotification.class})
public interface PersonComposite
extends Person, Name, Adress, Composite
{
}

Business Rules matters more
很多聪明的程序员总是认为架构中底层的框架比简单的领域模型更加重要,比如OSGI可能就是一个比较底层的框架,很多人热捧它,但是它如果脱离简化领域模型就没有意义,

领域模型是反映需求业务,是能够收到客户的钞票的,底层设施只是为这种目的实现的工具,别本末倒置了。如果我们更多程序员关注业务逻辑和领域模型,而不是关心事务 安全或框架的特点,软件生产力将得到真正加强。

Evans DDD一书写得很好,但是真正实现起来比较困难,因为缺乏一个语法环境,而Qi4j正是提供这样一个语法环境,什么时候DDD起飞了,也是Qi4j起飞之日。If DDD takes off, Qi4J or frameworks like Qi4J will take off too.

顺便罗嗦一句,本人当初推出开源Jdon框架其实也是为这个目标努力奋斗,只是徒有想法和构思,仍在不断发展中,和Qi4J相比还是有相当距离,不过看到距离就有努力方向了。

Qi4j项目


[该贴被admin于2010-03-15 15:56修改过]

>>在Qi4j宣称的面向组合编程Composite Oriented Programming模式中,对象才是真正第一等公民,对象创建一个或多个类。很有魄力的见解。

面向组合编程很不错。DDD中的聚合,实体,值对象,约束,边界划分如果能在语言级别得到支持,那样就更爽了。

>>领域模型是反映需求业务,是能够收到客户的钞票的,底层设施只是为这种目的实现的工具,别本末倒置了。如果我们更多程序员关注业务逻辑和领域模型,而不是关心事务 安全或框架的特点,软件生产力将得到真正加强。

Evans DDD一书写得很好,但是真正实现起来比较困难,因为缺乏一个语法环境,而Qi4j正是提供这样一个语法环境,什么时候DDD起飞了,也是Qi4j起飞之日。If DDD takes off, Qi4J or frameworks like Qi4J will take off too.

呵呵,jdon的大力宣传使得更多的国人关注DDD,从我这次买书看出来了,现在想买本中译本的“领域驱动设计”比登天还难呵呵。帖子:
求购领域驱动设计一书
[该贴被admin于2009-09-20 13:42修改过]

对于类似技术,我更多感兴趣的东西往往集中在
其是不是有大型成功案例
是否可生产化
IDE,插件,工具支持受否完备
应用服务器是否支持
等等问题,而不再是思想有多好,多么简化开发的理论

>类已经死亡,接口万岁
Qi4j不只是一个框架,其实为我们指出现实中OO的误区。

我曾经重构一个大型的BOSS,该BOSS使用Hibernate,屏蔽了数据库影响,基本都是使用面向对象设计,但是由于大量使用继承,导致耦合粒度太粗,结构混乱,这是OO之错?还是误用OO之错呢?

所以,在现实中,特别是领域建模时,使用继承会非常容易,可以说是直觉,但是使用接口才是设计,接口粒度要更细,至少有将行为和抽象分离的用处。

如果框架提供这种行为和抽象的分离约束就非常好,但是又会导致贫血模型,所以,现实中设计就是在博弈:最大限度用接口,然后将接口嵌入模型中(这个模型就是Qi4j所说的组合模型了,因为它是拆了组合得出来的,就象1+1=2的组合结果2一样)。


[该贴被banq于2009-09-22 07:08修改过]

为了生计之余,偶觉得兴趣也是关键.: D
Qi4j思想不错。真正应用可能还需要些时日。
[该贴被xinying_ge于2009-09-22 07:10修改过]

>Qi4j思想不错。真正应用可能还需要些时日
不能再等待了,因为Java语言以前在OO上的误导,已经很多人喊,Java死了:
21日昨天这篇文章Is Java dead?列举了Java作为语言为什么必须死亡的原因:
1.继承Inheritance: 继承是最不灵活的,导致紧耦合,组合(Qi4j的组合编程方式)是最好的选择。outside of frameworks, inheritance is inflexible, leads to tight coupling and is plain bad. Composition is most often a better choice. As are mixins and traits

2.语法噪音Noisy syntax: Lately there has been the enlightenment that too much noise in a language is a bad thing. Java is especially noisy in closures (anonymous inner classes) and generics.Java特别在内部类 泛型等方面都是噪音,我深有同感,一直在骂内部类和泛型。

3.Null / NPE: 空指针报错,这是Java初学者面临的最头疼问题。不过好像在Java 7中得到弥补了。

4.设计模式Design patterns: Many design patterns are a good thing, but some of them are just covering inefficiencies in an only-OO language like Java,很多设计模式是好的,但是有些设计模式在掩盖Java方面的不足,我认为DTO模式以及Facade模式都是这种类型,还有专门的J2EE模式,简直就是欲盖弥彰,哪有具体平台的模式,只能说明你这个技术有缺陷,不能随便玩,得按你的操作指南去玩,最后用户被平台技术绑定,而不能被领域模型主导。

5. List processing,很多应用基本都是集合的遍历 传递和更新,Java应该有更简单得象Google Collections那样的简化操作。

Java可能在2009年灭亡?Qi4j也许说了不。

别老这么吵新东西,细想是空洞的,等这qi4j开始有人使用,使用的多了,他又会成为第二个“java”。
下面是一个基于Qi4j框架的接口:

@Concerns({Security.class, Transaction.class})
@SideEffect({MailNotification.class})
public interface PersonComposite
extends Person, Name, Adress, Composite
{
}

如果如文章所说的那样,用现在的Java做细粒度的设计就是了,新瓶装老酒,不还是原来的酒,说来说去还是空洞的细想。。。

别老这么吵新东西,思想是空洞的,等这qi4j开始有人使用,使用的人多了,他又会成为第二个“java”,又会有人说qi4j将死。。。。。
下面是一个基于Qi4j框架的接口:

@Concerns({Security.class, Transaction.class})
@SideEffect({MailNotification.class})
public interface PersonComposite
extends Person, Name, Adress, Composite
{
}

如果如文章所说的那样,用现在的Java做细粒度的设计就是了,新瓶装老酒,不还是原来的酒,说来说去还是空洞的思想。。。
[该贴被meibin于2009-09-24 09:44修改过]

个人今天刚开始看QI4J,我理解的面向组合是这样的:
以往OOP开发的时候,一个现实世界的事物在不同环境下有可能扮演多个角色,那么设计上有可能针对同一个事物,需要多个对象来实现。实际从这个角度讲,就是一种矛盾,称为OOP,其实不是完全针对对象编程。从这一点上讲,现实世界的事物只有一个,而在软件中的实现却是多个。产生了这样的问题。所以把一个真正意义的对象给扭曲了。但是没办法,这个是OOP的设计思想决定的。个人认为对象的存在依赖于他的生存环境,所以在特性生存环境有特定的行为,仅仅通过OOP的思想创建出来的内容与面向对象的设计思想有些地方是矛盾的。

而组合做的就是,将这个现实的事物的各个角色的行为细粒度划分,每一种角色的行为都对应一个接口。但是终归该事物在不同环境下都只有一个对象于之对应,只是在不同环境下,对象行为不同而已,而在真正环境下的判定,是交给QI4J这样的框架为我们完成,客户端的调用完全不用考虑获取的对象属于哪个角色的问题。不知道这样理解是否正确,请指教!
[该贴被lovejdon于2009-09-24 09:59修改过]

楼上理解非常到位,看来不在实践中遇到这种困惑是无法有这种透彻理解的。

总体思路就是:设计粒度分得很细,使用时,通过框架组合起来方便使用。是一个划分再组合,打破再包装的过程。

那是不是也可以这么说,面向组合的的这种开发方式是更接近于DDD的一种方式,而我们目前应用的OOP思想在某中程度上是比COP更低级的设计思想。也就是COP作为了更抽象的设计思想而存在了。

>面向组合的的这种开发方式是更接近于DDD的一种方式
同意,cop或说真正的OOP能够让领域模型寿命更久,更可重用性,这是领域驱动设计根本逻辑所在,想想看,如果领域模型三天两头的变,模型一变,全局皆变,这哪里有稳定性 健壮性呢?

所以DDD虽然是构件一种领域模型的思想,但是应用在OOP上还是无从保证上面说一个事物多个角色的情况,还是套在OOP上比较死板,那COP确实也应对了领域的这一点,真正是接口万岁(抽象),领域稳定了!

呵呵,能重用就一定正确了吗
真正的趋势是可修改
试问自己写的业务逻辑有多少可以重用的
不要跟着大师们瞎忽悠重用的价值
我觉得设计讲究在快速原型基础上的可重构,可维护,可修改
重用只是缓兵之计,并不是本质
[该贴被quarph于2009-09-25 14:52修改过]

可重用境界要高于可重构 可修改,如果可重用目标达到了,可修改目标也达到了,但是可修改不一定可重用。

我今天对组合Composer有更深入的认识,组合和封装是有区别的,组合是将碎片再封装起来,但是这个封装是弱封装,是透明的封装,不是普通意义上完全封闭的封装,不是强封装。

以后封装这个词语由于含义不清,模棱两可,建议从OO术语中去除,改用组合替代,组合这个词就含有细分后在合的意思,包含进去再出来的概念,很精确。

面向组合架构是一种真正精确的可重用 可维护 可拓展的架构。

类可以组合,那么多个类可以组合成模块化,这就是好的模块化设计,看来OSGI也属于一种组合的模块化,不过是一种运行时刻的组合,也就是对象的组合,它的潜在前提逻辑还是遵循类生成对象这个思路,因此,我们更需要一种在设计编码阶段的面向组合设计(AOP的MIXIN要比OSGI更进步)。当然了,OSGI比JavaEE标准的模块化要进步,EJB或Web的Jar或War的内部是死死的封装了。

[该贴被banq于2009-09-27 08:38修改过]