本节书摘来异步社区《游戏编程模式》一书中的第1章,第1.2节,作者: 【美】Robert Nystrom (尼斯卓姆) 译者: 赵卫兵 , 许新星 , 姜召阳 , 陈侃 , 屈光辉 , 郑炯彬 责编: 陈冀康,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.2 有什么代价
这听起来很不错,不是吗?对一切进行解耦,你就可以迅速编写代码。每一次变化意味着只会涉及某一个或两个方法,然后你就可以在代码库上行云流水地编写代码。
这种感觉正是为什么人们会为抽象、模块化、设计模式和软件架构感到兴奋的原因。一个架构良好的程序工作起来真的会令人愉悦,每个人都会更加高效。良好的架构在生产力上会产生巨大的差异。怎么夸大它带来的效果是如何深远都不为过。
这小节的下半部分(维护你的设计)需要特别注意。我曾见过许多程序在开始时写得很漂亮,但死于一个又一个“一个小补丁而已”。
就像园艺一样,只种植是不够的。你必须要除草、修剪。
但是,天下没有免费的午餐。良好的架构需要很大的努力及一系列准则。每当你做出一个改变或者实现一个功能时,你必须很优雅地将它们融入到程序的其余部分。你必须非常谨慎地组织代码并保证其在开发周期中经过数以千计的小变化之后仍然具有良好的组织性。
你必须要考虑程序的哪一部分应该要解耦然后在这些地方引入抽象。同样地,你要确定在哪里做一些扩展以便将来很容易应对变化。
人们对此非常兴奋。他们设想着,未来的开发者(或者是他们自己)进入代码库,发现代码库开放、强大,只等着被加些扩展。他们想象一个游戏引擎便可统治一切。
但是,事情就在这里开始变得棘手。当你添加了一个抽象层或者支持可扩展的地方,你猜想到你以后会需要这种灵活性,于是你便为你的游戏增加了代码和复杂性,这需要时间来开发、调试和维护。
有人杜撰了“YAGNI”一词(You aren’t gonna need it 你不需要它)作为口头禅,用它来与猜测未来的自己会想要什么这种冲动进行斗争。
如果你猜对了,那么你之前的辛苦就没白费,而且也无须再对代码进行任何修改。但是猜测未来是很难的,并且当模块最终没起到作用时,很快它就变得有害。毕竟,你必须处理这些多出来的代码。
当你过度关注这点时,便会得到一个架构已经失控的代码库。你会看到接口和抽象无处不在。插件系统、抽象基类、虚方法众多,还有各种的扩展点。
你将花费大量时间去找到有实际功能的代码。当你需要做出改变时,当然有可能有接口能帮上忙,但你会很难找到它。从理论上讲,解耦意味着在你进行扩展时仅需理解少量代码,然而抽象却增加了理解代码的难度。
像这样的代码库正是让人们反对软件架构尤其是设计模式的原因。对代码进行包装很容易,以至于让你忽视了你要推出一款游戏的事实。一味地追求可扩展性让无数开发者在一个“引擎”上花费数年却没有搞清楚引擎究竟是用来做什么的。