从GIT系统设计认识编程领域中的‘抽象和分层’思想

一、前言

“抽象与分层,是计算与程序世界里最根本的思想。逻辑之始。”

宇宙的终极图景人类无法认知,愚蠢是人类理智的最后一道防线 ——《论克苏鲁世界观中的认知哲学》

毋庸置疑,现实世界是无比复杂的,以人类有限的脑力来认识和解构世界,无疑是需要一定的方法论的。

在编程领域中,系统可以是无比复杂的。而人类为了开发和持续维护复杂系统,必然要做好优秀的架构设计,才能有效降低开发者的心智负担

因此,抽象和分层是人类应对方法。

抽象是对普遍性的表达,分层则是在恰当的语义层上放置抽象

二、概念

抽象

抽象主要有通用域抽象和领域抽象。通用域抽象是所有软件都会复用的概念、实体与交互;领域抽象则特定于某个具体的行业领域。抽象通常使用术语来表达

主要有六类抽象:

  • 流程型抽象: 表达应用流程,将单一功能构造成实用的服务
  • 任务型抽象: 使用有限可控的任务执行者集稳定高效地完成源源不断来临的任务
  • 数据处理抽象: 任务的实际内容
  • 结构型抽象: 存储和容纳执行任务所需要的资源、数据集
  • 数据模型抽象: 具有语义关联的数据项聚合体
  • 原子数据抽象: 组成数据的基本数据单位

分层

  • 高层语义表达意图,底层语义呈现细节
  • 相同层次一般不相互直接调用
  • 不建议跨层调用

什么是整洁代码

摘录自《代码整洁之道》298页:

1,代码逻辑直接了当,让缺陷难以隐藏
2,尽量减少依赖关系,使之便于维护
3,依据某种分层策略完善错误处理代码
4,性能调至最优,省得引诱别人做没规矩的优化
5,整洁的代码只做一件事
6,简单直接,具有可读性
7,有单元测试和验收测试
8,有意义的命名
9,代码应在字面上表达其含义
10,尽量少的实体:类、方法、函数
11,没有重复代码

三、GIT系统设计

概念

从GIT系统分析可知,应该有如下的抽象(对象)
commit:一次确切的提交记录
branch:分支对象
tag: 标签
stash:暂存对象
stashList: 暂存栈
repo:GIT仓库对象
diff:提交、暂存所对应的文件改变内容对象

而我们自顶而下的设计该系统,应有如下分层:repo(仓库源) →branch(分支) -> commit(提交) → diff(文件改变内容对象)

对于一些特殊的抽象,可由其他抽象派生而得,比如tag派生自commit抽象

伪代码

如下是一些说明上述抽象的伪代码

// 每个Diff对象包含每个变更文件的具体变更信息:增加内容(行数),删除内容(行数)
class Diff {
    constructor() {
        this.changeFileList = []
        this.changeContent = {}
    }
}

class Commit {
    constructor() {
        this.type = 'commit'
        this.diffContent = new Diff()
        this.committer = '' // 提交者
        this.email = 'example@git.com'
        this.timestamp = Date.now() // 提交时间
        this.msgTitle = '' // commit message
        this.msgContent = '' // commit message content
        this.hash = '' // 38位hash字符串
        this.parentNode = null // 父节点,该属性可以将所有的commit列表转化为一颗commit树。
    }
}

class Branch {
    constructor() {
        this.name = ''
        this.startNode = new Commit()
        // endNode属性的作用是:当在某个分支的某个commit节点上分叉出一个新的分支,endNode用于确定当前分支的commit列表的结束位置。因此,会出现某个commit节点技术某个分支的endNode,也是另一个分支的startNode 
        this.endNode = null
    }
}
// Tag对象抽象与Commit不同的是:有tag属性和explain属性,且tag节点不能在向下生长commit节点
class Tag extends Commit {
    constructor() {
        super()
        this.type = 'tag'
        this.tag = ''
        this.explain = '' // 该tag的解释内容
    }
}
// Stash抽象对象不能推送到远程,stash并没有在commit树中,而是在StashList栈中list
class Stash extends Commit {
    constructor() {
        super()
        this.type = 'stash'
    }
}

class StashList {
    constructor() {
        this.list = []
    }

    pop() {}

    apply() {}
}

class Repo {
    constructor() {
        this.currentBranch = '' // HEAD指向
        this.commitList = []
        this.branchList = []
        this.tagList = []
    }
}
// 工作区
class WordSpace {

}

四、其他

抽象和分层是开发者在编程领域中的不二法宝,我们在阅读优秀的库/框架源码时,如果以“抽象和分层”的角度切入,进行源码的梳理解读,应该不失为一种高效的阅读源码的方法。

五、参考链接

posted @ 2021-04-25 16:24  西河  阅读(18)  评论(0编辑  收藏  举报