场景问题
示例:组装电脑
通常一般来说有俩种方案,一种是自己组装,第二种是找到装机公司,告诉他们具体要求,然后等着拿电脑就好了,如果把上面的过程看作是一个系统,那么第二种方案的装机公司就相当于我们外观模式(facade)
不同场景下的解决方案
以代码生成工具为例,假使我们的代码生成工具生成的模块都具有三层架构(表现层,逻辑层,数据层)
我们要想实现这个简单的工具,需要描述配置的数据Model,获取配置信息的实现,逻辑层的实现,表现层的实现,即使我们这里不采用代码说明,我们也可以想象得出,客户端为了使用生成代码的功能,需要和代码子系统的多隔模块进行交互,这与客户端来说,是一个麻烦,系统的编程应该尽量解耦
解决方案
由此我们可以使用一个合理的解决方案那就是外观模式
是什么
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易利用
为什么
客户端想要操作简单一点,那就需要根据客户端的需要来客户端定义一个简单的接口,然后如客户端调用这个接口,当然这里的接口就是客户端与访问系统之间的通道(并不是特指java里的接口,在外观模式中,通常是类)
示例代码
定义模块A
* @author tan
*
*/
public interface AModelApi {
/**
* A 模块暴露的方法
*/
void testA();
}
模块A的实现
/**
* @author 谭婧杰
* @data 2020/1/14
*/
public class AModelApiImpl implements AModelApi {
@Override
public void testA() {
System.out.println("A 模块----------");
}
}
同样的定义模块B,这里不做说明
。。。。
定义外观类Facade
/**
* @author 谭婧杰
* @data 2020/1/14
* 外观对象
*/
public class Facade {
public void test () {
AModelApi a = new AModelApiImpl();
a.testA();
BModelApi b = new BModelApiImpl();
b.testB();
}
}
客户端调用
/**
* @author 谭婧杰
* @data 2020/1/14
*/
public class Client {
public static void main(String[] args) {
new Facade().test();
}
}
结果截图
模式详解
外观模式的目的不是为了给子系统添加新的功能接口,而是为了让外部减少与内部系统的多个模块的耦合,使外部更加容易的使用子系统,对于子系统来说,外观类不需要很多,通常可以实现为一个单例,也可以直接把外观中的方法实现为一个静态方法,认我们可以不创建实例直接调用,Fadace也可以实现为一个接口,但是这样会添加系统复杂度,因为我们需要一个实现来获取外观模式接口的对象
优点
- 松散耦合,松散了客户端与子系统之间的关系,让子系统内部更加容易扩展和维护
- 简单易用,客户端不需要了解子系统内部的实现
- 更好的划分访问层次
缺点
过多的Facade让系统更加复杂
本质
封装交换,简化调用
外观模式很好的体现了最少知识原则
来源:CSDN
作者:谭婧杰
链接:https://blog.csdn.net/qq_42236003/article/details/103967558