POP (protocol Oriented Programing POP) 面向协议编程
OOP (Object Oriented Programing) 面向对象编程
OOP的优点
1)封装和权限控制
OC
:.h文件负责声明公共变量和方法,.m 文件负责声明私有变量, 并实现所有方法。
Swift
:也有public、internal、fileprivate、private 等权限控制;
2)命名空间
Swift
:不同的class即使命名相同, 在不同的bundle中, 由于命名空间不同,它们依然可以和谐共存,毫无冲突;在App体积很大的时候,bundle很多时候,这一点特别有用;
OC
: 没有命名空间, 所以很多类在命名的时候都加入了“驼峰式”的前缀;
3)扩展性:
Swift
:可以通过extension 来增加新方法, 通过动态特性亦可以增加变量, —— 可以保证在不破坏原来代码封装的情况下实现新的方法。
OC
:可以使用category实现类似功能;
在Swift和OC中, 还可以通过protocol 和代理模式实现更加灵活的扩展
4)继承和多态
同其他语言一样, 在iOS中,可将公共的方法和变量定义在父类中,在子类继承时再各自实现对应的功能,高效实现代码复用,针对不同的子类,从而大大增加代码的灵活性;
OOP 缺点
1)隐式共享
class 是引用类型, 当在代码中的某处改变某个实例变量时, 另一次在调用此变量时就会受此修改的影响;
很容易造成异常, 尤其是在多线程上, 我们经常会遇到资源竞选(Race condition) 就属于这种情况。
解决多线程时枷锁, 加锁有可能会引起死锁或者代码复杂度剧增。 解决这个问题最好的方案是诸如struct这样的值类型取代class
2)冗余的父类
eg: UIViewController 需要加入一个handleSomethiing() 方法, OOP的是在其extension直接添加这个方法,随着新方法越来越多, 导致UIViewController越来越冗余, 随着新方法越来越多, 导致职权不明确、依赖、冗杂等多种问题。
3)多继承
swift 和OC都不支持多继承, 因为他会造成“菱形”问题,
即为:多个父类实现了同一个方法,子类无法判断继承哪个父类的情况。 C++ 就会有这种情况, 使用了抽象类的实现方式确定继承方法;
在Java中, 有interface的解决方案, 在Swfit有类似的protocol
为什么Swift 要推出全新的POP?
1)OOP自身的缺点, 在继承和代码复用等方面, 其灵活度不高, POP恰好可以解决这个问题;
2)POP可以保证Swfit作为 静态语言的安全性, 而OC时代的OOP, 其动态特性经常会导致异常
3)OOP无法应用于值类型, 而POP可以将其优势扩展到结构体(struct)和枚举(enum)类型中;
OOP优点
1)更加灵活
:上面的handleSomething方法, 通过服从协议的同时, 增加了代码的可读性;
2)减少依赖
:相对于传入具体的实例变量,可以传入protocol来实现多态,同时,在测试也可以利用protocol 来模拟真实的实例,减少对对象以及其它实现的依赖
3)消除动态分发的风险
POP面试题
: 要给一个UIButton增加一个点击后抖动的 效果,应该怎么实现?
三种方案
:
1)方案一
:实现一个自定义的UIButton类, 在其中添加点击抖动效果的方法【shake方法】;
2)方案二
:写一个UIButton的Extension, 然后在其中增加share方法
3)方案三
:定义一个protocol,然后将协议扩展protocol extension中添加shake方法
分析:
1)性能扩展性不好, 复用性不好
2)可读性很差, 因为不是每个人都知道有这个方法
3)解决了复用性、可读性、维护性 这个三个难题。
本文由mdnice多平台发布