业务场景
教师若想开设一门新课,需要经过以下步骤:
1、填写申请表系里审查。
2、院长审核。
3、教务处审批。
public class Teacher {
public static void main(String[] args) {
Course course = new Course("商务英语");
new Department().audit(course);
new Dean().audit(course);
new DeanSOffice().audit(course);
}
}
@Data
@AllArgsConstructor(access = AccessLevel.PUBLIC)
@NoArgsConstructor
/**
* 普通课程
*/
class Course {
/**
* 课程名称
*/
private String courseName;
}
@Slf4j
class Department{
public void audit(Course course){
log.info("系里审核{}",course.getCourseName());
}
}
@Slf4j
class Dean{
public void audit(Course course){
log.info("院长审核{}",course.getCourseName());
}
}
@Slf4j
class DeanSOffice{
public void audit(Course course){
log.info("教务处审批{}",course.getCourseName());
}
}
上述示例存在的问题,教师为了申请开一门新课,需要与多个部门打交道。对于教师而言,很麻烦,而且如果流程变了,教师类必须修改。
使用外观模式
其他类不变,只添加新的外观类和修改Teacher类:
public class Teacher {
public static void main(String[] args) {
Course course = new Course("商务英语");
new Facade().applyNewCourse(course);
}
}
class Facade{
public void applyNewCourse(Course course){
new Department().audit(course);
new Dean().audit(course);
new DeanSOffice().audit(course);
}
}
看着相当于仅仅是把Teacher申请课程的代码挪到Facade里去了,但实质上是发生了变化了的。Facade是内部教务管理系统对教师开放的便捷接口,将教师和内部教务管理系统解耦,是Teacher的助手。
外观模式概述
定义
为子系统中的一组接口提供一个一致的高层接口,使子系统更加容易使用。
UML
public class AModule {
void methodA(){
System.out.println("A模块方法");
}
}
class BModule {
void methodB(){
System.out.println("B模块方法");
}
}
class CModule {
void methodC(){
System.out.println("C模块方法");
}
}
class Facade{
void method(){
AModule a = new AModule();
BModule b = new BModule();
CModule c = new CModule();
a.methodA();
b.methodB();
c.methodC();
}
}
class Test{
public static void main(String[] args) {
new Facade().method();
}
}
优缺点
1、松散耦合。松散了Client和Server子系统的耦合关系,Server子系统维护不会影响Client。
2、合理的划分访问层次。对外的接口和对内的接口区分开。符合迪米特法则。
3、过多的Facade容易让人迷惑,不如直接调用子系统内部接口清晰易理解。
4、在维护一个遗留的大型系统时,原系统已经难以维护和扩展,可以考虑开发Facade简单调用。
应用场景
1、为一个复杂的子系统提供一个简单的接口。简化客户端调用。
2、松散Client和Server耦合。
3、构建多层结构的系统,层与层之间通过Facade调用,松散依赖关系。
示例
摘自MyBatis源码。