【问题标题】:Does n tier architecture break OO concept of encapsulationn层架构是否打破了封装的OO概念
【发布时间】:2010-10-10 06:21:57
【问题描述】:

我有一个包含表示层、业务层、DAL 和业务对象层的 n 层应用程序。分离对象和写在对象上的操作打破了面向对象的封装概念。

【问题讨论】:

    标签: design-patterns oop architecture n-tier-architecture


    【解决方案1】:

    没有。考虑一下“封装”的含义:类的实现细节隐藏在类的接口(消息或方法)后面。

    事实上,您可以直接从 OO 原则和帕纳斯定律推导出 n 层架构:模块应该封装可能发生变化的内容。表示层封装了创建“可见”界面的细节;中间层是业务本身的模型;以及后端访问持久数据存储的详细信息。

    【讨论】:

      【解决方案2】:

      以这个例子为例,取自this article

      public class Position
      {
        public double distance( Position position )
        {
          // calculate and return distance...
        }
      
        public double heading( Position position )
        {
          // calculate and return heading...
        }
      
        public double latitude;
        public double longitude;
      }
      

      根据同一篇文章,这是一个很好的封装示例,因为数据和对该数据执行的操作是捆绑在一起的。请注意,此处的封装并不能保证数据隐藏或保护。

      相比之下,Steve McConnell 在 Code Complete(第 2 版,第 6.2 节,良好封装)中辩称封装被破坏,因为成员数据被暴露。

      在您的情况下,如果您的数据对象和操作它们的对象是分开的但没有公共字段,则根据第一个定义,封装被破坏,但不一定在第二种情况下。所以我们有两种截然不同的观点。一个人说数据隐藏不是封装的一部分,另一个消息来源说数据隐藏是封装的重要组成部分。

      数据隐藏可以看作是信息隐藏的一部分,该原则规定您应该隐藏复杂的设计决策和变更来源。普遍的共识似乎是,封装被视为信息隐藏的一种表现形式,包括数据隐藏。

      或者,正如Wikipedia 所说:

      经常使用术语封装 与信息互换 隐藏。并非所有人都同意 两者之间的区别; 人们可能会认为信息隐藏是 是原理和封装 作为技术。一个软件模块 通过封装隐藏信息 信息到模块或其他 呈现界面的构造。

      但是...本段后面的参考文献与我取第一个示例的文章是同一篇文章,所以即使是维基百科也在这里混淆了一些东西。此外,这里使用“区别”一词似乎是错误的。

      最后不得不说这话有点蹩脚,但封装和信息隐藏的术语已经超载,所以这一切都取决于来源。在您的情况下,我会坚持将封装定义为“将实现细节隐藏在抽象后面”。因此,您不一定要破坏封装。

      【讨论】:

        【解决方案3】:

        这是一个非常棒的点AP!

        在某些情况下,我同意将单个操作分解为多个对象确实会对封装产生不利影响。事实上,我认为这是我在许多 Web 架构中看到的一个大问题。

        另一方面,某些东西对分解很有用,例如向数据库发送查询的对象等。

        我认为,在许多情况下,有一个论据可以更好地“封装”网页,以便更多的功能包含在单个对象或更少的对象中。因此,这是一种更加“以页面为中心”的方法,而不是将逻辑分散到大量类中。

        我认为对于我们设计的每个系统,我们总是要问自己一个至关重要的问题——要抽象多少?具体要多少?如何有效地将系统分解为类。

        【讨论】:

          【解决方案4】:

          两者不一样。架构更多地是指模块(类组)。封装是指隐藏类的内部工作。如果您的系统设计得足够好,您可以同时拥有两者。

          您可能需要注意的是明确定义责任分离。只要您清楚每个模块/层的用途,并具体了解每个类的作用(以及该类的每个方法的作用),那么您应该能够有一个好的设计。

          我只是在这里推测,但您在设计模块接口时可能对facade design pattern 感兴趣。

          关于您下面的评论,逻辑绝对应该在员工类本身中。我会质疑为业务对象设置单独层的逻辑。定义像“Employee”这样的类通常是一种诱惑,因为它们对现实世界的对象或概念进行建模。但是,您定义类的动机不应该是“为真实世界对象建模”。

          你应该定义你的模块的目的(为什么你有一个业务逻辑层?包含所有的业务逻辑。)然后把你需要的东西放在那里。如果“Employee”类是需要计算业务逻辑的类,那么它应该进入业务逻辑类。如果不是,那么它应该放在您的业务对象类中(无论是什么用途)。如果它需要做两件不同的事情,因此可以适合两层,那么考虑将它分成两个类 - 请记住,您的对象不需要对现实世界的事物进行建模。 Robert C Martin 建议定义你的类,这样类的边界就是目的的边界。

          【讨论】:

          • 如果在业务对象层中定义了一个员工类,并且对员工工作的逻辑在业务层中,显然我在这里将数据和逻辑分离为 2 个不同的类。但是封装说数据和逻辑在一个类中?
          • 封装在哪里说的?使用该理论,应用程序中的所有内容都需要封装在 one 类中,因为它们都以某种方式相关。
          猜你喜欢
          • 2023-03-09
          • 1970-01-01
          • 2010-12-20
          • 1970-01-01
          • 1970-01-01
          • 2015-12-27
          • 2019-02-05
          • 2018-09-20
          • 2013-10-17
          相关资源
          最近更新 更多