原文:https://alexkondov.com/full-stack-tao-start-with-the-domain/
原标题:Start With the Domain
作者:Alexander
你终于开始从事一个全新的项目了!或者也许你刚刚加入一家新公司或团队?也许你在大学被布置了一份作业,或者你最终决定尝试一下一个创业想法。
你正在开始一个新的软件项目。
但是,你需要先做其他事情,而不是设置存储库、购买域名、选择技术栈和研究技术细节。
令许多工程师失望的是,你需要了解你所构建的业务和产品。
中间的最佳位置
在不了解技术应用领域的情况下思考技术,就像在不知道目的地的情况下决定使用何种交通工具一样。
你可能会选择一个导致过度设计的技术栈,并因此阻碍其他简单产品的开发。或者,你所使用的技术对你要构建的内容来说太过受限。
无论是设计不足还是过度,结果都是一样的——软件质量低于标准。
作为工程师,我们工作的一个重要部分是不断将我们正在构建的产品推向中间的最佳位置。在那里,我们能够以高效的速度进行开发,并对技术栈的能力充满信心。
但除非我们了解我们所支持的业务,否则我们无法找到这种平衡。
如果你不学习领域(业务)知识怎么办?
大多数工程师在了解业务细节时会有下意识的抗拒。毕竟这是别人的工作。产品和营销人员可以处理这个问题,而我们则专注于技术细节。
因此,我们不去说服你,而是探索一下当我们不了解我们的领域时会发生什么。
我们为数千名用户开发高度可扩展的系统。尽管我们的流量很难突破初级 MySQL 数据库的限制,但我们设计的数据适合 NoSQL 存储。
我们在抽象之上创建抽象,以避免想象中的场景。我们构建单体,将可以独立存在的组件放在同一个地方。
我们创建的设计系统无法支持它们。我们痴迷于不必要的重新渲染,而我们的性能瓶颈却处在其他地方。
我们花费大量时间设计解决方案,却几乎没有带来任何好处。我们根据自己的喜好选择技术,然后努力用它们来解决问题。
我确信你至少经历过其中一种情况。他们的共同点是:缺乏对产品的了解。
这种情况会导致糟糕的技术决策。
领域决定一切
精通产品的工程师更有可能为他们试图构建的产品找到正确的技术复杂度。这比选择使用 React 还是 Angular 来构建 UI 更有影响力。
从规模到体系结构和库选择,一切都由领域决定。
所需的可伸缩性级别取决于预期的流量。弹性水平取决于企业是否会突然出现流量高峰。甚至抽象和数据结构的深度也将取决于对产品的期望。
几年前,我从事规则引擎的实现工作。尽管我们设法使用图形创建了一个完美可靠的实现,但最后我们转向了使用多个树的解决方案。
树遍历在我们架构中的表现更好,尽管它更复杂,却能够处理更多的规则,效率也更高。而这些决定都与我们对使用场景和领域的理解密切相关。
最佳实践
在考虑解决方案时,最佳实践是一个很好的起点。这些指南适用于大多数情况,提供了基本的建议,但每个软件项目迟早都会偏离它们。
深入了解细节后,你会发现每个企业有独特需求,很难用通用知识解决。
理解商业模式的细微差别会帮助你做出明智的决定,决定哪些做法值得遵循,哪些需要放弃。
展望未来
如今,软件没有一成不变的。随着时间推移,一切都会发生变化。
然而,理解这个领域有助于我们克服与架构甚至低级编码决策相关的许多恐惧和不确定性。
只有对增长或业务转型有现实的预期时,担心是否需要更改数据库才有意义。如果你了解库的功能前景,评估其是否足够就会节省时间。
展望软件的未来就是考量公司的前景。只有在你熟悉这个领域时,这才可能实现。
需求不明确
由于需求常常不明确的问题,我们可能很快将责任转移到业务人员身上。当你不知道人们的具体要求时,很难做出正确决定。
但问题的关键在于——了解人们的需求。
了解业务将帮助你提出正确的问题。这样你可以在用户实施前识别边缘情况和潜在问题。
产品人员可能无法识别功能中的技术差距;但具备一些领域知识,你就会发现这些问题。
举个例子,一家软件公司为一家连锁精品酒店开发在线预订系统。需求是客户能够在线预订房间。
开发团队创建了一个简单的系统,客户可以选择房间并预订特定日期。一切看似正常。
但系统上线后问题出现了。客户不小心预订了已满的房间,有些预订的是正在维修的房间。系统无法处理长期住宿的特殊要求或折扣。
如果开发团队更了解酒店业务,他们可能会问:
- 如何管理房间空置率?
- 如何处理维护中的房间?
- 是否需要处理特殊要求功能,如婴儿床或无障碍设施?
- 长期住宿或特殊场合是否有折扣或特别套餐?
大多数开发人员或许会知道这些细节,因为我们熟知酒店运作方式。
但在其他领域,如金融,情况可能会不同。
消除产品层面的复杂性
我有一个项目,我们使用外部身份验证提供程序,但希望在新用户注册时在数据库中创建条目。然后使用数据库中的数据处理某些关系。
这造成了一种糟糕的竞态条件。
用户通过身份验证后进入应用程序时,我们可能还未创建其帐户。更糟糕的是,可能存在错误或暂时性故障,令他们的帐户无法使用。
这让我们不得不设计复杂的同步机制、空的UI状态及各种极端情况的处理方法。
最终,我们在UI中添加了一个额外的窗口,提示用户提交详细信息以存储在数据库中。这样,我们就避免了整个分布式系统的复杂性。
了解产品能够帮助你在技术问题前消除不必要的复杂性。
当然,这在某些情况下不可能。但若你能限制不必要的复杂性,那么必要的复杂性将更容易管理。
如何学习一个领域?
普通软件工程师每隔几年就换一次工作,每次都必须学习新领域——这很艰难。但好消息是,你不必在第一天就成为专家。下面是我喜欢问的一些问题以扩展我对业务的了解。
1. 谁购买产品,谁使用它?
常常,买家和用户是不同群体。这会告诉你人们为何使用产品以及对他们的重要性。
2. 他们如何使用它?是整天打开还是在通勤途中使用?这对他们的生活和工作有多重要?
对于大多数前端应用程序,长期状态管理是个问题。但大多数媒体公司已经找到避免这种情况的方法。他们的大多数用户是以原子方式浏览网站,即打开一个页面然后离开。
因此,许多媒体选择服务器端路由,这样他们就不用在客户端管理状态,可以依赖CDN缓存。
3. 产品有多少用户?
这让你了解企业的规模。
4. 未来的计划是什么?
如果公司计划通过营销获取新用户,那么可扩展性将是优先考虑。如果你在构建一个工具,他们计划白标和出售给其他公司,你需要考虑如何抽象化UI。
5. 亲自使用产品
如果你在为最终用户构建,请务必亲自试用。如果是企业软件,请找人引导你使用。
回答这些问题,操作一下产品,你会发现架构开始自我显现。你会知道哪些约束必须遵守,处理多少数据,UI操作速度,适用设备等等。
但如果你只是开发产品的一部分,你需要了解全部内容吗?不能只了解你的领域吗?
想了解更多?
这是我正在写的《全栈道》一书的一章。我会继续在我的博客和时事通讯中分享更多免费章节。