前段时间和朋友聊天,同为在开发行业呆了超过十年的“老人”,大家都觉得,现在开发的门槛越来越低了。好处是引入了越来越多的人才,“可惜”的是,老规矩被越来越多的人遗忘和忽略了。

我刚工作的时候,基础面试要问许多与软件工程相关的问题,比如设计模式、常见的软件设计原则——单一职责(SRP)、里氏替换(LSP)、依赖倒置(DIP)、关注点分离(SOC)等等。如今的基础面试似乎很少问这类问题了,大都是问一些流行的框架、用法等等。

这也不难理解,以前的“软件开发”,很多是在面向对象的世界里打转转,封装、继承、多态必须了然于胸,那么自然而然容易理解“把子类替换为父类之后,程序的行为功能不应变化”的LSP原则。而如今的“软件开发”很多是基于互联网的,很多应用甚至是“看到界面就能想到表结构和CRUD操作”,根本没有那么复杂的继承关系,所以这些原则被许多程序员忽视,似乎也情有可原。

但情况其实没有那么简单。不少软件设计原则的背后,蕴含的是软件开发人员依照软件本身的逻辑来解决某些问题的实践模式,体现着软件开发人员对真实世界的解析和建模。一旦要解决的问题稍微复杂,比如涉及到架构问题,传统的软件工程思维还是相当有威力的。

未说明这个道理,我经常举的例子就是SRP(单一职责原则)。在《敏捷软件开发》(我强烈推荐所有开发人员仔细阅读这本书)中,有专门的章节讲解它。下面我简单做个讲解:

所谓“职责”,指的是“变化的原因”。如果你能想到不只一个动机去改变一个类,那么这个类的职责就不唯一。理想情况下,每个类应当有唯一的职责。

谈到SRP,经常举的是下面这些例子:

  1. 矩形类有两个方法,一个负责计算面积,一个负责绘制,两者其实没有关系,应当把面积计算和绘制两个职责拆分到单独的类,避免互相干扰;

  2. Modem类有两类方法,一类负责连接管理,一类负责数据通讯,两者也是没有关系的,所以也应当把它们拆分到单独的类,避免互相干扰;

  3. 某个业务类,既包含业务规则,又包含持久化控制,两者同样不应该混为一谈,应当拆分到单独的类;

如果你觉得“类”看起来和面向对象息息相关,与自己每天在做的互联网没什么关系,但如果把“类”替换为“模块”、“子系统”、“服务”,就容易理解了。

我见过很多人设计的缓存模块,大概是为了图省事,它提供了“加速数据访问”功能,同时横亘在业务流程的关键路径上。结果缓存一出问题,不只是响应速度慢,而是业务流程根本执行不下去了。这就是违背SRP的恶果。

遵循SRP带来的好处也很明显。七八年前我做过一段时间的搜索项目,其中商品类目搜索很是烦人,用户往往要输入若干关键词,同时还需要按照标签分类筛选,按各种属性排序。本来,用Lucene之类的开源软件就可以满足需求。麻烦的是商品属性——比如价格、点击量、热度——会经常变化,频繁全量更新商品信息,会导致索引效率的急剧下降。按照SRP,我们拆分出“关键词和标签的布尔查询”以及“频繁变化的属性更新和查询”两个模块,前者延用已有系统,后者单独部署,开发部署之后,效果大为改观。遗憾的是,这些年我仍然见到不少程序员养成了“一听见搜索就想起Solr或者ES”的条件反射,结果设计出的系统在类似场景下仍然不堪重负,问题频出。这充分说明,SRP这样的设计原则,完全可以适用于互联网的系统架构的。

到现在为止,我们谈的都是软件设计,强调的是软件设计(架构)的重要性。但本文的题目是“从软件设计角度看O2O商机”,O2O商机在哪里呢?其实,用软件设计的目光来看很多O2O的生意,会发现不一样的风景。

仔细看看如今流行的O2O服务——外卖。有很多人认为,外卖的生意模式是不健康的,拼的就是补贴,不补贴这个生意就没法做。这种观点,我是不赞成的,依靠SRP就可以证明这一点。软件设计原则的威力,不仅仅限于软件设计领域。

我们仔细看看普通的餐馆,它有好几重职责:点菜、做菜、就餐、结账。在传统模式下,这几重职责天然是混为一体的,必须集中于餐馆,才能发生。

但是依据SRP我们知道,多重职责混为一体,必然带来职责的互相干扰,某方案职责的优化会受到其它方面职责的牵扯。对餐馆来说,最明显的就是做菜和就餐。对大多数餐馆来说,翻台率(也就是就餐的效率)决定了营收水平,做菜速度从来也不是一个主要的限制。那么如何提高翻台率呢?这方面已经有很多人动了脑筋,扩大餐馆空间,合理搭配大小桌,甚至装饰、背景音乐方面也有很多讲究…… 但想来想去,都脱不开餐馆本身。

如果我们换个角度思考:把做菜和用餐彻底分开,把用餐和餐馆彻底分开呢?餐馆只管做菜,变成彻底的“食品提供方”,不再承担“就餐场地”的功能,这样不但可以减去餐厅的面积,还可以大大提升厨师的使用效率(厨师一般不是计件工资)。对餐馆来说,既降低了门槛,又提升了效率,何乐而不为?从这个角度看出去,就不难理解为什么外卖生意如火如荼,各种餐馆对外卖趋之若鹜了。

这个故事提醒我们,用软件解决现实世界的问题,设计商业模式,软件设计原则可能是非常趁手的武器。而且,IT行业的人思考这样的问题天然就有优势。和传统做线下的人多聊聊就会发现,很多人对于责任、协议、接口等等概念,其实还没有任何意识。

这样说开去,O2O的题材已经热了好多年,但很多O2O其实是漫无方向的盲目尝试。我经常在想,是不是大家可以少交一点学费?有什么办法让大家少交一点学费?

其实,O2O既然是要把线上和线下联系起来,终极目的还是在线上系统里形成闭环,借助IT系统的高带宽、高信息流动性、强大的计算能力,原有线下运转阻力很大的生意模型可以拆分、重新组合,形成不一样的业务链条(从某种程度上说,这也是“现实增强”)。既然最终要在线上系统里形成闭环,免不了按照软件系统的逻辑和规则来组织和运转。果然如此,广大IT从业者为什么不认真学学软件设计的原则,再用这套方法去看现实世界呢?没准,下一个商机就在你眼前。