做者:陈皓 原文 html
以前,@风枫峰 在“这是谁的错?”中说过开发团队对需求来者不拒,而@weidagang 也在“需求变动和IoC” 中说过用IoC来最大程度地解决需求变动。今天我也想从Unix设计思想的角度来讲说什么是好的软件设计,什么样的设计能够把需求变动对开发的影响下降。(注意:这并不能解决用户或是PM的无理需求,面对无理需求,须要仔细分析需求,而用技术的手段没法搞定这个事,可是能够减轻需求变动带来的痛苦)程序员
我曾经在《Unix传奇》的下篇中写过一些Unix的设计哲学和思想(这里重点推荐你们看一下《The Art of Unix Programming》,我推荐过屡次了),之前也发过一篇“一些软件设计的原则”,不过,这些东西都太多了,记不住。其实,这么多年来,个人经验告诉我,不管是Unix设计,仍是面向对象设计,仍是别的什么如SOA,ECB,消息,事件,MVC,网络七层模型,数据库设计,等等,他们都在干三件事——解耦,解耦,仍是解耦!所谓解耦,就是让程序员的模块和模块间尽可能少地依赖起来。web 现实当中的例子让我先举几个现实生活中的例子:算法 一、现实社会中,制造灯具的工厂彻底不关心制造灯饰的工厂,制造灯饰的工厂彻底不关心制造灯具的工厂,可是,灯具和灯饰能够很完美地组合成用记所喜欢的样子(这和@weidagang 在“需求变动和IoC”说到的那个PC的例子相仿)。他们是怎么作到的?sql 二、互联网上,作网站的人彻底不用关心用户在用什么样的操做系统,什么样的浏览器,反过来,上网的人也不关心作网站的人在用什么的技术开发网站。可是你们在彻底不关心对方的状况下,能够很正常地协同工做在一块儿。为何?shell
这样的例子太多了。为何能够作成这样呢?由于你们依赖的是一个接口,灯具和灯饰并不互相依赖,他们依赖的是一个接口,作网站的人和浏览网站的人依赖的仍是接口——HTTP协议。这就是面向对象的核心思想——依赖于接口而不是实现,这就是触耦。当你看过这两个例子之后,我但愿你之后设计的软件至少不能比咱们现实社会中的这些方法要差。否则,你就是在让社会倒退了,呵呵。数据库 你会说,这和Unix,和应对需求变化有什么关系?好让咱们再来看一下Unix的设计。浏览器 Unix设计的例子下面是几个Unix下的例子:bash 一、Unix下,全部的硬件均可以经过文件的方式存取。其通通在/dev下。因而,软件和硬件的耦合被解开了,操做系统只须要把硬件通通变成文件,而程序只须要使用三个东西,一个是fd,一个是read(),一个是write(),就能够来操做任意的硬件了,这就是抽象,简单到不行。网络 二、Unix下,全部的命令均可以用管道串起来(管道绝对是个伟大的发明),这样,全部的命令间的交互所有解耦到只依赖于STD_IN, STD_OUT设备上。最酷的是,用户可使用管道任意地拼装那些命令,以完成各式各样的功能。管道这个设计思想能够映射为今天的Web Service,你能够任意地拼装各类Web Service。 看到这里,你会发现,这仍是解耦,本质上来讲,也是一种依赖倒置——OOD的精髓。可是,Unix还不只仅是这些。咱们再来看几个例子: 一、Unix下,软件都是绿色地安装。在iOS上更明显——各个程序间基本上互不干扰,这个程序产生的垃圾文件不会影响到另外一个程序。你删到一个程序不会让另外一个程序不举,各是各的空间。你能够删除这些程序,只要把内核心留着,系统照样能够启动。 二、Unix下,你能够经过设置一些环境变量,让多种环境同时存在,好比:某个LAMP用的是Apache 2.0, Mysql 4.0, PHP 4.0,某个LAMP用的是Apache 2.2, Mysql 5.0,PHP5.3,你不但能够方便地在系统中切换这两个环境,你甚至还能够同时启动他们。 三、Unix下,你能够随意地替换你想要的程序。好比,你不喜欢bash,你能够替换成ksh/csh等,你不喜欢awk,你能够替换成gawk,全部的东西都像零件同样,你不喜欢什么,你就能够替换什么。 这三个例子告诉了咱们——当你把你的软件设计地耦合度很是地低时,你能够随意地组合,随意地安排你的系统。想当的灵活,灵活到Windows到今天都学不会。 应对需求变化看到这里,你可能明白我想说的是什么了,你可能开始以为怎么样的系统设计会更有效了。若是你还记得《Steve Y 对平台的长篇大论》,你就会知道我想说什么了。是的,我想说的就是,当你真正了解了Unix的设计思想后,你会以为今天的这些东西都是对Unix设计思想的一种传承或是变种。这种东西就是: 1)解耦,解耦,解耦。尽可能地让你的模块不要在实现上耦合,而是耦合某个规范,某个标准。 2)KISS,KISS,KISS。要作到高度解耦,你的模块就必定要很简单,固然不是说简单到只有几行代码,而是简单到只干一件事,并把这件事干到极致。而后经过某个标准拼装起来。 3)拼装,拼装,拼装。我想不起来是谁说的了,这句话是这样的,当我想用一个模块的时候,我直接调用就行了,没有必要像C或Java同样,还要编译。是的,拼装须要一个框架,须要一种标准协议,而后让全部的系统都耦合在这种规范上,各自独立运行,就像一个机器上的各个部件同样,当我以为这个部件不爽,换了就是了。(例如,当咱们在尝试不用的算法的时候) 想一想建材和家俱市场,不管用户过来想装修什么,我均可以知足用户的不一样需求,只要你是和家装相关,我基本上都能知足你,不是吗?不管你怎么变,只要不变态,我基本上均可以知足你。这就是解耦,拼装带来的好处。 你可能会说我说得太简单了,另外一方面,你可能以为有一些系统这样作不必,我认可,不过,你能够有选择的或多或少地试试。(其实,我相信你已经在不自以为或多或少地使用这种方式开发软件了) |