为什么我停止写代码,开始转向设计
我曾以为软件开发就是编写功能。我以为我的工作就是创建实体、构建控制器以及连接数据库。
最近的一个项目改变了我的看法。我意识到编码仅仅是解决方案的一部分。真正的核心工作在你写下第一行代码之前就已经开始了。
你必须决定架构。你必须思考它为何适用、成本是多少,以及它能解决哪些风险。
以下是我总结的主要经验:
• 架构必须与产品阶段相匹配。 人们往往倾向于立即使用微服务、Kubernetes 和复杂的事件队列。在我们的项目中,我们选择在单个进程中使用分层架构。这使我们能够在不承受分布式系统带来的头痛问题的同时,实现职责分离。在起步阶段,简单往往更好。
• 有些决策现在成本很低,但以后会变得非常昂贵。
我们从第一天起就在数据模型中添加了 TenantId。尽管当时只有一个客户,但这为将来向 SaaS 模式转型铺平了道路。如果你等待太久才添加多租户支持,迁移过程将会变成一场噩梦。
• 设计可以防止未来的死胡同。 编程解决的是眼前的问题。而设计解决问题时,不会堵死未来的路。我们很早就使用了容器,以便轻松迁移到不同的基础设施。我们使用了接口(interfaces),使得更换供应商变得简单。
• 业务变化驱动技术变革。 系统向微服务转型是因为业务在增长。一个单一的诊所应用可能会变成面向数百家诊所的 SaaS 平台。这种转变会改变你处理计费、订阅和扩展的方式。
• 可靠性需要巧妙的设计模式。 我们将同步调用转向了事件驱动架构(event-driven architecture)。在医疗系统中,一个缓慢的通知服务不应该导致预约挂号功能崩溃。我们使用了 Outbox 模式,以确保即使消息代理(message broker)发生故障,数据依然安全。
• 模式必须契合领域。 不要盲目使用模式。医疗诊断需要强一致性(strong consistency)。为了患者的安全,你不能依赖最终一致性(eventual consistency)。如果使用缓存会破坏审计追踪(audit trail),那么请不要对敏感的临床数据使用缓存。
• DevOps 不是事后才考虑的事情。 部署、健康检查和流水线(pipelines)都是初始设计的一部分。你必须估算成本,并选择真正符合你需求的组件。
程序员与设计师的区别在于“为什么”。
程序员问:“我该如何实现它?” 设计师问:“为什么这是解决这一特定问题的正确方案?”