Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 类数据责任_Design Patterns_Class Design - Fatal编程技术网

Design patterns 类数据责任

Design patterns 类数据责任,design-patterns,class-design,Design Patterns,Class Design,我有一个“采购订单”课程。它包含有关单个采购订单的信息。我有一个数据库方法的DAO类 加载和更新采购订单的方法的责任应在哪里 PurchaseOrder类是否应该具有直接使用DAO类的“.update”、“insert”、“delete”和“.load”方法,或者PurchaseOrder类是否应该不知道DAO方法并具有管理这些交互的POController类 用户一次只能处理一个PurchaseOrder 谢谢 我肯定会将“业务逻辑”(PurchaseOrder)与数据库交互/访问分开。如果您

我有一个“采购订单”课程。它包含有关单个采购订单的信息。我有一个数据库方法的DAO类

加载和更新采购订单的方法的责任应在哪里

PurchaseOrder类是否应该具有直接使用DAO类的“.update”、“insert”、“delete”和“.load”方法,或者PurchaseOrder类是否应该不知道DAO方法并具有管理这些交互的POController类

用户一次只能处理一个PurchaseOrder


谢谢

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

采购订单应该不知道其持久性的细节。这就是拥有某种数据访问层的意义所在,它处理对象的管理,对象本身可以专注于成为一个采购订单


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

我个人会创建一个管理交互的对象。我不能充分说明不将此逻辑放入PurchaseOrder类本身,但创建此控制器对象将导致更松散耦合的对象。

这取决于您认为应用程序将存在多长时间。我公司的金属切削应用程序自1985年以来一直在不断开发,并通过计算机体系结构的多次变化得到了广泛应用。在我们的例子中,我们几乎总是把事情推到接口后面(或者用你的术语来说是控制器类),因为我们不知道事情在5年、10年、15年后会是什么状态

通过使用控制器类,我们可以更改底层API,而无需修改上述业务逻辑和UI调整的级别。这些水平代表了多年的工作,因此保护他们的行为很重要


请记住,项目生命周期的大部分时间都在维护中。您现在所做的任何使以后更改设计更容易的事情都将在今后节省大量时间。

PurchaseOrder类应该不知道DAO。purchaseOrder类应表示数据本身,仅此而已。使用控制器或服务管理器或任何您想调用它的东西来使用DAO持久化/加载PurchaseOrder记录。这为您的设计提供了最大的灵活性。您有一个位置用于数据模型,一个位置用于存储/检索PurchaseOrder的业务逻辑(控制器),还有一个位置用于实际保存PurchaseOrder。

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

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


另一件需要考虑的事情是结构的其余部分。保存/加载从何处启动?如果您要对PO进行大量操作(保存、加载、打印、发送给客户),那么可能需要一个控制器来完成所有这些操作,而不是将功能集成到PO类中。它的优点是,您可以添加PO操作,而无需修改PO类。

我将把PurchaseOrder作为一个接口,并将所有DAO代码放入实现中,然后使用工厂,从而使操作简单。

让我来向您介绍我的推理:

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

那么你就转到

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

PurchaseOrder po;
PurchaseOrderController poc;
poc = PurchaseOrderControllerFactory.Instance.Create();
po = poc.GetPurchaseOrder(42);
// do stuff
poc.SavePurchaseOrder(po);
// 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...
然后我会从头开始

从行为开始
文学士