[23种设计模式][结构型]19.门面模式

83 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情

1.门面模式(Facade)或外观模式:

  • 在软件开发系统中,客户程序经常与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化。那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦?这就是要说的Facade模式。
  • 位子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

2.门面(Facade)模式的构成:

  • 门面类(Facade):
    • 知道哪些子系统负责处理哪些请求
    • 将客户的请求传递给相应的子系统对象进行处理
  • 子系统类(SubSystem):
    • 实现子系统的功能
    • 处理由Facade传递过来的任务
    • 子系统无需知道Facade的存在,在任何地方都没有引用Facade

3.门面模式的要点:

  1. Facade模式对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
  2. Facade模式实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。
  3. 如果应用需要,它并不限制它们使用子系统类,因此你可以在系统易用性和通用性之间选择。

4.门面模式的适用性:

  1. 为一个复杂子系统提供一个简单接口。
  2. 提高子系统的独立性。
  3. 在层次化结构中,可以使用Facade模式定义系统中每一层的入口。

5.门面模式UML类图:

Image.png

6.门面模式UML序列图:

Image.png

7.代码示例:

Image.png 学生实体:

public class Student {

    public int age;
    public char sex;

    public Student(int age, char sex) {
        this.age = age;
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }
}

子系统:

public class SubSystem1 {

    public boolean isAgeValid(Student student) {
        if (student.getAge() > 18) {
            return true;
        } else {
            return false;
        }
    }
}
public class SubSystem2 {

    public boolean isSexValid(Student student) {
        if ('M' == student.getSex()) {
            return true;
        } else {
            return false;
        }
    }
}

门面:

public class Facade {

    public boolean isValid(Student student) {
        SubSystem1 sub1 = new SubSystem1();
        SubSystem2 sub2 = new SubSystem2();

        return sub1.isAgeValid(student) && sub2.isSexValid(student);
    }
}

客户角色:

public class Client {

    public static void main(String[] args) {

        Student student = new Student(20, 'M');

//        SubSystem1 sub1 = new SubSystem1();
//        SubSystem2 sub2 = new SubSystem2();
//
//        boolean flag = sub1.isAgeValid(student) && sub2.isSexValid(student);

        Facade facade = new Facade();
        boolean flag = facade.isValid(student);

        System.out.println(flag ? "valid" : "invalid");
    }
}