如何为不同的表示层设计应用程序?

时间:2009-06-06 10:26:33

标签: java oop object

我是使用专有mvc框架开发Web应用程序的团队的一员。 这个框架有点像一个非常可怜的男人的支柱!它有一个中央控制器,属性文件中的配置,像生成的数据库操作类一样的扭矩,没有表单bean。

假设您有一个用户帐户编辑屏幕,以下是开发人员编写的典型代码: 公共类Handler扩展了StupidFrameworkBaseHandler {

// This is analogous to Struts Action
// Handlers are invoked by your controller.
    public void execute() {
        // get form elements
        }
    }
    }

为了介绍表单bean的概念,声明了一个抽象的getFormBean()方法来扩展StupidFrameworkBaseHandler类。 BaseHandler类将调用此方法。所以现在代码看起来像这样:

public class Handler extends ExtendedStupidFrameworkBaseHandler {

public void execute() {
UserEditFormBean bean = (UserEditFormBean) baseBean;
// business layer classes.
}

public BaseBean getFormBean() {
// get HTTP Request parameters and build an object.
UserEditFormBean bean = new UserEditFormBean();
bean.setUser(httpRequest.getParam("whatever"));
// other setters...
}
return bean;
}

在使用此框架开发的早期应用程序中,编码器会将所有内容编码到Handler中 - 获取数据库连接,业务逻辑等。为了改变我在当前应用程序中引入业务和DAO层的概念。

所以最终代码看起来有点像这样:

    public class Handler extends ExtendedStupidFrameworkBaseHandler {

    public void execute() {
        UserEditFormBean bean = (UserEditFormBean) baseBean;
        UserBO busObj = new UserBO();
        busObj.validateUserDetailsAndSave(bean); // I know this sucks..
    }

    public BaseBean getFormBean() {
        // grab user input from form and return a form bean instance.
    }

}

业务层看起来像这样:

   public UserBO extends BaseBO {

    public void validateUserDetailsAndSave(UserEditFormBean bean) {
    UserDAO dao = factory.getDao("user");
    // call getters on bean, do some validations, throw business exceptions.
    User objUser = new User();
    object.setUserName(bean.getUserName());
    // few more setters here on User -> that is the model.
    dao.update(objUser);
    }

    }

我觉得这个整体设计很可怕,原因有很多:

  1. UserBO是一个没有状态的类。 它只是一组方法 程序代码。
  2. 如果您将这些称为图层, 那么每一层都不应该依赖 另一个:UserBo将永远 期望每种类型都有一种FormBean 方法,如果我忽略HTML 并重新使用相同的BO类 独立的java应用程序,我会的 永远不能没有创造 FormBeans作为params。
  3. 代码看起来很恐怖 unmaintaineable。
  4. 所以,我的问题是:

    您是否应该开发独立于表示层的业务层?我宁愿使用适当的状态,验证和异常抛出来编写我的业务对象?
    上面的例子不是代码提供的,非Java非常糟糕的做法吗?

2 个答案:

答案 0 :(得分:2)

我建议你看一下Spring Framework。它具有IoC容器(控制反转)的概念,并且在很大程度上依赖于依赖注入模式。后一种模式在解耦对象时非常有用,这是构建应用程序层时必须确保的主要事项。您的图层应完全独立。因此,例如,您的业务层永远不应该从您的表示层引用内容。例如,确保您可以使用以下情况,即Web表示层和独立客户端应用程序(表示层)具有相同的业务层。如果这可能比你在正确的道路上那么可能。

要解耦图层,您应该始终通过相应的接口定义明确的“合同”。因此,例如,您应该拥有业务(或服务)层类MyService.java和相应的IMyService.java(或者您喜欢的MyServiceImpl.java和MyService.java),其中IService.java是定义方法的接口。通过MyService类的实际实现公开,它基本上包含您的业务逻辑。因此,您的表示层将仅使用该界面连接到您的业务层。这就是Spring在依赖注入方面发挥作用的地方。在您的表示层上,您将拥有:

...
public void someMethod(..){
  IService service = new MyService();
  service.doSomething(...);
  ..
}

如您所见,这将通过使用MyService()对象再次耦合您的图层。因此,通常会避免使用这样的实例化,并使用Factories使其更加独立(您已经做了类似于我所看到的事情),例如在配置文件中以声明方式将其定义在某处.Spring为您执行此操作。我打算写一篇关于Spring的分层架构的这些优点的文章,但不是在7月之前,因为我现在很忙。

希望这能让你大致了解应该如何做。

答案 1 :(得分:0)

您应该将业务和表示层分开。

我会推荐Spring Framework,但鉴于您正在使用Web应用程序,我认为您会对Spring Web MVC特别感兴趣,因为它提供了您似乎正在寻找的所有功能。