ios 从 OOP 到 POP 面向对象到面向协议

区分简单理解

  • 面向对象: 一我的 名字/年龄/跑/吃
  • 面向协议: 是一我的,能够有不少能力(协议)

面向对象

  • 传统的面向对象思惟方式:
    • 有一只狗,有本身的名字, 能够跑
    • 有一只猫,有本身的名字, 能够跑
    • 有一我的,有本身的名字, 能够跑
    • 抽象出一个动物类, 以后, 将跑的行为放入动物类中
    • 若是须要一个吃的行为, 也能够抽象在动物类中

  • Animal 做为基类,构建跑和吃的行为方法
class Animal: NSObject {
    func running() {
        print("跑")
    }
    
    func eating() {
        print("吃")
    }
}
复制代码
  • Dog 做为子类,调用父类的方法
    • Dog 做为子类 继承自父类
    • 子类中 子类重写父类的方法,父类指针指向子类。 多态
    • 同理 Cat、Person 也是这样的
  • 多态的三个条件
    • 继承:各类子类继承自父类
    • 重写:子类重写了父类的方法 eating()、running()
    • 指向:父类指针指向子类
class Dog : Animal{
    override func eating(){
        super.eating()
        print("狗在吃")
    }
    override func running(){
        super.running()
    }
}
复制代码
  • 面向对象开发弊端
    • 若是有一个机器人(一辆车), 也有跑的行为, 这个时候如何抽象呢, 显然该抽象方式并非特别合理
    • 显然car、robot不能继承自Animal由于他们不是animal 只能在抽取一个基类或者本身写本身的

class Car: NSObject {
    
    func running() {
        
    }
}

class Robot: NSObject {
    func running() {
        
    }
}
复制代码
  • 真实开发场景中
    • 对UIViewController/UITableViewController/UICollectionViewController抽象相同的方法
    • 因此你可能须要作 BaseViewController/BaseTableViewController/BaseCollectionViewController 三个控制器的基类(仍是很复杂)
    • 若是你要去别的项目复制部分功能时,有些要复制,有些又不要复制,抽取就比较麻烦了
  • 面向对象开发核心是: 封装-继承-(多态)

面向协议示例

  • Swift 标准库中有 50 多个复杂不一的协议,几乎全部的实际类型都是知足若干协议的
  • 面向协议开发核心是: 模块化(组件化)
  • 面向协议开发应用:
    • 粒子动画效果实现, 抽取在单独的协议中, 若是有控制器须要, 实现个人协议便可
    • 不少UIView会经过xib进行描述, 而咱们常常须要从一个xib中加载UIView, 抽取单独的协议, 须要从xib中加载类, 只须要遵照协议便可

简单示例

  • 当UIViewController/UITableViewController/UICollectionViewController 都须要一个Test方法时
  • 写一个Testable.swift
  • 给自定义的协议中添加extension,在extension中对可选方法进行默认实现,这样遵照协议的对象就能够不用实现可选方法.
  • 代码示例:
import Foundation

protocol Testable {
    //这里只能写声明 而且声明中不能作方法的实现不然报错
//    func demo() // 必须
	func test() // 可选
}
//要实现协议的实现必须作个扩展 extension 至关于OC的extinction 文件拓展同样的 swift就很方便了
extension Testable {
    func test() {
        print("对代码进行简单测试")
    }
}
复制代码

class OneViewController: UIViewController, Testable
class TwoViewController: UITableViewController, Testable
class ThreeViewController: UICollectionViewController, Testable
复制代码
  • 三个类各自遵照协议 在合适的位置写入方法就能够了

从新回到eating和running

  • 子类遵照协议实现方法就能够了
import Foundation


protocol Runable {
}


extension Runable {
    func running() {
        print("正在跑ing")
    }
}

import Foundation


protocol Eatable {
}

extension Eatable {
    func eating(){
        print("正在吃东西ing")
    }
}


class Cat: NSObject, Runable {
}
class Person: NSObject, Runable {

}
复制代码

面向协议的条件 只有当前的类是UIViewController 才能遵照协议

protocol Emitterable {
    
}
extension Emitterable where Self : UIViewController
复制代码

网络请求(使用面向协议方式进行开发)

protocol Requestable {
    var method : HttpMethod { get }
    var host : String { get }
    var path : String { get }
    var parameters : [String : Any] { get }

    associatedtype ResultType : Decodable
}

extension Requestable {
    func request(completion : @escaping (ResultType?) -> Void) {
        // 1.建立URL
        let url = URL(string: host + path)!

        // 2.建立request对象
        let request = URLRequest(url: url)

        // 3.经过URLSession发送请求
        let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, _, error) in
            completion(ResultType.parse(data!))
        })

        // 4.发起请求
        task.resume()
    }
}

protocol Decodable {
    static func parse(_ data : Data) -> Self?
}
复制代码
相关文章
相关标签/搜索