研磨设计模式之外观模式(Facade)(解决方案)
来源:互联网 发布:乐其网络 忽悠 编辑:程序博客网 时间:2024/05/17 23:51
3.2 解决方案
3.2.1 外观模式来解决
用来解决上述问题的一个合理的解决方案就是外观模式。那么什么是外观模式呢?
(1)外观模式定义
这里先对两个词进行一下说明,一个是界面,一个是接口。
界面
一提到界面,估计很多朋友的第一反应就是图形界面(GUI)。其实在这里提到的界面,主要指的是从一个组件外部来看这个组件,能够看到什么,这就是这个组件的界面,也就是所说的外观。
比如:你从一个类外部来看这个类,那么这个类的public方法就是这个类的外观,因为你从类外部来看这个类,就能看到这些。
再比如:你从一个模块外部来看这个模块,那么这个模块对外的接口就是这个模块的外观,因为你就只能看到这些接口,其它的模块内部实现的东西是被接口封装隔离了的。
接口
一提到接口,做Java的朋友的第一反应就是interface。其实在这里提到的接口,主要是指的外部和内部交互的这么一个通道,通常是指的一些方法,可以是类的方法,也可以是interface的方法。也就是说,这里说的接口,并不等价于interface,也有可能是一个类。
(2)应用外观模式来解决的思路
仔细分析上面的问题,客户端想要操作更简单点,那就根据客户端的需要来给客户端定义一个简单的接口,然后让客户端调用这个接口,剩下的事情就不用客户端管,这样客户端就变得简单了。
当然,这里所说的接口就是客户端和被访问的系统之间的一个通道,并不一定是指Java的interface。事实上,这里所说的接口,在外观模式里面,通常指的是类,这个类被称为“外观”。
外观模式就是通过引入这么一个外观类,在这个类里面定义客户端想要的简单的方法,然后在这些方法的实现里面,由外观类再去分别调用内部的多个模块来实现功能,从而让客户端变得简单,这样一来,客户端就只需要和外观类交互就可以了。
3.2.2 模式结构和说明
外观模式的结构如图3.4所示:
图3.4 外观模式结构示意图
Facade:
定义子系统的多个模块对外的高层接口,通常需要调用内部多个模块,从而把客户的请求代理给适当的子系统对象。
模块:
接受Facade对象的委派,真正实现功能,各个模块之间可能有交互。
但是请注意,Facade对象知道各个模块,但是各个模块不应该知道Facade对象。
3.2.3 外观模式示例代码
由于外观模式的结构图过于抽象,因此把它稍稍具体点,假设子系统内有三个模块,分别是AModule、BModule和CModule,它们分别有一个示意的方法,那么此时示例的整体结构如图3.5所示:
图3.5 外观模式示例的整体结构示意图
还是来看看代码示例,会比较清楚。
(1)首先定义A模块的接口,A模块对外提供功能方法,从抽象的高度去看,可以是任意的功能方法,示例代码如下:
/**
* A模块的接口
*/
public interface AModuleApi {
/**
* 示意方法,A模块对外的一个功能方法
*/
public void testA();
}
(2)实现A模块的接口, 简单示范一下,示例代码如下:
public class AModuleImpl implements AModuleApi{
public void testA() {
System.out.println("现在在A模块里面操作testA方法");
}
}
(3)同理定义和实现B模块、C模块,先看B模块的接口定义,示例代码如下:
public interface BModuleApi {
public void testB();
}
B模块的实现示意,示例代码如下:
public class BModuleImpl implements BModuleApi{
public void testB() {
System.out.println("现在在B模块里面操作testB方法");
}
}
C模块的接口定义,示例代码如下:
public interface CModuleApi {
public void testC();
}
C模块的实现示意,示例代码如下:
public class CModuleImpl implements CModuleApi{
public void testC() {
System.out.println("现在在C模块里面操作testC方法");
}
}
(4)定义外观对象,示例代码如下:
/**
* 外观对象
*/
public class Facade {
/**
* 示意方法,满足客户需要的功能
*/
public void test(){
//在内部实现的时候,可能会调用到内部的多个模块
AModuleApi a = new AModuleImpl();
a.testA();
BModuleApi b = new BModuleImpl();
b.testB();
CModuleApi c = new CModuleImpl();
c.testC();
}
}
(5)客户端如何使用呢,直接使用外观对象就可以了,示例代码如下:
public class Client {
public static void main(String[] args) {
//使用Facade
new Facade().test();
}
}
运行结果如下:
现在在A模块里面操作testA方法
现在在B模块里面操作testB方法
现在在C模块里面操作testC方法
3.2.4 使用外观模式重写示例
要使用外观模式重写前面的示例,其实非常简单,只要添加一个Facade的对象,然后在里面实现客户端需要的功能就可以了。
(1)新添加一个Facade对象,示例代码如下:
/**
* 代码生成子系统的外观对象
*/
public class Facade {
/**
* 客户端需要的,一个简单的调用代码生成的功能
*/
public void generate(){
new Presentation().generate();
new Business().generate();
new DAO().generate();
}
}
(2)其它的定义和实现都没有变化,这里就不去赘述了
(3)看看此时的客户端怎么实现,不再需要客户端去调用子系统内部的多个模块,直接使用外观对象就可以了,示例代码如下:
public class Client {
public static void main(String[] args) {
//使用Facade
new Facade().generate();
}
}
去运行看看,是否能正确地实现功能。
如同上面讲述的例子,Facade类其实相当于A、B、C模块的外观界面,Facade类也被称为A、B、C模块对外的接口,有了这个Facade类,那么客户端就不需要知道系统内部的实现细节,甚至客户端都不需要知道A、B、C模块的存在,客户端只需要跟Facade类交互就好了,从而更好的实现了客户端和子系统中A、B、C模块的解耦,让客户端更容易的使用系统。
本文链接:研磨设计模式之外观模式(Facade)(解决方案),转自:http://sishuok.com/forum/blogPost/list/5063.html
如非特别注明,本站内容均为领悟书生原创,转载请务必注明作者和原始出处。
本文地址:http://www.656463.com/article/fQNnqq.htm
- 研磨设计模式之外观模式(Facade)(解决方案)
- 研磨设计模式之外观模式(Facade)(模式讲解)
- 研磨设计模式之外观模式(Facade)(场景问题)
- 设计模式之Facade(外观)
- 设计模式之Facade(外观)
- 设计模式之Facade (外观)
- 设计模式之Facade模式(外观模式)
- 设计模式之Facade外观模式
- 设计模式之Facade(外观)模式
- 设计模式之外观(Facade)模式
- 设计模式学习之---Facade(外观)模式
- 设计模式之Facade-外观模式
- 设计模式之八、外观模式Facade
- 设计模式之(五)外观模式Facade
- 设计模式之外观模式(Facade)
- 设计模式之外观模式(Facade Pattern)
- 设计模式之九 --- 外观(Facade)模式
- 浅学设计模式之外观<Facade>模式
- java处理ip的工具类
- 微软高管:Win8用户可免费升级Win9系统
- 关于C++中的大小端、位段(惑位域)和内存对齐
- 大型网站系统架构演化之路
- 撒旦法色特认识她让一个人个人铜火锅热天和让他和他鸡同鸭讲
- 研磨设计模式之外观模式(Facade)(解决方案)
- cocos2d基础
- 关于ASP.NET 中使用Ajax进行异步调用问题,前台参数无法跳转到后台,提示500 internal server error
- Commons CLI使用详解
- 第一篇
- 在线教育进入调整期:资本疯狂期即将结束
- 九度OJ1512:用两个栈实现队列
- UIButton文字的对齐方式
- 无所谓在不在乎