在阅读OSGi application design - am I abusing the service framework?和What is the best way of grouping OSGi bundles to make a coherent 'application'后,我现在仍然面临着如何应用“不要编程OSGi”口头禅的问题。
假设有界上下文是整个应用程序而不是单个bundle,我应该可以自由地在API包中声明一些聚合根实体,并且在DDD样式中,可以使用一个用于处理所述实体的存储库。现在,问题的关键:显式存储库似乎与OSGi风格是对立的,因为存储库本身就是一个注册表(域对象),并且这种设计可以回避OSGi服务注册表。但是,要取消存储库,需要消费者对OSGi进行编程,以便执行实体的查找。
据说存储库只是一个外观 - 这是否意味着我应该创建一个委托给服务注册表的存储库实现?这似乎不是一个连贯的方法,因为消费者在域模型中有两个入口点:存储库和服务注册表本身。放弃存储库将不再是DDD,因为我们正在以类似意大利面条的方式将域逻辑与框架代码混合在一起。
那么这里的外卖是什么?域驱动设计是否与“OSGi方式”不兼容,还是我错过了一些关键概念?
答案 0 :(得分:3)
不依赖OSGi的基本原理是,作为中间件,OSGi代码中的可见性使其不那么紧密。域代码和OSGi代码不应该混合(就像它不应该与JMS,Java EE或任何其他API混合)。较少内聚的代码更复杂,因此容易出错。
但是,您始终需要一些将基础结构链接到域代码的桥接代码。由于这个桥接代码无论如何都会被耦合到某个API,因此将它用于剑柄,完全没有必要从桥接代码的环境中抽象出来。
DS(和Blueprint,iPOJO等)隐藏了业务逻辑的注册表,它们只是提供域注册表的非常方便的方法。因此,使用OSGi,您几乎不必编写任何代码来拥有一个非常强大的域对象存储库,而您的域对象本身并不知道OSGi。
是的,如果您将代码从OSGi移动到其他地方,您必须重写桥接代码并来自OSGi世界,编写OSGi提供的通用功能非常大。但是,不使用OSGi构造,因为如果应用程序被移植,你必须提供的功能就是丢钱。
结论:域名不应该与OSGi混合,桥接代码应该利用OSGi来处理。
答案 1 :(得分:1)
我认为您应该将存储库注册为OSGi服务。需要存储库的bundle应该引用该服务,并且应该只知道存储库接口。当然,这意味着您必须在Activator中使用ServiceTracker,例如蓝图背景。我更喜欢蓝图上下文,因为这样你就没有对OSGi的真正的java级依赖。
当然这会以某种方式创建对OSGi的依赖,但这是不可避免的。要遵循的基本思想是,您应该将OSGi特定代码保留在业务代码之外,并将其放在单独的类或蓝图中。
请参阅我的一个教程,其中显示了一个带有UI,模型和持久性impl的简单应用程序。虽然应用程序太小而无法真正执行DDD,但是aproach应该是相当兼容的。您会注意到的一件事是整个应用程序不会导入单个OSGi接口。一个很好的副作用是你可以轻松地重用OSGi之外的代码,但当然你必须以不同方式解决DI。