六大设计原则:

一、单一职责原则

一个类或者模块只负责完成一个职责或者功能。

类似于:UIView 和 CALayer

二、开放封闭原则

对扩展开放,对修改封闭。

我们要尽量通过扩展软件实体来解决需求变化,而不是通过修改已有的代码来完成变化。

三、里氏替换原则

子承父类,子类应该满足父类所期望、规定的。

在继承体系中,子类中可以增加自己特有的方法,也可以实现父类的抽象方法,但是不能重写父类的非抽象方法,否则该继承关系就不是一个正确的继承关系。

四、接口隔离原则

一个类对另一个类的依赖应该建立在最小的接口之上。

单一职责原则注重的是职责,接口隔离原则注重的是对接口依赖的隔离。将某些方法单独隔离出来,进行单独封装接口处理,实现隔离。

五、依赖倒置原则

抽象不依赖于细节,细节依赖于抽象。

接口的封装,调用接口不关心内部的实现。

六、最小知识原则

一个对象应当对其他对象尽可能少的了解,实现高聚合、低耦合。

另外:

制定这六个原则的目的并不是要我们刻板的遵守他们,而需要根据实际情况灵活运用。对他们的遵守程度只要在一个合理的范围内,就算是良好的设计。

三大设计模式(工厂模式):

一、简单工厂模式

一个厂生产多个产品。

优:

  1. 根据约定好的参数就可以获取所需要的对象,而不需要知道其创建的细节。减少了系统的耦合度。
  2. 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,减少开发者的记忆成本。

缺:

  1. 如果业务上添加新产品的话,就需要修改工厂类原有的判断逻辑,这其实是违背了开闭原则的。
  2. 在产品类型较多时,有可能造成工厂逻辑过于复杂。所以简单工厂模式比较适合产品种类比较少而且增多的概率很低的情况。

demo:

import UIKit

// 产品协议
protocol ViewControllerProtocol {
    func showMessage()
}

// 具体产品
class HomeViewController: UIViewController, ViewControllerProtocol {
    func showMessage() {
        print("Home Screen")
    }
}

class SettingsViewController: UIViewController, ViewControllerProtocol {
    func showMessage() {
        print("Settings Screen")
    }
}

// 简单工厂
class ViewControllerFactory {
    enum ViewControllerType {
        case home
        case settings
    }
    //static让该方法成为类方法,而不是实例方法。便于直接通过类调用,而不需要实例化工厂对象
    static func createViewController(type: ViewControllerType) -> ViewControllerProtocol {
        switch type {
        case .home:
            return HomeViewController()
        case .settings:
            return SettingsViewController()
        }
    }
}

// 使用工厂创建对象
let homeVC = ViewControllerFactory.createViewController(type: .home)
homeVC.showMessage() // 输出:Home Screen

二、工厂方法模式

工厂父类负责定义创建产品对象的公共接口(工厂抽象类),而工厂子类则负责生成具体的产品对象,即通过不同的工厂子类来创建不同的产品对象(可乐抽象类)。

简单来说:工厂方法是在简单工厂的基础上扩展的,简单工厂是由一个代工厂生产不同的产品,而工厂方法是对工厂进行抽象化,不同产品都由专门的具体工厂来生产。可口可乐工厂专门生产可口可乐,百事可乐工厂专门生产百事可乐。
即:多个工厂对应多个品牌厂商进行一对一生产

优:

  1. 根据所需产品找对应工厂进行生产,不关心产品细节,也不需要知道产品类的类名。
  2. 当系统中加入新产品时,不需要修改抽象工厂和抽象产品提供的接口,也无须修改客户端和其他的具体工厂和具体产品,而只要添加一个具体工厂和与其对应的具体产品就可以了,符合了开闭原则。

缺:

  1. 当系统中加入新产品时,除了需要提供新的产品类之外,还要提供与其对应的具体工厂类。因此系统中类的个数将成对增加,增加了系统的复杂度。

demo:

import UIKit

// 产品协议
protocol ModuleViewController {
    func display()
}

// 具体产品
class ProfileViewController: UIViewController, ModuleViewController {
    func display() {
        print("Profile Module")
    }
}

class DashboardViewController: UIViewController, ModuleViewController {
    func display() {
        print("Dashboard Module")
    }
}

// 工厂协议
protocol ModuleFactory {
    func createViewController() -> ModuleViewController
}

// 具体工厂
class ProfileFactory: ModuleFactory {
    func createViewController() -> ModuleViewController {
        return ProfileViewController()
    }
}

class DashboardFactory: ModuleFactory {
    func createViewController() -> ModuleViewController {
        return DashboardViewController()
    }
}

// 使用工厂方法
let profileFactory = ProfileFactory()
let profileVC = profileFactory.createViewController()
profileVC.display() // 输出:Profile Module

let dashboardFactory = DashboardFactory()
let dashboardVC = dashboardFactory.createViewController()
dashboardVC.display() // 输出:Dashboard Module

三、抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。

简单来说:抽象工厂模式是在工厂方法模式的基础上扩展了,工厂方法是一个厂只能生产一种产品,而抽象工厂是一个厂就是一个品牌,这是通过提供一系列接口导致的。

优点:

  1. 不需要生产产品细节,只需要知道产品属于那个工厂就行,当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
  2. 让你感觉不到内部差异性(cocoa框架里到处都是使用了这种设计,比如NSString、NSNumber)。

缺:

  1. 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。

demo:

import UIKit

// 抽象产品
protocol Button {
    func render()
}

protocol TextField {
    func render()
}

// 具体产品
class iOSButton: Button {
    func render() {
        print("Render iOS Button")
    }
}

class AndroidButton: Button {
    func render() {
        print("Render Android Button")
    }
}

class iOSTextField: TextField {
    func render() {
        print("Render iOS TextField")
    }
}

class AndroidTextField: TextField {
    func render() {
        print("Render Android TextField")
    }
}

// 抽象工厂
protocol UIComponentFactory {
    func createButton() -> Button
    func createTextField() -> TextField
}

// 具体工厂
class iOSFactory: UIComponentFactory {
    func createButton() -> Button {
        return iOSButton()
    }
    func createTextField() -> TextField {
        return iOSTextField()
    }
}

class AndroidFactory: UIComponentFactory {
    func createButton() -> Button {
        return AndroidButton()
    }
    func createTextField() -> TextField {
        return AndroidTextField()
    }
}

// 使用抽象工厂
let factory: UIComponentFactory = iOSFactory()
let button = factory.createButton()
let textField = factory.createTextField()

button.render()    // 输出:Render iOS Button
textField.render() // 输出:Render iOS TextField

参考:【iOS】—— 六大原则和工厂模式_工厂模式6大原则是什么-CSDN博客

iOS常见的设计模式:工厂设计模式_ios常用的设计模式-CSDN博客

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐