班级数据责任

时间:2008-10-03 15:08:26

标签: design-patterns class-design

我有一个'采购订单'类。它包含有关单个采购订单的信息。我有一个DAO类用于数据库方法。

对于将加载和更新采购订单的方法,责任在哪里?

PurchaseOrder类是否应该直接使用DAO类的'.update','insert','delete'和'.load'方法,或者PurchaseOrder类是否应该忽略DAO方法并且具有POController类管理这些互动?

用户一次只能处理一个PurchaseOrder。

谢谢!

8 个答案:

答案 0 :(得分:4)

采购订单应该不了解其持久性的细节。这是拥有某种数据访问层的关键,它处理对象的管理,而对象本身可以专注于只是一个采购订单。

这也使系统更容易测试,因为您可以创建模拟采购订单并测试系统如何处理它们的逻辑,而不会纠缠于持久性问题。

答案 1 :(得分:1)

通过将PurchaseOrder作为接口并将所有DAO代码放在实现中,然后使用工厂,我会保持简单。

答案 2 :(得分:0)

这取决于您认为您的应用程序将存在多久。我公司的金属切削应用自1985年以来不断发展,并通过计算机架构的多种变化。在我们的例子中,我们几乎总是把东西推到一个接口(或控制器类使用你的术语)背后,因为我们不会在5年,10年,15年后的状态。

通过使用控制器类,我们可以更改底层API,而不会篡改上面的业务逻辑和UI调整级别。这些级别代表了多年的工作,因此保持其行为非常重要。

请记住您的项目在维护期间的大部分时间。您现在所做的任何事情都可以让以后更容易更改设计,这样可以节省大量的时间。

答案 3 :(得分:0)

PurchaseOrder类应该不知道DAO。 purchaseOrder类应该代表数据本身,仅此而已。使用控制器或服务管理器或任何您想要的方法来使用DAO持久保存/加载PurchaseOrder记录。这为您的设计提供了最大的灵活性。您有一个适合您的数据模型的地方,一个适用于您的业务逻辑(控制器)的地方,用于存储/检索PurchaseOrders的方式以及实际持有的一个地方。

答案 4 :(得分:0)

让我引导你完成我的推理:

班级方法
基本原则:持久性是一种阶级行为,应该是一种阶级方法
您需要分离关注点,因此您将数据库细节置于DAO类中,并使用该类中的数据来实现方法。
第一个问题:如果需要支持不同的DAO集,则需要通过Factory创建它们。 第二个问题:并非所有持久性行为都与该类的实例具体相关。例如List和Search方法:它们返回Class列表,而不是类,并且不依赖于实例。所以它们基本上是静态方法 第三个问题:您希望在此类上支持继承。因此,持久性细节因父母而异。如果你有静态方法,那将是一个问题。

所以你转到

<强>控制器
基本原则:持久性方法不属于单个类,它们更大,因此它们应该分开
需要再次分离关注点,因此您需要DAO。这是一个Utility类,因此方法基本上都是 static 第一个问题:如果要支持多种持久性方法,则需要工厂来创建DAO 第二个问题:您希望支持类的层次结构,因此您不能使用静态类。您需要通过工厂生成控制器 第三个问题:您向开发人员提供过于复杂的API 客户端代码示例:

PurchaseOrder po;
PurchaseOrderController poc;
poc = PurchaseOrderControllerFactory.Instance.Create();
po = poc.GetPurchaseOrder(42);
// do stuff
poc.SavePurchaseOrder(po);

然后我会从头开始。

从行为开始
基本原则:持久性不是一种行为。行为大于持久性。
在您的系统中,将有一个采购订单子系统。您的用户只能在高级别(用例级别)与其进行交互。因此,这些方法将实现Purchase Order用例。如果需要,这些方法将通过工厂使用DAO来访问数据库并执行他们需要做的任何事情 简而言之,您的PurchaseOrder基本上是一个DTO,一种传递数据的快捷方式。它不应该有行为 客户端代码示例:

// It could be a factory if needed.
PurchaseOrderSystem pos = new PurchaseOrderSystem(); 

List<PurchaseOrder> transacted;
transacted = pos.TransactPurchaseOrders(john, 23);

// Show transacted purchase orders or whatever...

答案 5 :(得分:-1)

我肯定会将“业务逻辑”(PurchaseOrder)与数据库交互/访问分开。如果您转移到其他供应商等,您可以更轻松地更改访问权限,而不会潜在地干扰业务实施,此外您还可以更轻松地避免向数据库访问层添加行为。

答案 6 :(得分:-1)

就个人而言,我会创建一个管理交互的对象。我不能强烈建议不将此逻辑放在PurchaseOrder类中,但是创建这个控制器对象会导致更松散耦合的对象。

答案 7 :(得分:-1)

这里要考虑的关键是你将来可能想要做什么。也许你想用另一个数据库替换你的数据库?这就是为什么你应该明确地将代码与代表PO的类的数据库分开。这是责任的基本分离,我希望你已经做到了。

现在问题是:您是否希望第三类(控制器)管理PO和DAO类之间的交互?我认为这取决于你可以创建DAO类接口的一般性。如果DAO接口足够通用,您可以使用不同的存储机制编写插件替换,但不更改接口,那么我会让PO类与之交互。如果没有,那么我会写一个控制器类。

要考虑的另一件事是结构的其余部分。保存/负载从哪里开始?如果您要对PO进行大量操作(保存,加载,打印,发送给客户),那么拥有一个完成所有这些操作的控制器而不是将功能集成到PO类中可能是有意义的。 。它为您提供的优势是您可以添加PO操作,而无需修改PO类。