6外观模式
外观模式
外观模式(Facade Pattern) 也叫门面模式,是一种比较常见并且很简单的设计模式。
1外观模式的定义
外观模式的英文原文是:
Provide a unified interface to a set of interface in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
意思是:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供一个高层次的接口,使得子系统更易使用。
外观模式注重“统一的对象”,即提供一个访问子系统的接口,只有通过该接口(facade)才能允许访问子系统的行为发生。
外观模式具有2个角色:
- 外观(Facade)角色:客户端可以调用该角色的方法,该角色知晓相关子系统的功能和职责。正常情况下本角色会将所有从客户端发来的请求委派到相应的子系统,即该角色没有实际的业务逻辑,只是一个委托类。
- 子系统(Subsystem)角色:可以同时有一个或多个子系统,每一个子系统都不是一个单独的类,而是一个类集合。子系统不知道外观角色的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。
由于子系统是一个类的集合,此处使用3个无关的类进行代表。
创建三个无关类
package com.eric.结构型模式.门面模式.引例;
import javax.xml.transform.Source;
/**
* @author Eric
* @ProjectName my_design_23
* @description 子系统
* @CreateTime 2020-12-02 18:04:23
*/
public class ClassA {
public void methodA(){
System.out.println("A的方法A");
}
}
class ClassB {
public void methodB(){
System.out.println("B的方法B");
}
}
class ClassC {
public void methodC(){
System.out.println("C的方法C");
}
}
门面对象
Facade.java
package com.eric.结构型模式.门面模式.引例;
import com.sun.org.apache.bcel.internal.generic.NEW;
/**
* @author Eric
* @ProjectName my_design_23
* @description 外观角色
* @CreateTime 2020-12-02 18:29:36
*/
public class Facade {
//被委托的对象
private ClassA a = new ClassA();
private ClassB b = new ClassB();
private ClassC c = new ClassC();
//提供外界的方法
public void methodA(){
a.methodA();
}
public void methodB(){
b.methodB();
}
public void methodC(){
c.methodC();
}
}
2外观模式的应用
a.外观模式的优点
- 减少系统的额相互依赖,所有的依赖都是对Facade对象的依赖,与子系统无关。
- 提高灵活性,不管子系统内部如何变化,只要不影响Facade对象,任何活动都是自由的。
- 提高安全性,Facade中未提供的方法,外界就无法访问,提高系统的安全性。
注意:外观模式最大的缺点是不符合开闭原则的,对修改关闭,对扩展开放。
b.外观模式的使用场景
- 为一个复杂的模块或子系统提供一个共外界访问的接口。
- 子系统相对独立,外界对子系统的访问只要黑箱操作即可。
- 预防风险扩散,使用Facade进行访问控制。
c.现实场景
- 去医院看病,可能要去挂号、门诊、划价、取药,让患者或家属觉得很复杂,如果有接待人员,只让接待人员处理,就很方便。
- java的三层开发模式。
3外观模式的实例
使用外观模式模拟秘书为老板工作的过程。
机场类、酒店类、宾馆类、司机类四个组成一个子系统集;秘书类是一个外观角色类,对子系统中的4个类进行引用;老板类无需知道子系统的各个类,只通过秘书安排工作即可。
Airport.java
package com.eric.结构型模式.门面模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 机场类
* @CreateTime 2020-12-02 18:53:22
*/
public class Airport {
public void bookTicket(String from,String to){
System.out.println("订购了从"+from+"到"+to+"的机票");
}
}
Hotel.java
package com.eric.结构型模式.门面模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 宾馆类
* @CreateTime 2020-12-02 18:56:21
*/
public class Hotel {
public void reserve(int days){
System.out.println("预定了"+days+"天的双人间");
}
}
Restaurant.java
package com.eric.结构型模式.门面模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 酒店类
* @CreateTime 2020-12-02 18:55:02
*/
public class Restaurant {
public void reserve(int num){
System.out.println("定了一桌"+num+"人的酒席。");
}
}
Chauffeur.java
package com.eric.结构型模式.门面模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 司机类
* @CreateTime 2020-12-02 18:57:41
*/
public class Chauffeur {
public void drive(String to){
System.out.println("司机开车到"+to);
}
}
创建秘书类
Secretary.java
package com.eric.结构型模式.门面模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 秘书类
* @CreateTime 2020-12-02 18:58:34
*/
public class Secretary {
private Chauffeur chauffeur = new Chauffeur();
private Hotel hotel = new Hotel();
private Restaurant restaurant = new Restaurant();
private Airport airport = new Airport();
//安排出差
public void trip(String to,int days){
airport.bookTicket("青岛",to);
chauffeur.drive("机场");
hotel.reserve(days);
}
//安排饭局
public void repast(int num){
restaurant.reserve(num);
chauffeur.drive("酒店");
}
}
测试类
Boss.java
package com.eric.结构型模式.门面模式.例1;
import jdk.management.resource.internal.inst.SocketOutputStreamRMHooks;
/**
* @author Eric
* @ProjectName my_design_23
* @description 老板使用秘书
* @CreateTime 2020-12-02 19:13:29
*/
public class Boss {
public static void main(String[] args) {
Secretary secretary = new Secretary();
System.out.println("老板告诉秘书要到上海出差10天...");
secretary.trip("上海",10);
System.out.println("-------------------------------");
System.out.println("老板告诉秘书要请8个人吃饭...");
secretary.repast(8);
}
}
测试结果
只要你不停下来,慢一点也没关系。