关于“幽灵架构”的补充说明1:协议中的方法定义

简介: 承接上一篇博文,上一篇的篇幅有点太长了,我觉得有一些相关的技术点需要说明,所以重新写几篇博文。

承接上一篇博文,上一篇的篇幅有点太长了,我觉得有一些相关的技术点需要说明,所以重新写几篇博文。这个系列的文章将要说明以下几个问题:
1.giveData和getData在各自协议中的位置
2.使用struct代替class的好处
3.“幽灵架构”为什么不会产生循环引用
4.协议的应用场景与局限性
5.运用面向协议编程思想改造控制器
让我们来简单回顾下这个架构,如果不明白的可以参考上一篇博文:
核心只有两个协议:

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

首先来回答第一个问题,为什么getData被定义在协议ViewType的定义中,只有函数声明没有实现,而giveData被定义在ModelType的扩展中,并且附带了方法的具体实现。请看下面的例子:

protocol SharedString{
}

extension SharedString{
    func methodForOverride(){
        print("(。•ˇ‸ˇ•。)")
    }

    func methodWithoutOverride(){
        print("------")
        methodForOverride()
        print("------")
    }
}

两个方法都被定义在了协议的扩展中,现在让String遵守该协议,String将免费获得这两个方法的实现,并且在String的扩展中重写methodForOverride()的实现,输出String本身的值:

extension String:SharedString{
    func methodForOverride(){
        print(self)
    }
}

现在使用字面量生成一个String类型,然后调用方法methodForOverride:

"hello".methodForOverride()

输出的结果是“Hello”,这符合我们的预期,这里使用字面量生成了一个实例,依靠了类型推断的默认值,“Hello”是Sting类型的,也就是SharedString的具体遵守者,所以调用了被重写的methodForOverride版本。Swift中的方法重载不仅可以根据参数进行重载,还可以根据返回值类型进行重载,只需要修改返回值的声明即可。这里我们修改“hello”的上下文:

//用一个字面量来跟大家打个招呼
"hello".methodForOverride()
//hello是SharedString类型的
let hello:SharedString = "hello"
hello.methodForOverride()

hello是SharedString类型的,虽然hello和“hello”的字面量是相同的,打印结果如下:
这里写图片描述
有趣的是在协议的扩展中声明的方法定义会被保留,更有趣的是另一个方法methodWithoutOverride(),这个方法在方法体中调用了另一个方法methodForOverride,现在对“hello”和hello调用方法methodWithoutOverride:

"hello".methodWithoutOverride()
hello.methodWithoutOverride()

结果如下:
这里写图片描述
结果有点出乎意料,虽然我们在协议遵守者的定义中重写了方法methodForOverride,定义在协议扩展中的另一个方法只会使用methodForOverride的默认版本的实现,这是协议扩展的静态特性。现在把methodForOverride的声明从协议的扩展中挪到协议的声明中:

protocol SharedString{
    func methodForOverride()
}

extension SharedString{
    func methodForOverride(){
        print("(。•ˇ‸ˇ•。)")
    }

    func methodWithoutOverride(){
        print("------")
        methodForOverride()
        print("------")
    }
}

现在无论你使用“hello”还是hello调用methodForOverride()和methodWithoutOverride()都只会输出重写后的结果。
结论:把需要被重写的方法声明在协议的声明中是一种刻意的做法,我们希望该方法被重写,回到架构上,getData负责不同的View处理获得的Model,View的类型非常多,所以getData的格式无法统一到一个默认的方法实现中,我们需要getData被具体的View所重写,为了强制这种意图,getData甚至没有一个默认的实现方法体。根据Swift的协议规则,协议遵守者需要实现协议中的所有方法,所以getData一定会有具体声明。而前文也总结过,对于ModelType中的giveData这个方法的功能非常统一,即向View传递Model,所以统一到同一个方法实现中,并且我们不希望这个方法被重写,因为重写会破坏getData中的逻辑,所以把方法声明写在了协议的扩展中。
最后需要说明的是“幽灵架构”这个名字只是想表达代码隐形的愉悦,其实名字本身并不重要。

目录
相关文章
|
1月前
|
前端开发 JavaScript
掌握微前端架构:构建现代Web应用的新方法
本文介绍了微前端架构的概念及其在现代Web应用开发中的优势与实施方法。微前端架构通过将应用拆分成独立模块,提升了开发效率和灵活性。其核心优势包括技术栈灵活性、独立部署、团队协作及易于维护。文章详细阐述了定义边界、选择框架、管理状态和通信等关键步骤,并讨论了状态同步、样式隔离及安全性等挑战。微前端架构有望成为未来Web开发的重要趋势。
|
3月前
|
边缘计算 物联网 5G
软件定义网络(SDN)的未来趋势:重塑网络架构,引领技术创新
【8月更文挑战第20天】软件定义网络(SDN)作为新兴的网络技术,正在逐步重塑网络架构,引领技术创新。随着5G、人工智能、边缘计算等技术的不断发展,SDN将展现出更加广阔的应用前景和市场潜力。未来,SDN有望成为主流网络技术,并在各行各业推动数字化转型。让我们共同期待SDN技术带来的更加智能、安全和高效的网络体验。
用户态协议栈05—架构优化
用户态协议栈05—架构优化
|
4月前
业务架构问题之什么是自上而下和自下而上的设计方法
业务架构问题之什么是自上而下和自下而上的设计方法
147 18
|
3月前
|
设计模式
软件设计与架构复杂度问题之认知负荷的定义如何解决
软件设计与架构复杂度问题之认知负荷的定义如何解决
|
3月前
|
开发者
软件设计与架构复杂度问题之McCabe圈复杂度的定义如何解决
软件设计与架构复杂度问题之McCabe圈复杂度的定义如何解决
|
3月前
|
NoSQL Serverless 数据库连接
Serverless 架构实现弹幕场景问题之initializer方法在执行过程中遇到错误如何解决
Serverless 架构实现弹幕场景问题之initializer方法在执行过程中遇到错误如何解决
35 0
|
3月前
|
存储 Serverless API
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
25 0
|
3月前
|
Android开发
Android项目架构设计问题之onFirstItemVisibleChanged方法的调用如何解决
Android项目架构设计问题之onFirstItemVisibleChanged方法的调用如何解决
38 0
|
3月前
|
Java 测试技术 Android开发
Android项目架构设计问题之使用反射调用类的私有方法如何解决
Android项目架构设计问题之使用反射调用类的私有方法如何解决
25 0

热门文章

最新文章