我的EJB3设计中有明显的缺陷

时间:2011-05-19 21:18:16

标签: java java-ee ejb-3.0

我有一个名为VehicleRecord的域对象,它是一个休眠实体。这些VehicleRecords上的CRUD操作通过实现为无状态会话bean接口的实体访问对象来处理

@Local
interface VehicleRecordEao {
    void add(VehicleRecord record);
    List<VehicleRecord> findAll();
    ...
}

@Stateless
class HibernateVehicleRecordEaoBean implements VehicleRecordEao { ... }

从业务层角度来看,删除和添加这些记录不仅仅是一个CRUD操作。例如,可能存在日志记录和安全性要求。要向客户端提供这些操作,会话Bean在业务层中创建。

@Local
interface VehicleRecordManager {
    void createVehicleRecord(VehicleRecord record);
    List<VehicleRecord> findAll(String make, String model); 
    ...
}

@Stateless
class VehicleRecordManagerBean {
    public void createVehicleRecordManager(VehicleRecord record) {
        //business rules such as logging, security,
        //   perhaps a required web service interaction
        //add the new record with the Eao bean
    }
    ...
}

控制器在表示层和上面的业务层之间工作,以完成工作,根据需要在表示对象(如表单)和实体之间进行转换。

这里的东西不对(闻起来)。我有一个名为Manager的类,它必须是一个红旗,但EJB书中的几个例子实际上建议这种高级类,并倾向于自己使用名称管理器。我是EJB设计的新手,但在OO设计中,使用称为Manager或Handler的高级类或实用程序的尖叫程序,需要重新考虑他们的设计。

这些程序 - 实用程序类会话bean是正常模式,还是通过一组仅与其操作的实体相关的方法来组织会话?会话bean有任何命名约定吗? Eao和业务会话bean应该在同一层工作吗?

如果对这种模式有一个不那么臭的替代方案,我很想知道,谢谢。

5 个答案:

答案 0 :(得分:4)

您的方法或多或少是标准的。是的,从根本上讲,这是一种程序性方法,与被称为Anemic Domain Model“反模式”的方式齐头并进。另一种方法是将您的业务逻辑合并到您的域模型中,以便创建更多的OO设计,使您的操作与您的DO相结合。如果你沿着这条路走you should be aware of the inherent pros and cons。如果你觉得你的方法最有意义,很容易理解,测试,扩展等等......然后用它来扮演角色。我曾参与过几个使用这种“程序”风格的n层项目 - 请放心,在EE应用程序中以这种方式做事是非常标准的。

答案 1 :(得分:4)

这是一个古老的讨论。面包烤自己,还是烤箱烤?消息是自己发送,还是邮局这样做?我是否通过要求他向自己发送消息向我的朋友Pete发送消息?

根据提出ADM一词的人来说,让每个对象自己完成所有这些事情更“自然”,更“OO”。采取极端(当然没有人提倡,但仅作为一个例子)类用户将包含整个应用程序的所有逻辑,因为最终用户会做所有事情。

如果您使用 slim 实体(仅包含数据的实体)和服务或DAO对象来处理它们,那么您不一定不会使用OO。 OO仍然存在 很多 。服务实现接口,从基类继承,具有封装状态(例如JPA中的EntityManager),通过动态代理具有透明拦截器(例如,检查安全性和启动/提交事务)等等。

术语“贫血”具有明确的负面联想,但称同样的“苗条”实际上听起来不错。这不仅仅是使用不同名称隐藏代码气味的情况,而是代表不同人群之间的不同思维。

答案 2 :(得分:1)

我认为这取决于您的品味,并且取决于您的应用程序的复杂性 - 这些事情更重要/更重要。我认为在设计中,你需要简单地解决这个问题:

“如果有新人在没有相关系统的任何先验知识的情况下进入 - 这个人是否足够直观地跟踪和追踪代码,并直接找到事物的位置”

在您的情况下 - 命名与实体对象相关的EJB使其变得简单明了 - 我没有得到的是为什么将它分成2个类EAO和Manager。为什么不把它们组合成一个,所以如果EJB / Bean类处理VehicleRecord实体,那么它将是“VehicleRecordEAO”或“VehicleRecordManager”或“VehicleRecordAccess”或其他任何东西。

我认为EAO / DAO / Access听起来更像是getter / setter - 或任何其他简单的操作。我没有看到“经理”出现任何问题,并使其全面保持一致,即所有业务层都将被称为“经理”。

或者如果您感觉更好,可以将其视为Facade Pattern - 因此您可以将业务层(Manager)称为VehicleRecordFacade和VehicleRecordFacadeBean。

这样你基本上遵循Facade模式的名称和概念,它成为应用层和数据层之间的中介。

答案 3 :(得分:1)

  

这里的东西不对(闻起来)。   我有一个名为Manager的类   必须是一面红旗

我的回答是针对你的这种担忧。

是。这是一面红旗。命名类似“VehicleRecordManager”的类将是代码气味,表明迟早会违反Single responsibility principle

详细说明,让我用一些用例来处理VehicleRecord

  1. 买车
  2. 租车
  3. 搜索车辆
  4. 卖车
  5. 查找经销商
  6. 在大多数Java应用程序中,当我们编写“VehicleService”(或“VehicleManager”)时,所有上述操作都将放在此类中!嗯,这个很容易做,但很难维护。当然,这门课有很多责任,因此有许多改变的理由。 (违反单一责任原则)

答案 4 :(得分:0)

调用它VehicleDao会消除一些异味吗?一个简单的改变,但清楚地表明它涉及数据访问问题。