Rod*_*uiz 37 architecture software-design ios viper-architecture
我一直在阅读罗伯特·马丁的清洁建筑,更具体地说是VIPER.
然后我遇到了这篇文章/ post Brigade的经验使用MVC替代,它描述了我目前正在做的事情.
在尝试在新的iOS项目上实现VIPER之后,我遇到了一些问题:
cti*_*tze 16
为了满足您的需求,我们需要有关特定案例的更多详细信息.为什么视图在回调时不能直接提供更多上下文信息?
我建议您传递Presenter一个Command对象,以便Presenter不必知道在哪种情况下该做什么.Presenter可以执行对象的方法,在需要时自己传递一些信息,而不了解视图的状态(从而引入高耦合).
id<FollowUpCommand> followUpCommand
.View创建一个XFollowUpCommand
(与YFollowUpCommand
and 相对ZFollowUpCommand
)并相应地设置其参数,然后将其放入DTO.FollowUpCommand
是什么,它都可以对数据做些什么.然后它执行协议的唯一方法followUpCommand.followUp
.具体实施将知道该怎么做.如果你必须在某些属性上执行switch-case/if-else,大多数时候它有助于将选项建模为继承自公共协议的对象并传递对象而不是状态.
呈现模块或呈现模块是否应该决定它是模态的?- 所提出的模块(第二个)应该决定,只要它被设计为仅以模态方式使用.把事物本身的知识放在事物本身.如果它的表示模式取决于上下文,那么模块本身就无法决定.
第二个模块的线框将收到如下消息:
[secondWireframe presentYourStuffIn:self.viewController]
Run Code Online (Sandbox Code Playgroud)
参数是应该进行演示的对象.asModal
如果模块设计为以两种方式使用,您也可以传递参数.如果只有一种方法,请将此信息放入受影响的模块(显示的模块)本身.
然后它将执行以下操作:
- (void)presentYourStuffIn:(UIViewController)viewController {
// set up module2ViewController
[self.presenter configureUserInterfaceForPresentation:module2ViewController];
// Assuming the modal transition is set up in your Storyboard
[viewController presentViewController:module2ViewController animated:YES completion:nil];
self.presentingViewController = viewController;
}
Run Code Online (Sandbox Code Playgroud)
如果你使用Storyboard Segues,你将不得不做一些不同的事情.
另外,假设第二个模块的视图被推入导航控制器,应如何处理"后退"操作?
如果你去"所有VIPER",是的,你必须从视图到其线框并路由到另一个线框.
要将数据从呈现的模块("Second")传递回呈现模块("First"),请添加SecondDelegate
并实现它FirstPresenter
.在弹出所呈现的模块之前,它会发送消息SecondDelegate
以通知结果.
但是,"不要反对框架".也许你可以通过牺牲VIPER纯粹来利用一些导航控制器的细节.Segues已经成为路由机制的一个步骤.查看VTDAddWireframe以了解UIViewControllerTransitioningDelegate
引入自定义动画的线框中的方法.也许这有帮助:
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
return [[VTDAddDismissalTransition alloc] init];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source
{
return [[VTDAddPresentationTransition alloc] init];
}
Run Code Online (Sandbox Code Playgroud)
我首先想到你需要保留一堆类似于导航堆栈的线框,并且所有"活动"模块的线框都相互链接.但事实并非如此.线框管理模块的内容,但导航堆栈是唯一代表哪个视图控制器可见的堆栈.
不同的模块是应该仅通过线框还是通过演示者之间的代表进行对话?
如果您直接向Presenter A发送另一个模块B的对象,那么会发生什么?
例如,由于接收者的视图不可见,因此动画无法启动.Presenter仍然需要等待线框/路由器.所以它必须将动画排入队列,直到它再次变为活动状态.这使得Presenter更具有状态,这使得它更难以使用.
在架构方面,考虑模块所扮演的角色.在Ports/Adapters架构中,Clean Architecture从中挖掘了一些概念,问题更加明显.作为类比:计算机有许多端口.USB端口无法与LAN端口通信.每个信息流都必须通过核心路由.
你的应用程序的核心是什么?
你有域模型吗?您是否有从各种模块查询的一组服务?VIPER模块围绕视图.与数据访问机制一样,stuff模块共享不属于特定模块.这就是你可以称之为核心的东西.在那里,您应该执行数据更改.如果另一个模块变为可见,则会提取已更改的数据.
但是,仅仅为了动画目的,让路由器知道该怎么做,并根据模块的变化向Presenter发出命令.
在VIPER Todo示例代码中:
谁应该保持当前所选引脚,MapViewController,MapPresenter或MapWireframe的状态,以便让我知道,当返回时,哪个引脚应该改变颜色?
没有.避免视图模块服务中的状态,以降低维护代码的成本.相反,尝试弄清楚是否可以在更改期间传递引脚变化的表示.
尝试达到实体以获得状态(通过Presenter和Interactor等等).
这并不意味着您Pin
在视图层中创建对象,将其从视图控制器传递到视图控制器,更改其属性,然后将其发送回以反映更改.一个NSDictionary
序列化的变化会吗?您可以将新颜色放在那里,然后将其从PinEditViewController
背面发送到Presenter,并在其中发布更改MapViewController
.
现在我被骗了:MapViewController
需要有国家.它需要知道所有引脚.然后我建议你传递一个改变字典,所以MapViewController
知道该怎么做.
但是,您如何识别受影响的引脚?
每个引脚都可能有自己的ID.也许这个ID只是它在地图上的位置.也许这是它在引脚阵列中的索引.在任何情况下你都需要某种标识符.或者您创建一个可识别的包装器对象,该对象在操作期间保持一个引脚本身.(但是,为了改变颜色,这听起来太荒谬了.)
VIPER非常基于服务.有许多大多数无状态对象绑在一起传递消息并转换数据.在Brigade Engineering的文章中,也展示了以数据为中心的方法.
实体处于相当薄的层.与频谱相反,我想到的是域模型.每个应用程序都不需要此模式.但是,以类似的方式对应用程序的核心进行建模可能有助于回答您的一些问题.
与实体作为数据容器相反,每个人都可以通过"数据管理器"到达,域保护其实体.域名也会主动通知变更.(通过NSNotificationCenter
,对于初学者.通过类似命令的直接消息调用.)
现在这也适用于你的Pin案例:
Pin
实体总是昙花一现,但它仍然是一个实体,因为它的身份很重要,而不仅仅是它的价值.)Pin
颜色已更改并通过发布通知NSNotificationCenter
.Pin
不知道),一些Interactor订阅这些通知并更改其视图的外观.虽然这也适用于您的情况,但我认为将编辑绑定
这个答案可能有点无关,但我把它放在这里供参考.Clean Swift网站是一个很好的实施,即鲍勃叔叔的" 清洁架构 ".所有者将其称为VIP(它仍然包含"实体"和路由器/线框).
该站点为您提供XCode模板.所以假设你要创建一个新场景(他称之为VIPER模块,"场景"),你所要做的就是File-> new-> sceneTemplate.
此模板创建一批7个文件,其中包含项目样板代码的所有问题.它还配置它们,使它们开箱即用.该网站提供了一个非常详尽的解释,说明每件事情如何融合在一
将所有锅炉板代码排除在外,找到解决方案,您上面提到的问题会更容易一些.此外,模板允许全面一致.
编辑 - >关于下面的评论,这里有一个解释为什么我支持这种方法 - > http://stringerstheory.net/the-clean-er-architecture-for-ios-apps/
还有这个 - > 好的,坏的,丑陋的关于iOS的VIPER
归档时间: |
|
查看次数: |
9900 次 |
最近记录: |