定义

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

又称为门面模式,为一组接口提供一个统一的入口。外观模式是迪米特法则的一种具体实现,通过引入一个新的外观角色降低原有系统的复杂度,同时降低客户端类与子系统的耦合度。

模式中的角色

  • Facade(外观角色):外观角色中可以知道相关的多个子系统的功能和责任,客户端调用它的方法,它再传递给相应的子系统对象处理
  • SubSystem(子系统角色):子系统可以不是单独的类,而是类的集合,它实现子系统的功能,每个子系统都可以被客户端直接调用,或者被外观角色调用,对于子系统而言,外观角色也是一个客户端。

角色关系UML

设计模式-外观模式_ide

画图形为例子,画长方形,正方形,圆形

UML图如下

设计模式-外观模式_客户端_02

java代码

接口:

package demo9;

/**
*
* @ClassName: Shape
* @Description:图像接口
* @author cheng
* @date
public interface Shape

/**
*
* @Title: draw
* @Description:画图方法
*/
void

子系统角色

package demo9;

/**
*
* @ClassName: Rectangle
* @Description: 长方形
* @author cheng
* @date
public class Rectangle implements Shape

/**
* 复写
*/
@Override
public void draw() {
System.out.println("画一个长方形");
}

}
package demo9;

/**
*
* @ClassName: Square
* @Description:正方形
* @author cheng
* @date
public class Square implements Shape

/**
* 复写
*/
@Override
public void draw() {
System.out.println("画一个正方形");
}

}
package demo9;

/**
*
* @ClassName: Circle
* @Description:圆形
* @author cheng
* @date
public class Circle implements Shape

/**
* 复写
*/
@Override
public void draw() {
System.out.println("画一个圆形");
}

}

外观角色

package demo9;

/**
*
* @ClassName: ShapeMaker
* @Description:外观类
* @author cheng
* @date
public class ShapeMaker
private Shape rectangle;
private Shape square;
private Shape circle;

/**
* 构造方法
*/
public ShapeMaker() {
rectangle = new Rectangle();
square = new Square();
circle = new Circle();
}

/**
*
* @Title: drawRect
* @Description:画长方形
*/
public void drawRect() {
rectangle.draw();
}

/**
*
* @Title: drawSquare
* @Description:画正方形
*/
public void drawSquare() {
square.draw();
}

/**
*
* @Title: drawCircle
* @Description:画圆形
*/
public void drawCircle() {
circle.draw();
}

}

测试

package demo9;

/**
*
* @ClassName: ClientTest
* @Description:测试
* @author cheng
* @date
public class ClientTest

public static void main(String[] args) {
System.out.println("============不使用外观模式================");
//与三个类发生了耦合
Shape rectangle = new Rectangle();
Shape square = new Square();
Shape circle = new Circle();
rectangle.draw();
square.draw();
circle.draw();

System.out.println("============使用外观模式================");
//与一个类发生耦合
ShapeMaker shapeMaker = new

运行结果

设计模式-外观模式_客户端_03

优点

屏蔽子系统,减少客户端所需交互的对象,简化调用
降低客户端与子系统耦合,面对子系统变化,只需要调整外观类即可
子系统间的修改不会相互影响

缺点

不能很好限制客户端直接使用子系统类,对访问子系统类做过多限制则减少可变性和灵活性
设计不当时,增加新的子系统需要修改外观类源码,违背 开闭原则

使用场景

需要访问一系列子系统完成业务需求
客户端和多个子系统很高的耦合,使用外观模式解耦,提高子系统的独立性和可移植性
层次化结构中,使用外观模式定义系统中每层的入口,层与层之间不直接产生联系,通过外观类建立联系,降低层之间的耦合