任何使用 Qi4J 的人
我之前读过一篇关于面向组合编程的 InfoQ 文章:
http://www.infoq .com/articles/Composite-Programming-Qi4j
我有兴趣了解是否有人当前正在使用(或已经使用)Qi4j 框架到底是什么?
它与使用传统的依赖注入框架(例如 Spring)将类连接在一起有何不同?从维护的角度来看,生成的对象图(基于 mixins 而不是类)是否更容易处理?
I was reading an InfoQ article on Composite Oriented Programming earlier on:
http://www.infoq.com/articles/Composite-Programming-Qi4j
I was interested in finding out whether anybody is currently using (or has used) the Qi4j framework at all?
How does it compares to using a traditional dependency injection framework such as Spring for wiring classes together. Is the resulting object graph (based on mixins rather than classes) easier to deal with from a maintenance point of view?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
嗯,我自己在一个项目中使用 Qi4j 已经大约一年了。一旦您习惯了域模型中 mixins 的强大功能,您就会想知道以前没有它们时是如何管理的。事实上,我认为创建领域模型的 POJO 方法应该已经过时了。它创建了系统上无法维护的代码。因为 mixin/composite 模型是 Qi4j 的重要特性,而不是 DI,所以在 Java 平台上确实没有任何比较。
至于 Bozho 的担忧:当涉及到声明 mixin 时,有两种不同的情况。在实体(即域模型)中,接口通常只有一种实现,实际上,出于维护和可读性的原因,您可能希望主动避免使用多种实现。所以我直接在界面中声明实现。但是,这只是默认值,如果需要,可以由组合覆盖。到目前为止我还没有发现有必要这样做。
另一种情况是服务,这是完全不同的。对于许多情况,只有一种实现,因此在接口中声明实现也是完全可以的。但是,在更多的情况下,您需要不同的实现,因此对于这些情况,您只需在具体的复合类型声明中声明 mixin 即可。所以这两种风格都是可能的,并且出于各种原因推荐。
至于施法,能够施法是一种奖励,而不是问题。如果您没有从一个角色到其他角色的转换,您将必须非常有创意才能解决它,这可能不会使您的代码变得更简单。
Well, I've been using Qi4j myself for about a year now in a project. Once you get used to the power of mixins in your domain model, you'll be wondering how you ever managed without them before. In fact, I think the POJO method of creating domain models should be obsolete. It creates systemically unmaintainable code. Because the mixin/composite model is the important feature of Qi4j, rather than DI, there really isn't any comparison on the Java platform.
As for Bozho's concerns: when it comes to declaring mixins there are two separate cases. In entities, i.e. the domain model, an interface will typically only have one implementation, and you would in fact want to actively avoid having several implementations for maintenance and readibility reasons. So I declare the implementation straight in the interface. But, it is only a default, which can be overriden by the composite if you want to. I've so far never found a need to do so.
The other case is services, which is quite different. For many cases there will be only one implementation, and so declaring the implementation in the interface is again quite ok. But, there are far more cases with services that you want different implementations, and so for those cases you simply declare the mixin in the concrete composite type declaration instead. So both styles are possible, and recommended for various reasons.
As for casting, being able to cast an object is a bonus, not a problem. If you don't have casting from one role to other roles you're going to have to be quite inventive to get around it, which probably won't make your code simpler.
卡布拉姆;已多次尝试与 JPA 集成。如果我们有两种重叠但不完全兼容的技术,那么最终只能得到可能性的交集。因此,将 Qi4j 与 JPA 集成有两种基本方法。
限制JPA选项,以便充分利用Qi4j所需的更灵活的数据结构。这样做没有任何意义,因为直接使用 SQL 性能更高,这就是我们的选择。
限制 Qi4j 的数据模型以适应现有的 JPA 数据模型。这样做会剥夺人们最初选择 Qi4j 的大部分优势。因此,我们决定不花费周期来执行此操作。不过,我认为 Qi4j 的可扩展性足以完成此类集成,而无需侵入 Core Runtime,只需创建一个 EntityStore即可。
Kabram; Integration with JPA has been attempted more than once. If we have two overlapping but not fully compaible technologies, you will end up only with the intersection of possibilities. So, there are two basic approaches to integrate Qi4j with JPA.
To limit the JPA options, so that the much more flexible data structures that Qi4j needs can fully be used. Doing that makes no sense, as going directly to SQL is much more performant, and that is what we chose.
To limit Qi4j's data model to fit an existing JPA data model. Doing this will take away most of the advantages of why people choose Qi4j in the first place. We have therefor decided not to spend the cycles to do this. However, I think the extensibility of Qi4j is good enough to do such integration without hacking in the Core Runtime, and simply create an EntityStore.
希望这次讨论还不算太晚:
但这就是我的看法。
首先,我喜欢 Qi4j 背后的想法(复合、混合、组件),但由于使用它的复杂性而受阻。
其中的概念应该是更广泛的保护伞的一部分,例如语言(例如 Java)而不是框架,并且应该更易于使用。
两年前我遇到了一个问题,这让我希望当时能有类似的东西。
我想要 3 种不同的行为可以在一组 Bean 上重用。有些豆子使用了所有这些豆子,其他豆子则任意组合了两种豆子。我不想把他们全部放在一个班级里,因为这没有意义。另一方面,我受到无法多重继承这一事实的限制。显而易见的解决方案:使用接口;这意味着多次执行某件事。
我记得向一位同事抱怨我希望有一种方法为接口提供默认实现。对我来说,这是一个简单的面向对象概念,它允许人们以一种更清晰的方式重用行为。如果您需要与默认实现不同的东西,则需要实现该实现。这会更有意义,并且不会破坏我所看到的任何自然法则。
因此,为了回答你的问题,我认为 Qi4j 的概念允许你以更简洁的方式思考 OO,其中 Spring 更具结构性,甚至在概念上没有可比性。您可能会考虑依赖注入,而不是 spring 和 Qi4j,而不是部门注入。
Hopefully not too late on this discussion:
But this is how I see it.
First of all I like the ideas(Composites, Mixins, Assemblies) behind Qi4j but am held back by the complexity of using it.
The concepts there should be part of wider umbrella such as a language(such as Java) than a framework, and should be easier to use.
I ran into a problem 2 years ago that left me wishing I had something like that then.
I wanted 3 different behaviors that could be reused on a set of beans. Some beans used all of them others any combination of two. I did not want to put all of them together in a class because it did not make sense. On the other hand I was constrained by the fact that I could not have multiple inheritance. The obvious solution: use an interface; which means implement the thing that many times.
I remember complaining to a co-worker about the fact that I hope I had a way of providing a default implementation for an interface. This to me is a simple OO concept that allows one to reuse behaviors in a cleaner fashion. And if it is the case where you need something different than the default implementation than implement that one. That would make more sense and would not brake any natural law that I can see.
So to answer your question I think this Qi4j's concepts allow you to think OO in cleaner fashion, where Spring is more structural and not even comparable conceptually. You could be thinking dependency injection and not be thinking spring and be thinking Qi4j and not be thinking dept injection.
阅读链接文章的第一部分后,我不喜欢两件事:
由于没有 Qi4J 的经验,我不能说这在实践中结果如何,但感觉不太好。
After reading the first part of the linked article, I didn't like two things:
@Mixins
) - what if these should be mocked, or implementations changed?Having no experience with Qi4J, I can't say how this turns out in practice, but it doesn't feel good.
当我在 2 分钟、10 分钟等教程中阅读 Qi4j 教程(最后一个教程不完整)时,我想到的一个明显问题是如何将其与 JPA/Hibernate 托管实体集成?我希望看到一个与 JPA 无缝集成的解决方案。在我看来,没有 JPA 就意味着没有采用 Qi4j。我很想看到作者写的一篇文章,其中展示了与 JPA 和 Spring 的集成,这两个东西在 Java 企业世界中有着深入的渗透。如果集成很简单,那么就会得到快速采用。
When I read through the Qi4j in 2 minutes, 10 minutes etc. tutorials (the last one is incomplete), the one obvious question that came to mind was how do I integrate this with JPA/Hibernate managed entities? I would like to see a solution that seamlessly integrates with JPA. No JPA implies no Qi4j adoption in my opinion. I'd love to see an article by the author(s) that shows integration with JPA and Spring, two things that have deep penetration in the Java Enterprise world. If the integration is straightforward, rapid adoption will follow.
博若;对于您关于在接口上声明 Mixin 的问题,
Mixin 实现可以在“更高”(即子)接口中被覆盖,因为实现的查找顺序“每个方法”发生,并且从声明的接口开始,从左到右-right,然后到每个超级接口(在 extends 子句中也是从左到右)。或者,您可以在组合体的程序集中覆盖;
其中 LdapAuthenticatorMixin 可能是抽象的并且仅重写单个方法。
Bozho; For you question about Mixins being declared on interfaces,
The Mixin implementations can be overridden, either in "higher" (i.e. sub-) interfaces, as the seek order for implementations happen "per method" and goes from the declared interface, left-to-right, and then to each of the super interfaces (also left-to-right in the extends clause). OR, you can override in the Assembly of a composite;
where the LdapAuthenticatorMixin may be abstract and only override a single method.