励志司机锐锐|高级软件工程师成长秘诀( 八 )


没有什么神圣的设计能够总是奏效
在设计系统时 , 我注意到两个广泛的主题 。
首先 , 我们发明的组件有限:队列、缓存、数据库和连接器(或者是让它们协同工作的代码) 。 每一个可能的设计都是这些组件的组合——每一个组件都表现出它们各自的权衡 。 有一些更快 , 有一些更易于维护 , 有一些扩展性更好 , 都取决于你的用例 。
根据你的约束 , 一种安排会比其它安排更好 。 你的目标就是寻找到那种最好的安排 。 有时候 , 你可以通过一些绝妙的方法来降低复杂性 , 或者让事情变得更快 。 但是 , 基础设施不会变化 。
其次 , 每个人都有一些快乐的主题可以回顾 , 他们已经在过去看到了很好的效果 。 这些都是观察系统的不同视角 。 设计就是要搞清楚哪种排列符合这个视角 。
例如 , 我喜欢简化状态并保持简单 。 简化状态有助于我更好地理解系统 , 也有助于我更好地写测试代码 。 保持简单也是一样 。 两者都会导致更少的bug 。 当然 , 不能太简单:这不能违反约束 。
正如我去年说的 , 速度、本地化开发和测试都值得考虑 。 如果两种设计效果相同 , 但其中一种设计更容易本地安装和编写测试 , 那么我总是会选择更容易编写测试的设计 。
我喜欢找出其他人的视角 , 并且尝试吸收我没有的视角 。 这也是我阅读技术博客的另外一个原因 。
在设计时 , 保留上下文也是值得的 , 就像写代码时候一样 。 很多时候 , 我都会发现自己回顾很久时间之前的代码 , 忘记了我们当时的假设 , 然后想“卧槽 , 我们是为什么要这样做的?!”明确我们的约束和权衡 , 有助于保持正确的观点 , 并有助于判断你是否做出了正确的决定 。
最后 , 在设计取代现有系统的系统时 , 我发现讨论迁移路径非常重要:我们将如何管理从旧系统迁移到新系统?
如果你曾经注意到一个系统 , 一半的东西运行在新代码上 , 另一半运行在旧代码上 , 那就是一条有缺陷的迁移路径 。 不考虑迁移路径会导致技术债务高筑:你现在不得不同时管理和维护新系统和老系统 。 有时 , 这是因为优先级切换 , 而你还停留在中间状态 。 无论哪种情况 , 这些异常都不会长久 。
好的迁移路径可能会花费比较长的时间 , 考虑到它们留在系统内的状态的话 。 如果优先级改变 , 我们是否会陷入到什么都不能做的状态?或者我们的迁移是增量的吗 , 即使改变优先级也能保持稳定运行?当然 , 增量迁移并不总是正确的解决方案 。 有时候 , 彻底地迁移会更容易一些 。 其中重要的一点是沟通好:我们不能处理这种迁移的优先级变更 。
总结:
每个系统设计都关乎权衡 。
每个设计都有有限的技术组件 。
人们进行设计时都有明确的视角 , 就像思维模型 。
在设计时保留上下文:写下你的约束和权衡 。
当取代老系统时 , 有一个明确的迁移路径 。
收集需求
根据上述主题 , 收集需求实际上就是收集约束 。 正如我们上面所见的 , 需求有时是将约束转变成技术需求 , 这并不总是正确的前进方向 。
在我的团队文化中 , 团队和项目经理之间有充足的信任 , 我们可以随意挑战彼此的意见 。 直接问问题就好了 。
问题清单在这里很有效 。 这里链接有一些我经常问的一些问题 。
最后一节将深入讨论一些问题 , 一些我曾经做错的事情 , 以及对所有做对的事情的总结 。
一些对我来说很好用的小诀窍
尽可能多地做代码审查 。 你错过的越多 , 你对代码的心理模型就越错误 , 你设计新东西时需要花费的时间就越多 。 斟词酌句:第二个问题一般就是问“你是怎么发现X的?” , 而X就是你第一个问题的答案 。 第一个审核我的PR的人是我自己 。 而且总是这样 。 我很喜欢这样做 。 这是我从写作中学到的:第一阶段写明主旨要点 , 第二阶段进行段落编辑 。 这和写代码很像 。 代码审核就是编辑阶段 , 而且对我的代码进行代码审核也会让我更好地编写代码 , 发现不一致的地方 , 并知道其他人是如何进行代码审核的 。超能力