清洁架构 - 罗伯特马丁 - 如何连接用例

时间:2015-03-06 05:25:13

标签: ios architecture software-design

我正在尝试实施罗伯特·马丁所描述的Clean Architecture。 更具体地说,我使用VIPER这是一个iOS版本的Clean Architecture。

我遇到的问题如下:

用户开始查看带有地点(引脚)的地图。 如果他点击一个按钮,则会丢弃一个引脚并将其带到另一个视图以创建(或编辑,如果它是对现有引脚的点击)该地点(或取消)。 在另一个视图中,用户可以编辑地点的信息,然后点击"返回"或者"完成" (或"编辑")。 如果他点击" done",PlaceDetailsViewController会向PlaceDetailsPresenter发送一条消息,其中包含场所信息,PlaceDetailsPresenter使用CreatePlaceInteractor创建该场所。此交互器返回用于标识场所的GUID。

如果用户在创建地点之前点击回来,他会回到地图并且掉落的引脚会上升和离开(因为它没有GUID,它是一个新的地方并且消失了)。 如果他在创建后单击后退,则引脚会保留在那里(因为它应该有一个GUID)。

我应该如何连接所有这些以及应该存储地点信息(包括GUID)的位置? 澄清一点:

  1. 谁应该通知MapPresenter针脚留在那里还是消失? 是PlaceDetailsPresenter还是我应该将此信息传递给PlaceDetailsWireframe - > MapWireframe - > MapPresenter - > MapView?
  2. 返回之前,应该在PlaceDetailsPresenter或PlaceDetailsViewController中存储此GUID的位置?
  3. 现在我拥有的是: enter image description here

    编辑:

    基本上我认为问题在于,VIPER来自罗伯特·马丁的清洁架构而且他来自网络(Rails)背景,所以他对国家(或者不是很多)没有太多考虑。在他的谈话中指明。)

    主要是我的问题,应该在哪里存储状态,不同模块应该如何通信,如果是通过线框,或通过数据库,或通过交互者,或通过演示者彼此通信,如此处https://github.com/objcio/issue-13-viper-swift

2 个答案:

答案 0 :(得分:18)

我对Viper了解不多,所以我无法对此发表评论。但是,系统的总状态应该保存在实体对象中并由交互者操纵。应通过控制器和演示者之间的特殊连接来管理GUI的详细状态(选择矩形等)。

在您的情况下有两个屏幕。地图和地方编辑器。单击地图会导致调用placePinController。它收集点击的位置和任何其他上下文数据,构造一个placePinRequest数据结构并将其传递给PlacePinInteractor,它检查引脚的位置,必要时验证它,创建一个Place实体来记录引脚,构造一个EditPlaceReponse对象并将其传递给EditPlacePresenter,它会打开场所编辑器屏幕。

如果在场所编辑器屏幕上单击了完成按钮,它将调用EditPlaceController,它将编辑的数据收集到EditPlaceRequest数据结构中并将其传递给EditPlaceInteractor。等。

您特别询问了该针的GUID。这将由Place实体创建并传递回editPlacePresenter PlacePinInteractor。

答案 1 :(得分:0)

在纯VIPER路由器中,应该以协议的形式保存模块输入。模块Presenter应该符合它。因此,当路由器使用其他模块路由器组装新模块时,它会将其输入传递给它。

然后第二个路由器将输入分配给其Presenters输出。因此,第一个模块的Presenter基本上成为第二个模块Presenter的委托。

因此,在您的情况下,当用户选择一个地点时,MapPresenter会向MapInteractor请求GUID,并告诉MapRouter导航到此GUID的详细信息。

MapRouter要求PlaceDetailsRouter为此GUID组装PlaceDetailsModule并将MapModuleInput传递给它。 PlaceDetailsRouter将MapModuleInput分配给PlaceDetailsPresenter。 PlaceDetailsRouter将GUID放入PlaceDetailsInteractor