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

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]之后,编译通过了。泛型协议保障了我们的数据安全和一致性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值