【08】结构型-外观Facade模式

一、上下文及问题

1、基本原则

     系统与其他外部系统交互,有时候操作比较复杂,需要一个防腐层来增强本系统与其他系统的耦合性,对本系统封装一些对外操作的细节,达到简化的目的。

     符合最少知识原则,即Least Knowledge Principle,也成为迪米特原则,Law of Demeter。


2、定义

为子系统中的一组接口提供一个一直的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

(1)界面:从一个组件外部来看这个组件,能够看到什么,就是这个组件的界面,即外观。

比如,你从一个类的外部来看这个类,那么这个类的public方法就是这个类的外观;

比如,你从一个模块外部来看这个模块,那么这个模块对外的接口就是这个模块的外观。

(2)接口:外部和内部交互的一个通道,通常是指一些方法,可以是类方法,也可以是interface方法


二、常见场景

1、系统对外部系统调用的Facade,内部系统只依赖于Facade的方法,其里头再调用外部接口,达到防腐的目的,也达到了屏蔽一些外部接口的调用细节,比如封装异常,分步调用等

2、EJB的Session Facade,对客户端屏蔽了远程调用操作,减少客户端与服务对象之间的依赖程度,把底层服务对象的接口和它们之间的复杂依赖交互通过Facade隐藏起来。


三、解决方法

      外观模式的目的不是给子系统添加新的功能接口,而是为了让外部减少与子系统内部多个模块的交互,松散耦合,从而让外部能够更简单地使用子系统。

      但是外观模式不阻止客户端直接调用子模块的功能,它只是提供了一个缺省的功能实现。对外屏蔽子系统: 如果把Facade实现成为接口,还附带一个功能,就是能够有选择性地暴露接口的方法,尽量减少模块对子系统外提供的接口方法。


四、抽象模型

【08】结构型-外观Facade模式

五、代码实例 

1、模块

/**
* A模块
*/
public interface AModuleApi {
    /**
     * 示意方法,A模块对外的一个功能方法
     */
    public void testA();
}

public class AModuleImpl implements AModuleApi{
    public void testA() {
        System.out.println("现在在A模块里面操作testA方法");
    }
}

/**
* B模块
*/
public interface BModuleApi {
    public void testB();
}

public class BModuleImpl implements BModuleApi{
    public void testB() {
        System.out.println("现在在B模块里面操作testB方法");
    }

}

/**
* C模块
*/
public interface CModuleApi {
    public void testC();
}

public class CModuleImpl implements CModuleApi{
    public void testC() {
        System.out.println("现在在C模块里面操作testC方法");
    }

}


2、Facade

public class Facade {
    //被委托的对象
    private ClassA a = new ClassA();
    private ClassB b = new ClassB();
    private ClassC c = new ClassC();

    //提供给外部访问的方法
    public void methodA(){
        this.a.doSomethingA();
    }

    public void methodB(){
        this.b.doSomethingB();
    }

    public void methodC(){
        this.c.doSomethingC();
    }
}


3、Client

public class Client {
    public static void main(String[] args) {
//        //不用Facade,需要自己跟多个模块交互
//        AModuleApi a = new AModuleImpl();
//        a.testA();
//        BModuleApi b = new BModuleImpl();
//        b.testB();
//        CModuleApi c = new CModuleImpl();
//        c.testC();
//        
//        System.out.println("使用Facade----------------------〉");
        //使用了Facade
        new Facade().test();        
    }
}


你可能感兴趣的:(【08】结构型-外观Facade模式)