阅读更多

1顶
0踩

移动开发
本文出自:owensd.io,译文出自:SwiftGG

最近Swift的热点都围绕在协议上,他们觉得任何东西都应该是协议。理论上这挺好,但是事实上,这种观点会产生一些副作用。

我在代码中使用协议时,总是牢记下面两条规则:

1.不要把协议当成类型
我看到的(和我一开始写的)许多方法都是在继承关系里把协议当成一个基类。我不认为这是协议的正确用法,这种设计模式仍然停留在“面向对象”的思维方式上。

换句话说,假如你的协议只在继承关系里有意义,那就应该扪心自问是否真的有必要使用协议。我不赞同这种说法:“我的类型是结构体,所以我需要用协议来代替。”如果真的需要这样,那就重构它,把它变得更通用。

进一步的验证可见:http://swiftdoc.org/swift-2/。需要关注所有那些协议(不以 _ 开头的协议)吗?所有的协议都能适用不同的类型,不管是不是类型继承。

2. 不要把协议泛型化,除非你必须这么做!
这并不是一个小问题,一旦你把协议泛型化,就无法再使用包含不同协议实例的类型集合。我认为这是严重的设计缺陷。比如说,无论在哪里使用协议,协议中所有不受Self限制的功能都应该保证调用安全。

这条规则同样适用于遵守泛型协议的协议,比如Equatable,泛型会传染。

下面这行代码就是典型的例子:
protocol Foo : Equatable {}  

来个实际点的例子吧:

我们想要对HTTP response建模,并且想要支持两种不同的response类型:String和JSON。

你可能会这样写:
class HTTPResponse<ResponseType> {
    var response: ResponseType
    init(response: ResponseType) { self.response = response }
}

我认为这样写不好。一旦这样写,我们就人为地限制了使用这个类型的能力;比如,这不能在复杂情况下的集合里使用。现在,为什么我想要在集合里使用不同的ResponseType?假设,我想要构建一个 response/request的测试工具。返回response的集合里需要有我支持的类型:String和JSON。

使用AnyObject是个不错的做法。虽然可行,但是真的很操蛋。

另一种方法是使用协议。然而,除了构建ResponseType协议之外,让我们想想真正想要什么。我真正关心的是,HTTPResponse接收到的ResponseType都能表示成String。

揣着这样的想法,我写出这样的代码:
protocol StringRepresentable {
    var stringRepresentation: String { get }
}
class HTTPResponse {
    var response: StringRepresentable
    init(response: StringRepresentable) { self.response = response }
}

对我而言,这为API使用者提供了极大的方便,也维持了类型的明确性。当然,这样做是有弊端的。假如你真的需要为response使用特定的类型,那么就需要进行类型转换。
class JSONResponse : StringRepresentable {
    var stringRepresentation: String = "{}"
}
let http = HTTPResponse(response: JSONResponse())
let json = http.response as? JSONResponse

引用

这个方法明显更好。调用者知道可能的返回类型或返回值。这明显与遍历整个集合取出返回值是不同的,因为,代码的使用者可能使用的是其他的返回类型,比如 XMLResponse ,而我们的代码不可能知道这个。

最好是这样写:
class HTTPResponse<ResponseType : StringRepresentable> {
    var response: ResponseType
}
<span style="font-family: Helvetica, ​Tahoma, ​Arial, ​sans-serif; font-size: 14px; white-space: normal; background-color: initial;">let responses = [json, string] &nbsp;//responses变量是以HTTPResponse为元素的数组,元素中的ResponseType是未指定的。</span>

如果要用集合,你还是需要强制转换response的类型,不过现在你可以直接用JSON实例来验证类型。

反正我是每次都用[HTTPResponse]类型的集合,而不是[AnyObject]。

本文出自:owensd.io,译文出自:SwiftGG
来自: SwiftGG
1
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • Grails与Maven集成

    本文主要介绍Grails和Maven集成。Grails2.1版本以后,对Maven的集成有了很大的改进。本文通过实例讲述Grails与Maven集成的各种方法,使读者可以学会使用Maven对Grails项目进行构建。Grails简介:Grails是一个开源的...

  • grails新增的screencasts

    http://grails.codehaus.org/Grails+Screencasts

  • grails-core:Grails Web应用程序框架

    设置GRAILS_HOME环境变量以指向提取的下载文件的根目录,并将GRAILS_HOME/bin添加到您的可执行文件PATH 。 然后在外壳中,键入以下内容: grails create-app sampleapp cd sampleapp grails run-app 要构建Grails...

  • 精通Grails:创建自定义插件

    本文内容包括:ShortenUrl插件简介创建TinyUrl类测试TinyUrl类创建IsGd类创建ShortenUrl服务打包并部署插件结束语下载参考资料在这个“精通Grails”系列中,ScottDavis将向您展示如何创建您自己的Grails插件。...

  • grails.2.5.1 环境

    grails.2.5.1 环境,适用于Windows下Grails开发,具体配置请参照https://jingyan.baidu.com/article/86fae3461af6cf3c49121a91.html

  • Grails开源框架 - 使用指南

    Grails开源框架 - 使用指南,版本1.0,中文文档。 Grails开源框架 - 使用指南 作者: Graeme Rocher, Marc Palmer 版本: 1.0 Copies of this document may be made for your own use and for distribution to ...

  • grails-3.3.9

    Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring、Hibernate等开源框架之上,是一个高生产力一站式框架。 Grails这个独特的框架被视为是提升工程师生产效率的动态工具,因为其...

  • grails-4.0.3.rar

    Grails 4 ships with the following dependency upgrades: Groovy 2.5.6 GORM 7 and Hibernate 5.4 (now the default version of Hibernate for new applications) Spring Framework 5.1.5 Spring Boot 2.1.3 ...

  • grails-2.3.6.zip

    grails-2.3.6

  • grails-2.5.6

    Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring、Hibernate等开源框架之上,是一个高生产力一站式框架。 Grails这个独特的框架被视为是提升工程师生产效率的动态工具,因为其...

  • grails-2.4.4

    这是Grais2.4.4版本的SDK,最适合他用的工具是IDEA,Grails是一款一站式开发平台

  • Grails模块架构图.JPG

    Grails模块架构图

  • Grails案例

    实现了基本的增删查改等功能

  • grails-4.0.4.zip

    grails-4.0.4.zip

  • eclipse开发grails插件

    eclipse插件、用来开发grails(路漫漫其修远兮、吾将上下而求索)

  • grails-2.4.2开发包

    Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring、Hibernate等开源框架之上,是一个高生产力一站式框架。

  • 基于Django花卉商城系统的设计与实现-2885fb37-.zip

    基于Django花卉商城系统的设计与实现_2885fb37--.zip

  • 102页-智慧农业解决方案.pdf

    智慧农业,作为现代农业的新篇章,正引领着农业生产的革命性变革。本解决方案以物联网、云计算、大数据等先进技术为核心,为农业生产打造了一套全面、智能的管理系统。 想象一下,从温室大棚到广袤田野,智能传感器遍布每个角落,它们能实时感知空气温湿度、土壤水分、光照强度等环境参数,仿佛为农作物装上了“眼睛”和“耳朵”。这些数据通过物联网技术传输到云端,经过大数据分析,为农民提供精准的种植建议,如何时灌溉、施肥、防虫,让农业生产变得更加科学、高效。 更有趣的是,通过智慧农业平台,农民可以远程监控作物生长情况,甚至用手机就能控制温室大棚的遮阳板、通风设备等,实现“指尖上的农业”。此外,方案还包含了农产品可追溯系统,从田间到餐桌,每一步都可追溯,让消费者吃得放心。而智慧农业电商平台,则让农产品销售更加便捷,农民直接对接市场,收益倍增。 总之,这套智慧农业解决方案不仅让农业生产变得更加智能、高效,还提升了农产品的质量和安全,为农民带来了实实在在的收益,开启了农业现代化的新篇章。 对于想要投身智慧农业领域的你来说,这不仅仅是一套解决方案,更是一把开启现代农业大门的钥匙,引领你走向更加辉煌的未来。

  • 【人工智能模型部署】DeepSeek本地部署与WebUI可视化:环境搭建、模型启动及界面开发指南文档的主要内容

    内容概要:本文档详细介绍了DeepSeek本地部署与WebUI可视化的一般步骤。本地部署方面,涵盖了环境准备(硬件要求如多核CPU、8GB以上内存或带适当显存的NVIDIA GPU,软件环境涵盖操作系统如Ubuntu 20.04及以上版本、Python环境及依赖库如PyTorch或TensorFlow)、获取DeepSeek模型代码和权重(通过官方仓库克隆代码,从指定渠道下载权重)、模型配置与启动(配置模型参数,运行启动脚本以初始化模型和服务)。WebUI可视化部分则推荐了Streamlit和Gradio两种框架,介绍了它们的安装、使用方法(通过编写脚本调用DeepSeek API构建交互界面),以及集成与部署(确保WebUI与模型服务之间的数据正确传递,在本地运行后可通过浏览器访问)。 适合人群:对深度学习模型部署有一定了解的技术人员,尤其是那些希望将DeepSeek模型应用于本地环境并提供用户友好界面的研发人员。 使用场景及目标:①为希望在本地环境中运行DeepSeek模型的研究者或开发者提供详细的部署指南;②帮助用户快速搭建一个带有图形化操作界面的DeepSeek应用,降低使用门槛,提高用户体验。 阅读建议:在阅读时,应根据自己的操作系统环境和硬件条件调整相应的配置要求,同时注意按照官方文档的具体指引操作,确保各组件版本兼容,以便顺利完成部署和可视化工作。

Global site tag (gtag.js) - Google Analytics