您的位置:首页 > 运维架构 > 网站架构

关于“幽灵架构”的补充说明5:改造控制器

2016-05-12 23:24 441 查看
Swift中的泛型有非常多的用处,除了我在之前介绍的方法中作为占位符之外,还可以被用在协议中,构成一个泛型协议,那么遵守这个泛型协议的成员就会变成泛型成员。还用我们之前的事件节日提醒Demo来展示,在之前的版本中我们使用了一个TableView来展示数据,现在如果有新的需求,需要在CollectonView中做类似的排列,并且针对数据源提供日期的筛选功能,面对相似的功能需求显然你不想写两份代码,那么此时最好的办法就是提炼出一个协议来,并且在协议扩展中声明一份默认的实现。

让我们来实现第一步:分析需求,提炼协议的组成,在上面的情景中,我们想要一个日期的筛选,所以需要定义一个方法,而筛选是针对数据源的,也就是我们之前的Demo中使用的数组dataList

第二步:定义这个协议,格式如下:

protocol FestivalsAndEventsTool{
var dataList:[DateViewModel]{get set}
func search(date:String) -> [DateViewModel]
}


第三步,在协议扩展中声明默认实现,这个默认实现需要是符合绝大多数情况的实现,这样可以我们在遵守协议的时候可以免费获得这个实现,避免多余的代码,注意这一步不是必须的,但是确实可以显著地提升代码的复用:

extension FestivalsAndEventsTool{
func search(date:String) -> [DateViewModel]{
return dataList.filter{
$0.date == date
}
}
}


现在回到TableViewController的子类中,只需要遵守协议,就可以获得数据筛选的方法:

class ShowedTableViewController: UITableViewController, FestivalsAndEventsTool


如果还需要在一个CollectionViewController展示事件和节日的话,只需让CollectionViewController也遵守FestivalsAndEventsTool即可,然后在代码的合适位置调用search方法。

下面来聊聊泛型控制器,我们的数组源是异构的,因为数组成员是协议类型,如果你希望协议的数据源依旧保持多样性,但是每个控制器的数据源是同构的,那么可以使用associatedtype 关键字声明一个泛型协议:

protocol FestivalsAndEventsTool{
associatedtype Model:DateViewModel
var dataList:[Model]{get set}
func search(date:String) -> [Model]
}

extension FestivalsAndEventsTool{
func search(date:String) -> [Model]{
return dataList.filter{
$0.date == date
}
}
}


使用associatedtype声明的Model也是一个占位符,你可以给这个占位符加一些约束,比如上例中我们需要Model必须遵守DateViewModel协议。在遵守者的代码中不用显示地声明Model的类型,编译器会根据每一个Model实际传入的类型确定Model的实际类型,如果你把协议声明成了上面的格式,那么之前的TableViewController会报错,因为我们的dataList是[DateViewModel]类型的,如果你把dataList修改成[Event]或者[Festival]之后,编译通过了。泛型协议保障了我们的数据安全和一致性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: