第三代半导体 maven 电力杆 全局重载运算符 performance interface pygame x86 gulp xampp air Avalon erp系统源码 jquery获取元素宽度 hadoop创建文件夹 xcode打包 winbox使用教程 bootstrap颜色 python的数据类型 python内置库 python加入环境变量 java的包 java表达式 java的数据结构 java时间格式化 java循环list java字符串相等 linuxgrep ie模拟器 python队列 渐变事件 winterboard 通讯录管理系统 彩虹岛小草黑暗之矛 狮子狗皮肤 小度音箱app js刷新当前页 绘图软件下载 操作系统安装 kmplayer绿色版
当前位置: 首页 > 学习教程  > 编程语言

【大话设计模式-12】外观模式(案例解析)

2020/7/24 10:54:29 文章标签:

文章目录

    • 1 影院管理项目
    • 2 传统方式解决影院管理
    • 3 传统方式解决影院管理问题分析
    • 4 外观模式基本介绍
    • 5 外观模式原理类图
    • 6 外观模式解决影院管理
      • 6.1 传统方式解决影院管理说明
      • 6.2 外观模式应用实例
    • 7 外观模式在 MyBatis 框架应用的源码分析
    • 8 外观模式的注意事项和细节

1 影院管理项目

组建一个家庭影院:
DVD 播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能,其过程为:
直接用遥控器:统筹各设备开关
开爆米花机
放下屏幕
开投影仪
开音响
开 DVD,选 dvd
去拿爆米花
调暗灯光
播放
观影结束后,关闭各种设备

2 传统方式解决影院管理

在这里插入图片描述

3 传统方式解决影院管理问题分析

  1. 在 ClientTest 的 main 方法中,创建各个子系统的对象,并直接去调用子系统(对象)相关方法,会造成调用过程混乱,没有清晰的过程
  2. 不利于在 ClientTest 中,去维护对子系统的操作
  3. 解决思路:定义一个高层接口,给子系统中的一组接口提供一个一致的界面(比如在高层接口提供四个方法ready, play, pause, end ),用来访问子系统中的一群接口
  4. 也就是说 就是通过定义一个一致的接口(界面类),用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节 => 外观模式

4 外观模式基本介绍

  1. 外观模式(Facade),也叫“过程模式:外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
  2. 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节

5 外观模式原理类图

在这里插入图片描述
对类图说明(分类外观模式的角色)

  1. 外观类(Facade): 为调用端提供统一的调用接口, 外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象
  2. 调用者(Client): 外观接口的调用者
  3. 子系统的集合:指模块或者子系统,处理 Facade 对象指派的任务,他是功能的实际提供者

6 外观模式解决影院管理

6.1 传统方式解决影院管理说明

  1. 外观模式可以理解为转换一群接口,客户只要调用一个接口,而不用调用多个接口才能达到目的。比如:在 pc上安装软件的时候经常有一键安装选项(省去选择安装目录、安装的组件等等),还有就是手机的重启功能(把关机和启动合为一个操作)。
  2. 外观模式就是解决多个复杂接口带来的使用困难,起到简化用户操作的作用
  3. 示意图说明
    在这里插入图片描述

6.2 外观模式应用实例

  1. 应用实例要求
  2. 使用外观模式来完成家庭影院项目
  3. 思路分析和图解(类图)
    在这里插入图片描述
    DVD机
package com.atguigu.facade;
public class DVDPlayer {
	//使用单例模式, 使用饿汉式
	private static DVDPlayer instance = new DVDPlayer();
	public static DVDPlayer getInstanc() {
		return instance;
	}
	//打开
	public void on() {
		System.out.println(" dvd on ");
	}
	//关闭
	public void off() {
		System.out.println(" dvd off ");
	}
	//运行
	public void play() {
		System.out.println(" dvd is playing ");
	}
	//暂停
	public void pause() {
		System.out.println(" dvd pause ..");
	}
}

爆米花机

package com.atguigu.facade;
public class Popcorn {
	private static Popcorn instance = new Popcorn();
	public static Popcorn getInstance() {
		return instance;
	}
	//打开
	public void on() {
		System.out.println(" popcorn on ");
	}
	//关闭
	public void off() {
		System.out.println(" popcorn ff ");
	}
	//出爆米花
	public void pop() {
		System.out.println(" popcorn is poping ");
	}
}

投影仪

package com.atguigu.facade;
public class Projector {
	private static Projector instance = new Projector();
	public static Projector getInstance() {
		return instance;
	}
	public void on() {
		System.out.println(" Projector on ");
	}
	public void off() {
		System.out.println(" Projector ff ");
	}
	//聚焦
	public void focus() {
		System.out.println(" Projector is Projector ");
	}
}

屏幕

package com.atguigu.facade;
public class Screen {
	private static Screen instance = new Screen();
	public static Screen getInstance() {
		return instance;
	}
	//升屏幕
	public void up() {
		System.out.println(" Screen up ");
	}
	public void down() {
		System.out.println(" Screen down ");
	}
}

立体声

package com.atguigu.facade;
public class Stereo {
	private static Stereo instance = new Stereo();
	public static Stereo getInstance() {
		return instance;
	}
	public void on() {
		System.out.println(" Stereo on ");
	}
	public void off() {
		System.out.println(" Screen off ");
	}
	//
	public void up() {
		System.out.println(" Screen up.. ");
	}
}

影院灯光

package com.atguigu.facade;
public class TheaterLight {
	private static TheaterLight instance = new TheaterLight();
	public static TheaterLight getInstance() {
		return instance;
	}
	public void on() {
		System.out.println(" TheaterLight on ");
	}
	public void off() {
		System.out.println(" TheaterLight off ");
	}
	//调暗
	public void dim() {
		System.out.println(" TheaterLight dim.. ");
	}
	//调亮
	public void bright() {
		System.out.println(" TheaterLight bright.. ");
	}
}

外观类

package com.atguigu.facade;
public class HomeTheaterFacade {
	//定义各个子系统对象
	private TheaterLight theaterLight;
	private Popcorn popcorn;
	private Stereo stereo;
	private Projector projector;
	private Screen screen;
	private DVDPlayer dVDPlayer;
	//构造器 初始化
	public HomeTheaterFacade() {
		super();
		this.theaterLight = TheaterLight.getInstance();
		this.popcorn = Popcorn.getInstance();
		this.stereo = Stereo.getInstance();
		this.projector = Projector.getInstance();
		this.screen = Screen.getInstance();
		this.dVDPlayer = DVDPlayer.getInstanc();
	}
	//操作分成 4 步
	public void ready() {
		popcorn.on();
		popcorn.pop();
		screen.down();
		projector.on();
		stereo.on();
		dVDPlayer.on();
		theaterLight.dim();
	}
	public void play() {
		dVDPlayer.play();
	}
	public void pause() {
		dVDPlayer.pause();
	}
	public void end() {
		popcorn.off();
		theaterLight.bright();
		screen.up();
		projector.off();
		stereo.off();
		dVDPlayer.off();
	}
}
package com.atguigu.facade;
public class Client {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//这里直接调用。。 很麻烦
		HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
		homeTheaterFacade.ready();
		homeTheaterFacade.play();
		homeTheaterFacade.end();
	}
}

7 外观模式在 MyBatis 框架应用的源码分析

  1. MyBatis 中的 Configuration 去创建 MetaObject 对象使用到外观模式

  2. 代码分析+Debug 源码+示意图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  3. 对源码中使用到的外观模式的角色类图
    在这里插入图片描述

8 外观模式的注意事项和细节

  1. 外观模式对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统使用的复杂性
  2. 外观模式对客户端与子系统的耦合关系 - 解耦,让子系统内部的模块更易维护和扩展
  3. 通过合理的使用外观模式,可以帮我们更好的划分访问的层次
  4. 当系统需要进行分层设计时,可以考虑使用 Facade 模式
  5. 在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个Facade 类,来提供遗留系统的比较清晰简单的接口,让新系统与 Facade 类交互,提高复用性
  6. 不能过多的或者不合理的使用外观模式,使用外观模式好,还是直接调用模块好。要以让系统有层次,利于维护为目的。

本文链接: http://www.dtmao.cc/news_show_50357.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?