4

我的一个项目中有设计级别的问题。我正在开发一个需要使用 REST 获取一些对象的项目。例如,获取客户并将其显示在列表中。

以下可以对客户进行的操作,

  • 添加客户
  • 编辑客户详细信息
  • 删除客户

所以我想包括一个名为'CustomerManager'的类,包括以下方法,

  @interface CustomerManager
  - (CustomerManager *)sharedManager;

  - (BOOL)addCustomer:(Customer *)customer;
  - (BOOL)deleteCustomer:(Customer *)customer;
  - (BOOL)updateCustomer:(Customer *)customer;

  @end

  @implementation CustomerManager

   - (BOOL)addCustomer:(Customer *)customer;
    {
       NetworkManager  * manager = [NetworkManager manager]     addCustomer:customer ];
    }
   @end

在我需要执行客户相关操作的 ViewController 中,我曾经这样做过,

 Customer * manager = [Customer sharedManager];
 [manager addCustomer:customer];

 //fetch customer
 [manager customers];

 //While deleting
 [manager deleteCustomer:customer];

一切看起来和工作正常,直到我得到一个设计级别的问题,为什么中间有一个经理。所有工作都在客户对象上完成,因此您需要在客户类中拥有所有与客户相关的操作,如下所示。

  @interface Customer

  + (BOOL)addCustomer:(Customer *)customer;
  + (BOOL)deleteCustomer:(Customer *)customer;
  + (BOOL)updateCustomer:(Customer *)customer;
  + (NSArray *)customers;

  @end

这里的问题是,即使网络相关代码在一个单独的类中,我也需要在我的所有模型类中都有我的网络管理器的具体引用。迷茫,该选哪一个。

哪个是最好的方法?我想对此有一些详细的答案。

4

2 回答 2

2

我不相信这里有正确的答案。我个人在如何让我的 Web 服务与我的模型交互方面反复讨论。但我可以为您提供一些建议:

  1. CustomerManager 是矫枉过正。Customer 模型负责管理自身——您可以在其中放置与 Customer 相关的方法。您在这里不需要单独的对象。
  2. 我通常为我的模型使用超类。因此,例如,您可以有一个名为 ApplicationModel 的类,Customer 和您的所有其他模型都将从该类继承。这是干掉模型中的代码的好方法。如果您确实决定在模型中包含与网络相关的代码,我建议将其放在这个超类中。这样,如果您需要更改 Web 服务的工作方式,您只需在 1 个地方更改代码。
  3. 一般来说,我建议将与网络相关的代码与您的模型分开。我喜欢让我的网络逻辑尽可能独立。与网络相关的代码很容易发生变化,并且您希望尽量减少网络更改影响您的代码的地方的数量。例如,我通常创建一个作为 API 包装器服务的类,它提供了一个用于进行 API 调用的公共接口。此类还负责解析这些方法的响应并与模型交互(即解析 JSON 自定义数组并与 Customer 交互以将这些对象添加到数据库中)。
于 2013-05-24T12:24:18.427 回答
2

我不同意迈克尔弗雷德里克的第一点。

您的 CustomerManager 比将客户 CRUD 操作放在客户模型对象本身上要好得多。第一个也是最重要的原因是客户模型类的单一职责应该是代表一个客户;不另外管理一组客户(单一责任原则)。在 DDD 术语中,我希望 Customer 类是一个entity

请注意,模型对象(如在 MVC 模式中)和域对象之间存在很大差异。主要区别在于模型对象的职责是为视图提供一些数据的表示,而域对象的职责是,并且不应该超过,是域概念的逻辑转换,独立于表示。

正如我从您的控制器中得知的那样,您的模型应该拥有一组客户。因此,我会让 CustomersModel 持有一组 Customer 对象。控制器的职责是处理请求并根据请求适当地操作模型,以便结果是应用程序状态的一致视图。它不也不应该对 CRUD 操作本身负责。通常在多层设计中,应用层服务将负责此类操作,这可能会将其委托给基础设施层存储库(或 DAO)。放在一起,至少我的设计看起来像:

客户crud uml

所有的 CRUD、请求的处理和状态管理都在这个 UML 图的左侧执行。

另一种看待方式是,用最简单的术语来说,所有这些都可能相当于几行代码。假设您正在对数组执行相同的 CRUD 操作。数组元素本身是否应该负责操作数组?当然不是。CustomerRepository 是数组,NetworkManager 是它的持久性(即内存),控制器是使用数组的参与者,CustomersModel 是本地副本或子集,Customer 是数组元素。

于 2013-05-25T11:41:40.480 回答