面向对象与分层;平衡“面向对象的纯度”和完成工作

dav*_*000 5 oop class-design

我相信面向对象,但还没有达到为了“符合面向对象”而使用不适当的设计/实现的程度。

那么,如何处理Serlvet/EJB/DataContainer分层架构:

  • Servlet 接收请求并调用“业务层”(例如会话 EJB)
  • 业务层从数据库中定位DataContainer并操作它们来实现业务逻辑
  • DataContainers 不包含真正的代码,仅包含与数据库对应的获取/设置。

这种方法很有吸引力;DataContainer 的作用很明确,并且很容易知道数据来自哪里。

除了不是面向对象之外,这还会导致业务层类不明确,难以命名和组织。

即使我们试图变得更加“面向对象”(例如,将其中一些方法放入 DataConatiners 中),其中一些操作也会对多个数据集进行操作。

如何防止业务层变得令人困惑的程序,但又不会用业务逻辑污染您的数据容器?

例子

class UserServlet {
  handleRequest() {
    String id = request.get("id");
    String name = request.get("name");
    if (UserBizLayer.updateUserName(id,name))
      response.setStatus(OK);
    else
      response.setStatus(BAD_REQUEST);
  }
}

class UseBizLayer {
    updateUserName(String id, String name) {
        long key = toLong(id);
        user = userDAO.find(key);
        if user == null
            return false;
        if (!validateUserName(name))
            return false;
        user.setName(name);
        userDAO.update(user);
        return true;
    }

    validateUserName(String name) {
        // do some validations and return
    }
}

class User {
    long key;
    String name;
    String email;

    // imagine getters/setters here
}
Run Code Online (Sandbox Code Playgroud)
  • 我们不需要validateUserName用户,因为它只对名称进行操作;我想它可以进入另一个类,但是我们有另一个程序“uti”类型类
  • 我们不希望用户使用持久性方法,因为将数据结构与其持久性策略解耦是有价值的
  • 我们不希望 Servlet 中包含业务逻辑,因为我们可能需要在其他地方重用该逻辑
  • 我们不希望我们的业务逻辑在 User 中,因为这会过多地吸引 User 类,从而使业务逻辑的重用变得困难,并将用户与其持久性策略耦合起来

我意识到这个示例并没有那么糟糕,但想象一下 10 个 DataContainer 和 20 个 BizLayer 对象,每个对象都有多个方法。想象一下其中一些操作并不“集中”在特定的数据容器上。

我们如何避免这成为程序上的混乱?

Dan*_*nig 3

因此,我将通过以下几个要点来阐述我对此的想法:

  1. 似乎在 Java EE 系统中的某个时刻,您必须处理 Java EE 的管道,管道并不总是受益于 OO 概念,但它肯定可以通过一些创造力和工作。例如,您可以利用 AbstractFactory 等来帮助尽可能多地通用此基础设施。
  2. Eric Evans 的优秀著作《领域驱动设计》中讨论了您正在研究的很多内容。我强烈建议您查看它,因为他确实解决了表达领域知识并处理支持它的技术基础设施的问题。
  3. 阅读并理解了 DDD 的一些内容后,我会将我的技术基础架构封装在存储库中。所有存储库都将被编写为使用基于会话 EJB 的持久性策略。您可以编写一个默认实现,它知道如何与您的会话 EJBS 通信。为了实现这一点,您需要添加一些约定并在接口中指定该约定/约定。存储库执行所有 CRUD,并且只有在绝对需要时才应该执行更多操作。如果你说“我的 DAOS 是我的存储库”,那么我会同意。
  4. 所以继续这个。您需要一些东西来封装 UseBizLayer 中表达的工作单元。在这个级别上,我认为它的本质是你被困在编写所有将成为事务脚本的代码。您正在创建责任和状态的分离。这通常是我在 Java EE 系统中看到的默认架构的实现方式。但它不是面向对象的。我会尝试探索该模型,看看是否至少可以尝试通用一些写入 BizClass 的行为。
  5. 我之前使用过的另一种方法是摆脱 BizLayer 类,然后将来自域的调用代理到执行操作的实际存储库/DAO。然而,这可能需要一些基础设施建设投资。但是您可以使用像 Spring 这样的框架做很多事情,并使用一些 AOP 概念来使其工作良好并减少所需的自定义基础设施的数量。