博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于“幽灵架构”的总结:适用场景与方法重载
阅读量:6785 次
发布时间:2019-06-26

本文共 2959 字,大约阅读时间需要 9 分钟。

前几篇博文对“幽灵架构”做了用法的介绍和相关技术点的补充,本文是一篇总结性质的文章,分析该架构的适用场景和限制,首先让我们回顾一下iOS开发的MVC模式,参考斯坦福公开课里Paul老爷子的讲解,如下图所示:

这里写图片描述
在MVC模式下Model和View是不能直接通信的,在“幽灵架构”体系中Model和View依旧不能直接通信,在传统的MVC中,这种通信的阻隔很多时候是因为在没有得到Model和View实体的情况下无法完成二者的数据绑定,在过去你可能想过在View中写一个方法来接受一个模型,然后写具体的实现,在没有泛型的帮助下只能用方法的重载来做,没有协议扩展的情况下需要在父类和写重复的代码中做选择。
在“幽灵架构”体系中,通过ModelType和ViewType可以在不借助控制器的帮助下实现二者的逻辑绑定,依旧是使用了方法传值的用法,Controller起到了“开关”的作用,依靠泛型和协议对数据类型进行了约束,并且避免了重复代码,不需要在意数据源的同构和异构。
我们需要在Controller中创建Model和View的实例,并且和MVC一样可以对Model和View做处理,但是Model和View之间的逻辑关系是定义在View的getData中的,比如Demo中Event的Cell会被标注为红色,如果要通过修改Controller的标志位来影响Model和View之间的逻辑,比如Demo中在Controller中加入一个开关,点击后会互换Event和Festival的背景色,这就属于Controller中引入了标志位来影响View和Model的逻辑,此时如果要继续维持“幽灵架构”的体系,那么需要重载giveData和getData方法,传入Controller中的标志位。首先给getData增加默认实现,因为在View的代码中我们只想重写需要的重载的方法:

//视图使用的协议protocol ViewType{    func getData
(model:M)}//数据使用的协议protocol ModelType{}//定义默认方法giveDataextension ModelType{ func giveData
(view:V){ view.getData(self) }}extension ViewType{ func getData
(model:M){ }}

为了维持“幽灵架构”的灵活性,我们重写了giveData和getData,不是在具体的遵守者中重写,而是直接扩展协议:

extension ModelType where Self:HasDate{    func giveData
(view:V,tag:Bool){ if let tableCell = view as? ShowedTableViewCell{ tableCell.getData(self,tag:tag) } }}extension ViewType where Self:ShowedTableViewCell{ func getData
(model: M,tag:Bool){ }}

现在不需要修改所有的Model,但是需要在View中重写新定义的方法:

func getData
(model: M,tag:Bool) { //这里不能写成guard let dateModel = model as? DateViewModel else{}令我有些意外 guard let dateModel = model as? HasDate else{ return } //处理相同属性 dateLabel.text = dateModel.date //处理数据源异构 if let event = dateModel as? Event{ MixLabel.text = event.eventTitle backgroundColor = tag ? UIColor.redColor():UIColor.whiteColor() } else if let festival = dateModel as? Festival{ MixLabel.text = festival.festivalName backgroundColor = !tag ? UIColor.redColor():UIColor.whiteColor() } }

这是协议扩展的另一个神奇之处:不会引入多余的状态,避免了“上帝类”的出现,如果你的工程中有其他的Model和View的绑定,不会受到任何影响。最后一步,修改Controller中的数据绑定:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCellWithIdentifier(cellReusedID, forIndexPath: indexPath) as! ShowedTableViewCell        //调用重载的方法        dataList[indexPath.row].giveData(cell,tag:true)        return cell    }

现在尝试向tag传入true和false看看效果吧:

这里写图片描述
tag传入false
这里写图片描述
tag的值取决于Controller,从上面的例子中看出在Controller中切换View和Model的绑定逻辑是完全没问题的。之前讲过giveData方法是为了在异构数据源中避免Box类型的出现,提高运行效率,针对同构的数据源,我们只需要重载getData并在控制器中直接使用getData对数据进行捆绑就好了。
所以,我之所以在最初的文章中称“幽灵架构”为MV,其实并没有弱化控制器的职责,但是把控制器中有关于模型和视图逻辑绑定的代码移到了View中,并且集中在了getData一个方法中,便于维护,为控制器减压,所以其实这是一个“伪架构”。从上面的示例中可以看到,MVC和MVVM能做到的“幽灵架构”一样能做到,并且比MVC中控制器的代码更好维护,比MVVM少写了很多代码。“幽灵架构”今后的发展,需要经历时间的考验了。

你可能感兴趣的文章
Java与Highcharts实例(四) - Hello Highcharts (后台Java传递数
查看>>
连接数据库的操作 总结
查看>>
Android 小米手机开发APP图标更换后还显示原来的图标
查看>>
在代码中修改Shape的solid属性的color值
查看>>
MySQL字符集问题
查看>>
Java多线程总结
查看>>
iPad Mini外屏碎了 换屏幕教程
查看>>
LinkedBlockingQueue操作,线程安全问题,ConcurrentModificationException 异常分析与解决方案...
查看>>
redis3.2新功能--GEO地理位置命令介绍与实战开发
查看>>
java 通过ssh 执行命令
查看>>
算法导论——基数排序(基于计数排序)
查看>>
19.TCP的交互数据流
查看>>
字符串匹配的Boyer-Moore算法
查看>>
memcached数据库未授权访问漏洞解决
查看>>
centos 7 安装在vmware Workstation的网卡问题 RHEL7
查看>>
嵌入式开发平台-iTOP-4418开发板
查看>>
我的友情链接
查看>>
ssh配置公钥私钥(key)登录SecureCRT
查看>>
go 字符串长度为空的判断 效率
查看>>
openstack安装(liberty)--安装认证服务(Identity service)
查看>>