很好的问题。
首先,请记住,这是书中的一个简单示例。读者可以对此进行扩展并想象更复杂的场景。在所有这些场景中,进一步想象您不是团队中唯一的开发人员;相反,您在一个大型团队中工作,开发人员之间的沟通通常采取协商类接口的形式i.e.API、公共方法、公共属性、数据库模式。此外,您通常还需要担心回滚、向后兼容性以及同步发布和部署。
例如,假设您想要将数据库从 MySQL 交换到 PostgreSQL。通过SRP,您将重新实施CarDAO
,更改使用的任何特定于方言的 SQL,并保留Car
逻辑完整。但是,您可能需要进行一些小更改(可能是在配置中),以告诉 Car 使用新的 PostgreSQL DAO。一个合理的 DI 框架会让这一切变得简单。
在另一个示例中,假设您希望将 CarDAO 委托给另一个开发人员来与 memcached 集成,以便读取虽然最终一致,但速度很快。同样,该开发人员不需要了解任何有关商业逻辑 in Car
。相反,他们只需要在 CRUD 方法后面进行操作CarDAO
,并可能在中声明更多方法CarDAO
具有不同一致性保证的API。
再举一个例子,假设您的团队雇用了一位专门研究合规法的数据库工程师。为了准备即将到来的 IPO,数据库工程师的任务是保留公司 35 个数据库中所有表的所有更改的审核日志。有了 SRP,我们勇敢的 DBA 就不必担心任何问题商业逻辑使用我们的任何桌子;相反,他们的突变跟踪魔法可以通过使用装饰器或其他方面编程技术巧妙地注入到 DAO 中。 (顺便说一句,这也可以在 SQL 接口的另一端完成。)
好吧,最后一个 - 假设现在团队中引入了一名系统工程师,其任务是跨 AWS 中的多个区域(数据中心)分片这些数据。该工程师可以进一步改进 SRP,添加一个组件,该组件的唯一作用是告诉我们每个 ID 的每个实体的归属区域。每次我们进行跨区域读取时,新组件都会碰撞一个计数器;每周,自动化工具都会将跨区域频繁读取的数据迁移到新的主区域,以减少延迟。
现在,让我们进一步发挥想象力,假设业务正在蓬勃发展 - 突然间,您正在为一家财富 500 强公司工作,该公司的多个部门横跨多个国家。财务部的业务分析师希望使用您的表格在其 IPO 后投资者报告中绘制汽车销售的季度增长情况。而不是让他们访问Car
(因为用于报告的逻辑可能与用于准备在 Web UI 上呈现的数据的逻辑不同),您可以为以下内容创建一个只读接口:CarDAO
包含精心策划的公共属性的简短列表,您现在必须跨部门边界维护这些属性。上帝禁止你必须重新命名这些属性之一:为 3 个月的日落计划和许多悲伤的仪表板和深夜升级做好准备。 (并且请不要让他们直接访问实际的 SQL 表,因为隐含的假设是整个表是the公共界面。)哎呀,我的伤疤可能会露出来。
一个推论是,如果您需要更改商业逻辑 in Car
(比如说,添加一个方法来计算每辆特斯拉在令人尴尬的召回后的较低销售价格),你不会碰CarDAO
, since if car.brand == 'Tesla; price = price * 0.6
与数据访问无关。
补充阅读:CQRS https://martinfowler.com/bliki/CQRS.html