我相信OO,但是不应该使用不恰当的设计/实现只是为了“符合OO”。
那么,如何处理Serlvet / EJB / DataContainer分层架构:
这种方法具有吸引力; DataContainers清楚地知道他们做了什么,并且很容易知道数据的来源。
除了不是OO之外,这导致了不清楚的商业层类,这些类很难命名并且难以组织。
即使我们 试图更加“OO”(例如将其中一些方法放在DataConatiners中),其中一些操作也会对多个数据集进行操作。
如何保持业务层不会出现令人困惑的程序问题,但不会使用业务逻辑污染DataContainer?
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
}
validateUserName
,因为它只对名称进行操作;我想它可以进入另一个类,但是我们有另一个程序“uti”类型类我意识到这个例子并不是那么糟糕,但想象一下10个DataContainers和20个BizLayer对象,每个对象有几个方法。想象一下,其中一些操作并非“集中”在特定的数据容器上。
我们如何避免程序混乱?
答案 0 :(得分:3)
所以我将在几个要点中阐述我对此的看法:
答案 1 :(得分:1)
因为您正在实现类和对象,所以无论您如何分层,您的解决方案都将是OO - 根据您的情况/需求,它可能不是很好的结构! ; - )
对于您的具体问题,在某些情况下,validateUserName属于User类是有意义的,因为每个用户都希望拥有一个有效的名称。或者你可以有一个验证实用程序类,假设其他东西的名称使用相同的验证规则。电子邮件也是如此。您可以将它们拆分为NameValidator和EmailValidator类,如果它们将被大量使用,这将是一个很好的解决方案。您还可以在刚刚调用实用程序类方法的User对象上提供validateUserName函数。所有这些都是有效的解决方案。
关于OOD / OOP的一大惊喜是,当设计正确时,你知道它是正确的,因为很多东西都不属于你可以做到的模型你以前做不到。
在这种情况下,我会创建NameValidator和EmailValidator类,因为将来很可能其他实体将拥有名称和电子邮件地址,但我会在User类上提供validateName和validateEmailAddress函数,因为这样可以提供更方便的界面对于要使用的商业对象。
剩下的'我们不想要'的子弹是正确的;它们不仅是正确分层所必需的,而且它们也是清洁OO设计所必需的。
分层和OO基于层之间的关注点分离而进行手套。我认为你有正确的想法,但是需要一些实用程序类来进行常见的验证
答案 2 :(得分:1)
考虑如果没有计算机,这些任务将如何完成,并以这种方式为您的系统建模。
简单示例...客户端填写表单以请求窗口小部件,将其交给员工,员工验证客户端的身份,处理表单,获取窗口小部件,将窗口小部件和事务记录添加到客户并在公司某处保存交易记录。
客户端是否存储了他们的数据?不,员工这样做。员工在存储客户数据时会扮演什么角色?客户记录守护者。
表单是否验证它已正确填写?不,员工这样做。员工在做这件事时会扮演什么角色?表格处理器。
谁给客户端小部件?作为Widget分销商的员工
等等......
将其推入Java EE实现......
Servlet代表客户端行事,填写表单(从HTTP请求中提取数据并制作适当的Java对象)并将其传递给相应的员工(EJB),然后员工根据需要填写表单要完成。在处理请求时,EJB可能需要将其传递给另一个专门处理不同任务的EJB,其中一部分包括从/向存储(您的数据层)访问/放置信息。唯一不应该直接映射到类比的东西应该是关于对象如何相互通信的具体信息,以及数据层如何与存储进行通信。
答案 3 :(得分:0)
我自己也有同样的想法。
在传统的MVC中,最重要的是将View与模型和控制器部分分开。将控制器和模型分开似乎是一个好主意,因为你最终可能会得到臃肿的模型对象:
public class UserModel extends DatabaseModel implements XMLable, CRUDdy, Serializable, Fooable, Barloney, Baznatchy, Wibbling, Validating {
// member fields
// getters and setters
// 100 interface methods
}
虽然你可以为上面的许多界面设置单独的控制器(或整个模式),是的,它本质上是程序性的,但我想这就是现在的工作方式。或者你可以意识到一些接口正在做同样的事情(CRUDdy - 数据库存储和检索,Serializable - 与二进制格式相同,XMLable,与XML相同)所以你应该创建一个单独的系统来处理这个,每个潜在的后端都是系统处理的独立实现。上帝,这真的很糟糕。
也许有类似“co-classes”的东西可以让你为控制器实现提供单独的源文件,就像他们是他们所采用的模型类的成员一样。
至于业务规则,它们通常同时处理多个模型,因此它们应该是分开的。
答案 4 :(得分:0)
我认为这是一个关于“关注点分离”的问题。您的分层架构似乎在很长的路要走,但也许您需要做更多相同的事情 - 即在Java EE层中创建架构层?
DataContainer看起来很像数据传输对象(DTO)模式。
现代的OO设计有很多小类,每个类都与少数“朋友”相关,例如:通过作文。这可能会产生比你真正熟悉的更多的类和Java样板,但它应该导致设计更好的分层,更容易进行单元测试和维护。
(问题为+ 1,关于何时知道正确分层的答案为+1)
答案 5 :(得分:-1)
粗略地说,“我们不想要”部分必须要去。你想要它是正确的,或者你希望它保持原样。当您需要时,不创建一个类是没有意义的。 “我们有很多”是一个不好的借口。
事实上, 揭示所有内部类是不好的,但根据我的经验,每个概念创建一个类(即用户,ID,数据库概念) ...)总是有帮助。
接下来,Facade模式是不是可以解决BizRules类加载的问题,隐藏在一个组织良好且干净的界面背后?