我问我自己Facade模式是否违反了SOLID原则,并且模式本身是否是一个反模式。
我的意见:
- SRP被违反了,当你不直接调用方法,而是直接调用比如事务、日志记录、错误处理(我已经见过很多次了)。即使只是调用其他方法,我也不确定。 违反了
OCP,因为您将向facade
添加更多方法。LSP/ISP被违反,因为消费者/客户端有依赖关系,会有太多客户端不需要的方法
DIP,在我看来,只要接口本身只暴露抽象或dto,就不会违反
SOLID一般是小的, 稳定的,因此可组合的接口。
一个立面趋于相反大和不稳定。
在不考虑任何实现细节的总体思路中,我们可以将Facade视为一种使用Composition and Encapsulation隐藏一组子系统的方法,这些子系统使用更高级别的包装器类。更高级的包装器类总是与任何客户端对话,而包装器内部的子系统是真正完成工作的。
的例子:
public class Bulb{
public void on(){
//logic to turn on the bulb.
}
}
public class Room{
private Bulb bulb;
public void lightUp(){
this.bulb.on();
}
}
上面的灯泡是一个子系统,房间是包装(立面)。因此,客户希望看到它直接照亮房间,而不感兴趣知道它必须用灯泡做什么。
那么回到你的问题,如果我们把坚实的原则一个接一个。
- SRP:您应该认为包装器类违反了这一原则,因为它所做的不仅仅是一项任务。但另一方面,它只是调用一些其他人来做这些事情,而不是用包装器保持实现。不管怎样,这个想法可能是非常私人的。 OCP:当然可以,如果你增加一些子系统/功能的话。同时,你可以使用一些现代的实现绑定框架来避免在这种情况下违反OCP。
- LSP: general I don't find any。但是也可能存在特定于实现的情况,而不是模式。
- ISP: as LSP.
- DIP: as LSP, ISP.
关于将Facade视为反模式(Cons of Facade),
- 可以看到,它正在增加维护工作。对于某些更改,您必须更改子系统实现+各自的包装器调用。
- 子系统与Wrapper紧密耦合。
- 这是一些程序性的,有点偏离对象导向。
使用Facade(许多模式)的选择仍然取决于个人喜好。
你可以在这篇文章中找到。