首页 > 代码库 > Git的设计太帅了!
Git的设计太帅了!
Git是Linux之父Linus的又一力作,设计做得太帅了,不愧是世界级的产品,让人顶礼膜拜!
有以下几个特点:
功能设计紧凑、克制
软件系统的功能设计需要想清楚能做什么,同时,也要想清楚,不做什么。
往往想清楚不做什么更重要。
有经验的专家敢于确定哪些不做,不是草率鲁莽,而是思虑万全。
在经验和直觉基础的经过了审慎的考虑,确认了功能实现、性能、安全、并发不会有问题。
同时对取舍的缺点也洞若观火,判定无伤大雅。分层设计,层次间协议清爽
内核、功能、交互 分层设计,层次间仅通过约定的协议通信。
越向内层,越注重简洁和稳定。
内核极其简单
Git的内核包括blob、tree、commit三类对象。
三类对象职责清晰,分层明确,对象之间的关联简单到不能再简单。
足够简单的同时,也稳固到不能再稳固。
blob存数据、tree存结构、commit存历史。
blob和tree之间通过hash key关联,作为唯一协议。
tree和blob或自己关联。
commit和tree关联,和blob不直接关联。
仅仅三个对象,太帅了!
如果换个身边的设计师,首先,能把微内核做到这么极致就是个挑战,仅仅做内核可能就有十几个概念出来了。什么sync、trans、log、audit都会出来。
能够确定不做什么更重要!
功能层仅仅同内核通过简约协议通信
HEAD、tag、branch几个引用对象,作为版本控制的业务领域概念,属于功能层,或称为业务层。
仅仅通过commit直接关联。
hash key作为引用指针算法,是唯一的协议,也是简单到不能再简单的协议,不需要协议说明手册,不需要接口说明,真的做到了一句话能说清楚。
世界级的对象命名
给对象起名字,是顶级重要的事情,直接影响到软件系统的设计质量,以及其后的开发质量、推广成本和维护成本。
blob、tree、commit几个名字起得太帅了!
可以叫file、dir、his,但这样和物理直接相关,抽象程度不够,抽象程度不够的代价会极其惨痛。
而且命名含义会引起混乱,最终没人能搞清楚这个软件是怎么回事。
如果换个人设计,会不会叫DataNode、StorageNode、DirectoryEntry、HistoryVersionEntry呢?
叫sjjd、mljd也有可能,拼音首字母,能看懂吗?
有效隔离关注点
现在的软件产品已经复杂很难把全部需要关注的事情同时放入人脑了。
在设计、开发软件的时候,必须有效隔离关注点,才能确保设计和开发的质量。
我们想象一下Git开发的过程:
实现blob的时候,仅仅思考文件怎样存储,怎样提取,磁盘数据如何管理就OK了,其他概念与它无关。
实现tree的时候,仅仅考虑blob的上层API和自己要实现的功能部分就可以了。
以此类推:Git通过良好的设计有效地分离了关注点,虽然在设计实现一个复杂的软件系统,但在做架构工作时,仅仅需要考虑模块的划分与通信协议,设计实现具体模块的时候,由于设定了良好的协议和功能规约,仅仅需要模块内的事情。
把庞大复杂的事情拆分成清爽简单的事情。开发人员仅仅做好了砖块,项目经理只是做好了运输组织,设计人员只是做好了现场施工,长城建成了!
平凡和伟大的关系就这样联系在一起了。
层次化、模块化、简约协议、高内聚、低耦合这些话一直挂在嘴边,分离关注点也是设计师的尝试,但有谁真正做好了呢?
状态的管理
想想一个文件系统(或版本控制系统)中文件和各种操作的状态如何处理?特别是通过网络互相访问的时候。
你是否开始在脑海里画复杂到更复杂的状态图,思考各种并发模型的处理效率、死锁的出现条件,各种原因失败后的处理机制,文本文件的冲突处理机制、二进制文件的冲突处理机制?
Git怎么处理的呢?
Git中blob、tree、commit几个核心对象创建后,永远不变!
想想,也应该这样啊。key是全球唯一码,必然这样的。
还是那句话,确定要做什么很简单,难在确定不做什么。永远不变,不考虑状态是Git核心层的决定。
有了核心层的决策后,也就指明了方向。
变化的职责由业务层来处理,业务层核心对象是三个指针,指针什么的,应对变化太自然了。
实现文件比对吗?也有高效的处理方案。而且感觉比cvs什么的更高效。
性能、分布式、并发的考虑
有哪个软件系统不需要考虑性能吗?
现在还有哪个软件不需要考虑分布式和并发吗?
做架构设计和核心层设计更是需要思虑万全,考虑到事情的方方面面,每一个细节都要考虑过,更何况性能、分布式和并发。
由于核心对象创建后永远不变,性能、分布式、并发的考虑忽然简单了。
而且通过网络共享文件,相同文件出现的概率越高(估计机率很小吧),存储的利用效率也就越高(理论上)。
综上所述,神级的设计,顶礼膜拜!
Git的设计太帅了!