如何设计松耦合系统,这些系统可能经常需要彼此的数据,但不一定属于同一类别?
例如,让我们将旧宠物店的例子更进一步,并创建一个宠物店特许经营权。每个宠物商店都有自己的网站,列出他们的联系信息,促销活动和当前库存。
特许经营权所有者想要列出所有特许经营宠物店以及联系方式,以及可能在公司网站上提供的一些照片。他们希望能够更新此信息,并自动双向推送任何更新。他们还希望以自动方式向所有商店的网站提供促销信息。
因此,在这种情况下,库存清单由商店“拥有”,并且联系信息由两个实体“部分”拥有,并且促销信息由HQ“拥有”。由于任意原因,所有这些数据都不能存储在同一个地方。
是否有一些应对这种情况的最佳做法或常用策略?
答案 0 :(得分:1)
我的理解是,这种问题通常使用称为“数据联合”的技术来解决 - 独立实体独立运行,但是存在一个类似伞状的实体,它提供了一个整体查看系统的能力
这是一篇可能有用的文章: http://www.soamag.com/I22/0908-1.asp
在规划架构时,请记住当其中一个参与者不可用时会发生什么。例如,我建议将促销信息作为批处理过程或参考数据更改时复制到所有商店。这样,如果网络出现故障,各个商店仍然会有促销信息并且可以正常运行。
答案 1 :(得分:1)
我一直在考虑这个问题,并且我通过说类之间的关系是在上下文中确定的来表达它。任何假设类之间存在全局静态关联(固有耦合)的模型都存在问题。
我喜欢使用的另一个例子是Products。
产品可以扮演一堆不同的角色。它与OrderItem相关联,OrderItem与Order关联,Order与客户关联。
由供应商提供。
它位于目录中,可能是Section和Page。
买方有责任,有多家供应商提供。
轻松处理这种复杂性的能力是Relational数据模型的基本优势;我没有看到它在OOP方面处理得很好。
除此之外:还有另一个ORM(对象角色建模,请参阅VisioModeler,InfoModeler等),它从关系方面看问题,非常有用(恕我直言)。
当您将自己与数据库的关系区分开时(通过使用CRUD生成器,ActiveRecords等),您隐藏了这个重要方面。 (我认为LINQ有同样的问题,并且引入了基本的耦合问题,但我还没有完全解决它。)
我认为如果你小心的话,你可以成功地完成它,但是在设计中嵌入耦合变得很容易,特别是如果你从数据库工作回到应用程序的其余部分,而不是另一个方向
答案 2 :(得分:1)
在这种情况下,SOA似乎有所帮助。我特别指的是业务级SOA,如例如Bill Poole和Udi Dahan使用pub-sub async基于事件的实现。
您描述了具有不同所有者的多个业务功能:特许经营和销售。你想在它们之间实现松耦合。
在SOA中,您可以定义特许经营服务,以及多个销售服务实例,每个商店一个。商店最初非常相似,但可以单独发展。
然后,您定义在这些服务中发生的共同感兴趣的业务事件。特许经营服务可以发布所有销售服务订阅的NewPromotion事件。此事件消息包含有关促销的所有详细信息,消费者可以选择所需的内容。销售服务反过来发布由特许经营消费的ContactDetailsChanged事件。
每个服务都有自己的内部多层实现,包括数据库,面向客户的网站,与其他系统的私有集成点等。
每个服务以其认为合适的形式私下存储它感兴趣的所有数据:股票清单,联系信息,促销信息。对一个服务中的信息的更新通过事件传播到其他服务。
在实施方面,您需要在服务之间使用某种服务总线,并支持在不可靠的互联网上进行持久的消息传递,例如: NServiceBus。没有WebServices(tm)是必需的。
您的服务在实施中松散耦合,因为它们只共享合同(他们发布的消息和端点的描述),并且可以独立地发展内部表示。它们也在时间上松散耦合,因为如果它们在任何时候都没有发送可以通过互联网超时的同步请求。所有消息都由基础设施(服务总线)处理。
希望这会有所帮助:)
答案 3 :(得分:0)
我大多同意上面提出的解决方案(使用SOA)。 ESB可能是一种很好的方法,具体取决于应用程序的复杂性。但是,我认为ESB占用空间很大,并且为大多数实际应用程序带来了不必要的复杂性。
但是,恕我直言,任何好的架构都应该很容易适应应用服务器而不需要进行重大的架构/设计更改。
假设一个基于Java的中型大规模n层应用程序,以下是我对中间层和EIS层的建议:
分离每个子系统实现并通过服务接口公开它的功能,并隐藏直接使用或引用的实现。
为每个子系统创建一个JAR(或EAR)文件,并确定上述子系统/ JAR之间的运行时和编译时依赖关系。
投入大量时间确定服务接口方法和子系统依赖关系的正确粒度。
在此过程中,尝试为每个模块识别DAO层(假设涉及DB)并为每个子系统分离数据库表。
对于Web层,尝试通过subSystems对表示层进行分区来执行与上面相同的操作。为每个子系统创建一个WAR文件。如有必要,尝试将表示层WAR放入上面标识的相应EAR文件中。
对上述体系结构的一个很好的验证是使用每个服务作为OSGi服务(在创建适当的清单文件之后)在OSGi中部署它。
请记住,如有必要,也可以在任何这些子系统之间建立基于事件的/异步通信。
这提供了分割子系统并将它们部署在不同服务器场中的机会,以获得更好的可扩展性机会。
祝你好运..!