一个设计的反复

最近,我确实比较闲一点,所以我把十几年前的 WordPress 插件,翻出来重新写,这个过程,虽然没什么价值,但是真的很有乐趣的一件事情,就好像有些人打游戏一样的,你把一个游戏打完了,以前完成得不够好的地方,你就再打一遍,用你以为最完美的形式。写代码,也是一样的。

这是一个面向对象设计的范畴。就像很多网站一样,WordPress 也分为前台和后台,前台是大家看到的博客页面,后台,则是各种控制面板和写作界面。然后,作为 Programmer,你一定会遇到的情况就是,有些代码只属于前台,有些代码只属于后台,而无法避免的就是,有些代码前后台都会用到。这种划分,其实是业务属性层面的划分。

还有一个情况就是,有些代码属于界面布局表现,有些属于后台逻辑计算,有些属于用户交互行为,这是逻辑层面的划分。

我们对这些代码进行分类,无非就是为了更好地去管理复杂性,我们追求的一个方向是高内聚,低耦合,让紧密联系的逻辑尽可能靠近,以加强理解和管理,进而便于去复用。不过,从上面我们也能发现,业务属性的划分和逻辑层面的划分,其实是两个不同的维度,近乎是正交的。

于是,就出现了多种的选择,供 Programmer 去进行决策。我就讲个真实的例子。我在开发一款插件,插件功能是在博客的页面上提供一些官方原本没有的功能,比如,有两个小功能,一个是给每篇文章做一个自动摘要,使得博客首页的文章,总是在一定长度后被截断,不要显示全文,这样即便我忘记进行手动摘要,也可以只显示部分内容,便于读者快速浏览整个博客的内容。另一个功能是,在单篇文章的页面,我们也叫帖子页,展示一个相关文章的列表,展示位置在文章结束的地方,提供一个“相关阅读”的栏目,让读者读完一篇文章的时候,快速发现感兴趣的东西,减少站点跳出。

无论是摘要还是相关文章列表,都是改变前台表现的功能。为了控制这两个功能,我就需要提供不少的用户选项。比如,对于摘要功能来说,怎么控制摘要的长度?文章摘要完毕后,要插入一个链接,引导用户跳转到全文进行查看,这个链接展示的样式,也需要控制,也可能,有用户不喜欢这个功能,需要关闭这个功能,那就需要一个开关。

相关文章的列表的控制项就更多了,列表的长度,是否展示文章的阅读次数或者评论数?列表的标题?或者是否关闭功能。

那么为了控制这些选项,显然,还需要后台选项的调整界面。这就是后台业务逻辑了。

我本来的设计是,有一个 Option Manager,提供所有选项的缺省值管理,选项值的读取,写入,持久化。这样,前台功能的时候,可以通过 Option Manager 访问,后台管理界面也可以。

后来我发现,在这个系统里,实现一个后台管理界面的话,会比较复杂,涉及到很多点,比如后台页面的入口位置,后台表单的呈现,提交后的验证等逻辑。后台交互的组织,非常精巧,所以我就实现了一个抽象类,专门管理后台界面的几个方面,为了控制上面两个功能的选项,我显然要把所有的选项划分成两组去分别管理,后来很自然想到了把所有的缺省值和管理界面放在一起,因为选项的结构和和界面的交互设计,也很有关系,放在一起互相启发和功能调整起来都比较快。

然后我今天重构前台的时候,就发现了很大的困难。因为,为了节省内存,我在判定用户只访问前台的时候,不加载后台的代码,我把选项缺省值,内聚到选项面板的代码里去了,这样,如果用户不访问后台的话,就不加载后台部分代码(为了节省 IO 和 内存),结果前台也读不到选项的缺省值了。

可是如果把选项缺省值抽离到 Option Manager 管理,则管理面板和被管理的选项之间的内聚性就牺牲了,于是我就给自己造就了一个两难的选择。

当然,如果这是我的工作的话,我可能随意选择一个方案就处理了,不会去追求完美,但是我这就是像打游戏一样的心态,肯定是希望对极致能有所追求,于是,这就成为一个有趣的设计问题,完全可以尝试进行一番更为精巧的设计。

感觉我就是很喜欢做这种事情,这才是我的热情所在的地方。要是能找到专门干这种事情就能挣钱谋生的工作岗位,那就完美了。