外观模式即系统很复杂的时候,客户端与系统各个业务类亲自交互也会显得相当复杂,为了降低各个类之间的耦合度,使程序结构变得清晰,外观模式提供了一个外观角色来统一和客户端交互,而复杂的业务类只需和外观角色交互即可。
这个外观怎么理解呢?某个系统存在一群复杂的业务交互,但这些业务交互对于客户端而言都看不到,客户端能看到的就是这个外观类,外观类负责在外面挡风遮雨,在客户端来看,它就是复杂业务的外观。
外观模式UML类图:
实例代码:
抽象外观类:
public abstract class AbstractFacade {
public abstract void runSystem();
}
具体外观类:
/*****
* 外观类
* @author wjw
*
*/
public class FacadeA extends AbstractFacade{
SubSystemA sa;
SubSystemB sb;
SubSystemC sc;
public FacadeA(){
sa = new SubSystemA();
sb = new SubSystemB();
sc = new SubSystemC();
}
@Override
public void runSystem() {
// TODO Auto-generated method stub
sa.method();
sb.method();
sc.method();
}
}
子系统A类:
public class SubSystemA{
public void method() {
// TODO Auto-generated method stub
System.out.println("运行A系统!");
}
}
子系统B类:
public class SubSystemB{
public void method() {
// TODO Auto-generated method stub
System.out.println("运行B系统!");
}
}
子系统C类:
public class SubSystemC{
public void method() {
// TODO Auto-generated method stub
System.out.println("运行C系统!");
}
}
Main类:
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class facadeClazz = Class.forName(ReadProperties.readProperties("facade_name"));
AbstractFacade af = (AbstractFacade)facadeClazz.newInstance();
af.runSystem();
}
}
运行结果:
运行A系统!
运行B系统!
运行C系统!
我们使用外观模式,为什么使用呢,因为有好处,比如我们如果不用外观模式,那么客户端调用ABC三个子系统分别new这三个对象,与这三个对象发生耦合,而使用外观模式呢,我们客户端类仅仅与外观类发生耦合,大大降低了耦合性,使编程过程变得简单。另外抽象外观类的好处是易扩展,比如我们还有一个子系统D类,我们想使用它的功能,只需添加SubSystemD和一个外观类FacadeB类,修改一下配置文件,不用修改源代码,这属于对扩展开放,对修改关闭。
在这里说一下外观模式和代理模式的区别,其实,模糊来看,外观模式和代理模式都是提供一个中间类来代替访问真实类,但从目的性上来说却不一样,看外观模式和代理模式UML类图,其实还是有相似的,不同的是,代理模式代理类和真实类要实现相同的接口,为什么外观模式不用呢,这就是他俩的差异了:
外观模式的目的是降低系统复杂程度,外观类用来整合系统,所以他的系统类(说不定有什么系统功能呢)属于散养,而代理模式目的就是代理,为了从代理类精确打击真实类,所以二者要实现相同接口。
如果不使用外观模式,我们可以绕过外观类直接使用客户端访问子系统类,虽然这样会使系统显得复杂,但功能无影响。
而代理模式讲究的就是这个代理过程,一般情况下我们会在代理过程中添加一些日志功能、权限功能,如果我们绕过代理类,那么我们系统功能就会被更改。
总结一句就是:使不使用外观模式功能无影响,但复杂程度有影响。使不使用代理模式复杂程度无影响但功能有影响。
如有错误,欢迎指正
end