外观模式介绍
外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
在软件设计中,当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
优点
迪米特法则的典型
降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
缺点
不能很好地限制客户使用子系统类,很容易带来未知风险。
增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。//可以通过引入抽象外观类解决
外观模式的实现
结构
外观角色:为多个子系统对外提供一个共同的接口。
子系统角色:实现系统的部分功能,客户可以通过外观角色访问它。
客户角色:通过一个外观角色访问各个子系统的功能。
外观角色内有子系统角色的引用
实现
外观角色:玩具车遥控器
子系统角色:对玩具车的操作
客户角色: main方法
public class ToyCarTest {
public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl();
remoteControl.goRight();
remoteControl.goLeft();
remoteControl.goStraight();
}
}
//创建一个接口规范子系统角色
interface OperateToyCar{
void Operate();
}
//子系统角色1
class GoRight implements OperateToyCar{
@Override
public void Operate() {
System.out.println("操作玩具车右拐");
}
}
//子系统角色2
class GoLeft implements OperateToyCar{
@Override
public void Operate() {
System.out.println("操作玩具车左拐");
}
}
//子系统角色3
class GoStraight implements OperateToyCar{
@Override
public void Operate() {
System.out.println("操作玩具车直行");
}
}
//外观角色 遥控器
class RemoteControl{
private GoRight goRight;
private GoLeft goLeft;
private GoStraight goStraight;
public RemoteControl() {
goRight=new GoRight();
goLeft = new GoLeft();
goStraight = new GoStraight();
}
public void goRight(){
goRight.Operate();
}
public void goLeft(){
goLeft.Operate();
}
public void goStraight(){
goStraight.Operate();
}
}
怎么看都和工厂模式很像, 但是工厂模式是创建模式
输出结果:
操作玩具车左拐
操作玩具车右拐
操作玩具车直行
引入抽象外观类
外观模式最大的缺点在于违背了“开闭原则”,
当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。