任何使用Qi4J的人

时间:2010-02-04 00:45:48

标签: java dependency-injection apache-zest cop

我之前正在阅读InfoQ关于面向复合编程的文章:

http://www.infoq.com/articles/Composite-Programming-Qi4j

我有兴趣了解是否有人正在使用(或已经使用过)Qi4j框架?

与使用传统的依赖注入框架(如Spring)将类连接在一起相比如何?从维护的角度来看,生成的对象图(基于mixins而不是类)更容易处理吗?

6 个答案:

答案 0 :(得分:9)

好吧,我在一个项目中已经使用Qi4j大约一年了。一旦你习惯了域模型中mixins的强大功能,你就会想知道以前如何在没有它们的情况下进行管理。事实上,我认为创建域模型的POJO方法应该是过时的。它创建了系统不可维护的代码。因为mixin / composite模型是Qi4j的重要特性,而不是DI,所以在Java平台上确实没有任何比较。

至于Bozho的担忧:当谈到宣布mixins时,有两个不同的案例。在实体(即域模型)中,接口通常只有一个实现,并且您实际上希望主动避免出于维护和可读性原因而进行多次实现。所以我在界面中直接声明了实现。但是,它只是一个默认值,如果你愿意,它可以被复合覆盖。到目前为止,我从未发现需要这样做。

另一种情况是服务,这是完全不同的。对于许多情况,将只有一个实现,因此声明接口中的实现再次非常好。但是,对于需要不同实现的服务的情况要多得多,因此对于这些情况,您只需在具体的复合类型声明中声明mixin。所以这两种风格都是可能的,并且出于各种原因推荐。

至于铸造,能够铸造物体是一个奖励,而不是问题。如果你没有从一个角色转换到其他角色,那么你必须具有很强的创造力来解决它,这可能不会使你的代码变得更简单。

答案 1 :(得分:3)

Kabram;已经多次尝试与JPA集成。如果我们有两种重叠但不完全可比的技术,那么最终只会有各种可能性。因此,将Qi4j与JPA集成有两种基本方法。

  1. 限制JPA选项,以便可以充分利用Qi4j所需的更灵活的数据结构。这样做毫无意义,因为直接使用SQL会更加高效,这就是我们选择的。

  2. 限制Qi4j的数据模型以适应现有的JPA数据模型。这样做会消除人们为什么首先选择Qi4j的大部分优势。因此我们决定不花费周期来做这件事。但是,我认为Qi4j的可扩展性足以在不运行Core Runtime的情况下进行此类集成,只需创建一个EntityStore。

答案 2 :(得分:2)

希望在这次讨论中不要太晚: 但这就是我的看法。

首先,我喜欢Qi4j背后的想法(复合材料,混合材料,装配体),但我对使用它的复杂性感到畏惧。

那里的概念应该是更广泛的一部分,比如语言(如Java)而不是框架,应该更容易使用。

我在2年前遇到了一个问题,这让我希望自己有这样的东西。

我想要3种不同的行为可以在一组bean上重用。有些豆子使用了所有其他豆子的任意组合。我不想把它们全部放在一起,因为它没有意义。另一方面,我受到了无法进行多重继承的限制。显而易见的解决方案:使用界面;这意味着多次实施的东西。 我记得向同事抱怨我希望我有办法为界面提供默认实现。这对我来说是一个简单的OO概念,允许人们以更清洁的方式重用行为。如果您需要与默认实现不同的东西而不是实现那个。这会更有意义,也不会制止我能看到的任何自然法则。

所以为了回答你的问题,我认为这个Qi4j的概念允许你以更清洁的方式思考OO,其中Spring更具结构性,甚至在概念上也不具备可比性。你可能会想到依赖注射而不是思考春天,而是想着Qi4j而不是思考dept注射。

答案 3 :(得分:1)

在阅读链接文章的第一部分后,我不喜欢两件事:

  • 实现是在接口中定义的(使用@Mixins) - 如果应该模拟这些实现,或者实现更改会怎么样?
  • 需要施法

没有Qi4J的经验,我不能说实践中结果如何,但感觉并不好。

答案 4 :(得分:1)

当我在2分钟,10分钟等教程中阅读Qi4j时(最后一个是不完整的),我想到的一个显而易见的问题是如何将其与JPA / Hibernate管理实体集成?我希望看到一个与JPA无缝集成的解决方案。在我看来,没有JPA意味着没有采用Qi4j。我很想看到作者的一篇文章,它展示了与JPA和Spring的集成,这两件事在Java Enterprise世界中有着深刻的渗透。如果整合很简单,那么将会迅速采用。

答案 5 :(得分:1)

Bozho;关于在接口上声明Mixins的问题,

可以在“更高”(即子)接口中覆盖Mixin实现,因为实现的搜索顺序“按每个方法”发生,并从声明的接口,从左到右,然后到每个超级接口(在extends子句中从左到右)。或者,您可以在复合的装配中覆盖;

public void assemble( ModuleAssembly module )
{
    module.entities( Account.class ).withMixins( LdapAuthenticatorMixin.class );
    :
}

其中LdapAuthenticatorMixin可能是抽象的,只覆盖单个方法。