Java 具有不断变化的接口的装饰器模式
我有一个用例,其中我有一个由外部供应商提供的数据库接口,假设它如下所示:Java 具有不断变化的接口的装饰器模式,java,database,oop,design-patterns,Java,Database,Oop,Design Patterns,我有一个用例,其中我有一个由外部供应商提供的数据库接口,假设它如下所示: interface Database{ public Value get(Key key); public void put(Key key, Value value) } 供应商提供此接口的多种实现,例如ActualDatabaseImpl、MockDatabaseImpl。我的消费者希望使用数据库接口,但在调用某些API之前,他们希望执行一些额外的工作,例如在进行调用之前调用客户端速率限制器。因此,
interface Database{
public Value get(Key key);
public void put(Key key, Value value)
}
供应商提供此接口的多种实现,例如ActualDatabaseImpl、MockDatabaseImpl。我的消费者希望使用数据库接口,但在调用某些API之前,他们希望执行一些额外的工作,例如在进行调用之前调用客户端速率限制器。因此,与其让每个消费者都去做额外的检查RateLimitor限制的工作,我想创建一个装饰类,它将抽象出rate Limitor部分,消费者可以在不知道RateLimitor逻辑的情况下与DB交互。e、 g
class RateLimitedDatabase implements Database{
private Database db;
public RateLimitedDatabase(Database db) {this.db = db;}
public Value get(Key key) {
Ratelimiter.waitOrNoop();
return db.get(key);
}
public void put(Key key, Value value) {
Ratelimiter.waitOrNoop();
return db.put(key, value);
}
}
只要数据库接口不引入新的方法,这就可以了。但是一旦他们开始添加我并不关心的API,例如delete/getDBInfo/deleteddb等,问题就开始出现了
每当发布具有更新方法的DB的新版本时,我的RateLimitedDatabase构建就会中断。一种选择是在修饰类中实现新方法,以调查构建失败的根本原因,但这对开发人员来说只是额外的痛苦。如果在不断变化/扩展的接口中使用装饰器模式,这似乎是一个常见的问题,那么还有其他方法来处理这种情况吗
注意:我也可以考虑构建一个基于反射的解决方案,但对于这个特定的问题来说,这似乎是一个过激/过度工程。如果这是可行的(您需要修改所有的客户端代码),您可以提取供应商.Database
接口的“镜像”,并将其称为镜像.Database
;然后从vendor.Database
界面将所需的方法复制到mirror.Database
(具有完全相同的签名)
编辑客户端代码以使用mirror.Database
界面,并让RateLimitedDatabase
实现此mirror.Database
界面。由于所有方法签名都是相同的,因此将客户机代码切换到镜像接口应该是无痛的RateLimitedDatabase
将委托给供应商。当然,数据库的实施
(我认为我描述的或多或少是桥接模式(使用接口“屏蔽”底层更改)。面向方面编程解决了这个问题。
大多数框架都会为你的界面生成一个动态代理,所以它总是同步的