实践GoF的23种设计模式:SOLID原则(11)


// demo/src/main/java/com/yrunz/designpattern/db/Db.java// DB抽象接口public interface Db { Optional query(String tableName, PrimaryKey primaryKey); void insert(String tableName, PrimaryKey primaryKey, Record record); void update(String tableName, PrimaryKey primaryKey, Record record); void delete(String tableName, PrimaryKey primaryKey);...}
接着,我们让依赖Db接口,而实现Db接口,以此来完成依赖倒置:
// demo/src/main/java/com/yrunz/designpattern/service/registry/Registry.java// 服务注册中心public class Registry implements Service {...// 只依赖于Db抽象接口private final Db db;private final SvcManagement svcManagement;private final SvcDiscovery svcDiscovery;private Registry(..., Db db) {...// 依赖注入Dbthis.db = db;this.svcManagement = new SvcManagement(localIp, this.db, sidecarFactory);this.svcDiscovery = new SvcDiscovery(this.db);}...}// demo/src/main/java/com/yrunz/designpattern/db/MemoryDb.java// 内存数据库,实现Db抽象接口public class MemoryDb implements Db {private final Map> tables;...// 查询表记录@OverridepublicOptional query(String tableName, PrimaryKey primaryKey) {...}// 插入表记录@Overridepublicvoid insert(String tableName, PrimaryKey primaryKey, Record record) {...}// 更新表记录@Overridepublicvoid update(String tableName, PrimaryKey primaryKey, Record record) {...}// 删除表记录@Overridepublicvoid delete(String tableName, PrimaryKey primaryKey) {...}...}// demo/src/main/java/com/yrunz/designpattern/Example.javapublic class Example {// 在main函数中完成依赖注入public static void main(String[] args) {...// 将MemoryDb.instance()注入到Registry上Registry registry = Registry.of(..., MemoryDb.instance());registry.run();}}
当高层模块依赖抽象接口时,总得在某个时候,某个地方把实现细节(低层模块)注入到高层模块上 。在上述例子中,我们选择在main函数上,在创建对象时,把注入进去 。
一般地,我们都会在main/启动函数上完成依赖注入,常见的注入的方式有以下几种:
另外,DIP不仅仅适用于模块/类/接口设计,在架构层面也同样适用,比如DDD的分层架构和Uncle Bob的整洁架构,都是运用了DIP:
当然,DIP并不是说高层模块是只能依赖抽象接口,它的本意应该是依赖稳定的接口/抽象类/具象类 。如果一个具象类是稳定的,比如Java中的,那么高层模块依赖它也没有问题;相反,如果一个抽象接口是不稳定的,经常变化,那么高层模块依赖该接口也是违反DIP的,这时候应该思考下接口是否抽象合理 。
最后
本文花了很长的篇幅讨论了23种设计模式背后的核心思想 —— SOLID原则,它能指导我们设计出高内聚、低耦合的软件系统 。但是它毕竟只是原则,如何落地到实际的工程项目上,还是需要参考成功的实践经验 。而这些实践经验正是接下来我们要探讨的设计模式 。
学习设计模式最好的方法就是实践,在《实践GoF的23种设计模式》后续的文章,我们将以本文介绍的分布式应用系统demo作为实践示范,介绍23种设计模式的程序结构、适用场景、实现方法、优缺点等,让大家对设计模式有个更深入的理解,能够用对、不滥用设计模式 。
参考
【实践GoF的23种设计模式:SOLID原则】Clean ,C.(“Uncle Bob”)敏捷软件开发:原则、模式与实践,C.(“Uncle Bob”)使用Go实现GoF的23种设计模式, 元闰子SOLID原则精解之里氏替换原则LSP, 人民副首席码仔