Skip to content

SOLID原则解析与实战

目标

  • 软件系统的价值&架构工作的目标
  • 了解编程范式的定义
  • 掌握基础的设计原则-SOLID原则

硬实力 软实力 => 更长远 架构师

软件系统的价值&架构工作的目标

  • 结构是系统的一部分
    • 行为价值 核心价值 90% 工作内容

    • 架构价值

      • 当需求迭代时,软件变更更加便捷,开发效率更高

      业务 => 技术

前端团队 10人:leader(1) > 架构师(2) > 开发(7)

紧张重要矩阵: 紧急 ↑ | 3.不重要且紧急 | 1.重要且紧急 | —————————————|—————————————→ 重要 | 4.不重要且不紧急| 2.重要且不紧急 | |

架构的目标

服务于开发

目标:用最少的人力成本满足构建和维护系统需求 支撑软件系统的声明周期 让系统便于理解 易于修改 方便维护 轻松部署

开发阶段:CLI产出、组件库、基础依赖 => 提高开发效率 部署阶段:CI/ID(持续集成/持续部署) 预发 线上 运行阶段:稳定性 容灾演练 安全攻防 灰度(少部分用户或者测试人员使用) 压测 AB(双版本) 维护阶段:告警监控 1、5、10规则(1min识别并记录、5min通知、10min做出响应)

编程范式

上层限制:

架构的限制 => 组件库 vue/react/cli 基础依赖

底层限制:

  • 结构化编程 - 控制权直接转移 1968
  • 面向对象编程 - 控制权间接转移 1966
  • 函数式编程 - 限制赋值 1936

结构化编程

对控制权专一进行限制

  1. 顺序结构 分支结构 循环结构 => 搭建任何一个程序 限制goto(去执行别的程序)的使用,因为goto紊乱了结构导致不可控

  2. test case test() expect test case: all pass

总结:赋予可证伪程序单元的能力

面向对象编程

封装 继承 多态

在非面向对象的编程语言中 函数指针

c
struct FILE{
  void (*open)(char* name,int mode);
  void (*close)();
  int (*read)();
}

面向对象限制了函数指针的使用

函数式编程

函数保持独立,没有副作用和不修改状态

React props

设计原则

SOLID 面向对象设计的五条原则(Bob 2000):

  • S:单一职责原则 SRP
  • O:开闭原则 OCP
  • L:里氏替换原则 LSP
  • I:接口隔离原则 ISP
  • D:依赖倒置原则 DIP

设计class结构应该遵守的准备和最佳实践。

  1. 设计原则是指导
  2. 不一定都要遵守

开闭原则 OCP

软件实体的行为应当不是修改实体,而是对实体进行拓展

抽象约束 封装变化

js
// 开闭原则
// 目标:已有的场景下,对于需要拓展的进行开放,拒接直接的功能修改

// scene 春节活动
function setColor(){
  if (game === 'PUBG') {
    
  } else if (game === 'LOL') {

  } else {

  }
}

// 重构

class Game {
    constructor(name) {
        this.name = name;
    }
    setColor() { }
    openDialog() { }
}

class LOL extends Game {
    openDialog() {

    }
}

class PUBG extends Game {
    openDialog() {

    }
}

单一职责原则 SRP

一个对象(方法)只做一件事

考虑边界

js
class PUBG {
    openDialog() {
        // 计算金额
        setPrice();
    }
}

const pubg = new PUBG();
pubg.openDialog();

// 改写

class PUBG {
    constructor(command) {
        this.command = command;
    }

    openDialog(price) {
        // 计算金额
        this.command.setPrice(price);
    }
}

class PriceManager {
    setPrice(price) { }
}

const exe = new PriceManager();
const pubg2 = new PUBG(exe);
pubg2.openDialog(15)

依赖倒置原则 DIP

高级模块不应该依赖低级模块,他们都应当依赖抽象

抽象不应该依赖实现,而实现应该依赖抽象

js

// scene1 分享
class Store {
    constructor() {
        this.share = new Share();
    }
}

class Share {
    // 分享到不同平台
    shareTo() { }
}

const store = new Store();
store.share.shareTo('wx');

// scene2 评价
class Store {
    constructor() {
        this.share = new Share();
        this.rate = new Rate();
    }
}
class Rate {
    star() { }
}
const store2 = new Store();
store2.rate.star();

// 重构
// 暴露挂载 => 动态加载
class Store {
    // 维护模块名单
    static modules = new Map();
    constructor() {
        for (let module of Store.modules.values()) {
            module.init(this);
        }
    }

    static inject() {
        Store.modules.set(this.modules.constructor.name, this.module)
    }
}

class Share {
    init(store) {
        store.share = this;
    }
    // 分享到不同平台
    shareTo() { }
}

class Rate {
    init(store) {
        store.rate = this;
    }
    star() { }
}

const rate = new Rate();
Store.inject(rate)
const share = new Share();
Store.inject(share)

const store3 = new Store();
store3.rate.star(5);

接口隔离原则 ISP

不应当强迫客户依赖他们不用的方法

目标:用多个专业的接口,而不是用单个大而全的接口

js
class Game {
    constructor() {

    }
    run() { }
    shot() { }
    mega() { }
}

class LOL extends Game { }

class PUBG extends Game { }

const lol = new LOL();
lol.run();

const pubg = new PUBG();
pubg.run();

// 很明显不同游戏相同的行为处理不同

// 重构

class Game {
    constructor() { }
    run() { }
}

class MOBA extends Game {
    mega() { }
}

class FPS extends Game {
    shot() { }
}

// 然后再继承

里氏替换原则 LSP

如果S是T的子类,那么T的对象可以替换为S的对象,而不会破坏程序。

所有引用其父类方法的地方,都可以透明的替换其子类的对象。

js
class Game {
    start() { }
    shutDown() { }
    play() { }
}

const game = new Game();
game.play();

class MobileGame extends Game {
    play() { }
    mobileStores() { }
}

const mobileGame = new MobileGame();
mobileGame.play();

// 重构

class Game {
    start() { }
    shutDown() { }
}

class MobileGame extends Game {
    play() { }
    mobileStores() { }
}

class PCGame extends Game {
    play() { }
    speed() { }
}

鄂ICP备2024055897号