【问题标题】:Advice on designing loosely-coupled complete systems?关于设计松散耦合的完整系统的建议?
【发布时间】:2010-09-22 14:21:52
【问题描述】:

如何设计松散耦合的系统,这些系统可能经常需要来自彼此的数据,但不一定属于同一类别?

例如,让我们将旧的 Pet-shop 示例更进一步,并创建一个 pet-store 特许经营权。每个宠物商店都有自己的网站,列出他们的联系信息、促销活动和当前库存。

特许经营权所有者希望拥有所有特许经营宠物店的列表以及联系信息,并且可能在他们的公司网站上提供一些照片。他们希望能够更新此信息,并让任何更新都自动双向推送。他们还希望以自动方式向所有商店的网站提供促销信息。

因此,在这种情况下,库存清单由商店“拥有”,联系信息由两个实体部分“拥有”,促销信息由总部“拥有”。由于任意原因,所有这些数据都不能存储在同一个地方。

是否有一些最佳实践或常见策略来应对这种情况?

【问题讨论】:

    标签: design-patterns architecture distributed coupling


    【解决方案1】:

    我基本同意上面提出的解决方案(使用 SOA)。根据应用程序的复杂性,ESB 可能是一种很好的方法。但是,我认为 ESB 占用空间很大,并为大多数实际应用程序带来了不必要的复杂性。

    但是,恕我直言,任何好的架构都应该很容易适应应用程序服务器,而无需进行重大的架构/设计更改。

    假设一个基于 Java 的中大型 n 层应用程序,以下是我对中间层和 EIS 层的建议:

    1. 分离每个 subSystem 实现并通过服务接口公开其功能,并隐藏这些实现以防止直接使用或引用。

    2. 为每个子系统创建一个 JAR(或 EAR)文件,并确定上述子系统/JAR 之间的运行时和编译时依赖关系。

    3. 花费大量时间来确定服务接口方法和子系统依赖项的正确粒度。

    4. 在此过程中,尝试识别每个模块的 DAO 层(假设涉及 DB)并为每个子系统分离数据库表。

    对于网络层,尝试通过子系统划分表示层来执行与上述相同的操作。为每个子系统创建一个 WAR 文件。如有必要,请尝试将表示层 WAR 放入上面确定的相应 EAR 文件中。

    对上述架构的一个很好的验证是将其部署在 OSGi 中,使用每个服务作为 OSGi 服务(在创建适当的清单文件之后)。

    请记住,如有必要,也可以在任何这些子系统之间设置基于事件/异步通信。

    这提供了拆分子系统并将它们部署在不同服务器群中的机会,以获得更好的可扩展性机会。

    祝你好运..!

    【讨论】:

      【解决方案2】:

      似乎 SOA 在这种情况下会有所帮助。我特别指的是业务级 SOA,例如, Bill PooleUdi Dahan 具有基于 pub-sub 异步事件的实现。

      您描述了具有不同所有者的几个业务功能:特许经营和销售。您希望实现它们之间的松散耦合。

      在 SOA 中,您定义特许经营服务和多个销售服务实例,每个商店一个。商店最初非常相似,但可以单独发展。

      然后,您定义在这些服务中发生的共同感兴趣的业务事件。特许服务可以发布所有销售服务订阅的 NewPromotion 事件。此事件消息包含有关促销的所有详细信息,消费者可以选择他们需要的内容。销售服务依次发布 ContactDetailsChanged 事件以供特许经营使用。

      每个服务在内部都有自己的多层实现,包括数据库、面向客户的网站、与其他系统的私有集成点等。

      每个服务都以它认为合适的形式私下存储它感兴趣的所有数据:库存清单、联系信息、促销信息。一个服务中的信息更新通过事件传播到其他服务。

      在实施方面,您需要在服务之间建立某种服务总线,并支持在不可靠的互联网上进行持久消息传递,例如NServiceBus。不需要 WebServices(tm)。

      您的服务在实现中是松耦合的,因为它们只共享合约(对它们发布的消息和端点的描述)并且可以独立地发展内部表示。它们在时间上也是松散耦合的,因为如果它们在任何时候都不会相互发送可能通过互联网超时的同步请求。所有消息传递都由基础架构(服务总线)处理。

      希望这会有所帮助:)

      【讨论】:

        【解决方案3】:

        我一直在思考这个问题,我通过说类之间的关系是由上下文决定的来表达它。任何假设类之间的全局静态关联(内在耦合)的模型都是有问题的。

        我喜欢使用的另一个示例是产品。

        一个产品可以扮演很多不同的角色。它与 OrderItem 相关联,OrderItem 与 Order 相关联,而 Order 又与 Customer 相关联。

        它由供应商提供。

        它在目录中,可能按章节和页面。

        这是买方的责任,可从多个供应商处获得。

        轻松处理这种复杂性的能力是关系数据模型的根本优势;而且我还没有看到它在 OOP 方面得到了很好的处理。

        除此之外:还有另一个 ORM(对象角色建模,请参阅 VisioModeler、InfoModeler 等)从关系方面看问题,非常有用(恕我直言)。

        当您将自己与数据库的关系隔离(通过使用 CRUD 生成器、ActiveRecords 等)时,您就隐藏了这一重要方面。 (我认为 LINQ 也有同样的问题,以及引入了基本的耦合问题,但我还没有完全解决。)

        我认为如果你小心点,你可以成功地完成它,但是在设计中嵌入耦合变得很容易,特别是如果你从数据库工作回到应用程序的其余部分,而不是另一个方向.

        【讨论】:

        • 我想你可能会找到一本书 (view it online) “基于事件的编程:将事件发挥到极致” 不要只看书名——第一章给出了深刻的描述和减少/转移耦合到较小形式的耦合行为的方法。
        【解决方案4】:

        我的理解是,这类问题最常使用一种称为“数据联合”的技术来解决——独立实体独立运行,但存在一个伞状实体,可以将系统视为一个整体.

        这是一篇可能有用的文章: http://www.soamag.com/I22/0908-1.asp

        在规划您的架构时,请记住当其中一位参与者不可用时会发生什么。例如,我建议将促销信息复制到所有商店,或者作为批处理,或者在参考数据更改时。这样,如果网络出现故障,各个商店仍然有促销信息并可以正常运行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-01
          • 2014-03-15
          • 2011-01-01
          • 2010-11-28
          • 1970-01-01
          • 2017-06-05
          • 1970-01-01
          • 2020-10-26
          相关资源
          最近更新 更多