设计模式——外观模式

设计模式——外观模式

本篇博文通过学习尚硅谷韩顺平老师《设计模式》课程所做,在此非常感谢!

概述

基本介绍

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

细节和注意事项

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

UML
在这里插入图片描述

问题引入

组建一个家庭影院:DVD 播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能,其过程为: 一、(开爆米花机、放下屏幕、打开投影仪、打开音响) ——> 二、(暂停播放) ——> 三、(去拿爆米花、调暗灯光、继续播放DVD) ——> 四、(观影结束后,关闭各种设备)

要求使用外观模式实现上述的需求,保证客户端调用足够简单;

编码实现

UML

首先我们构造出UML图,如下所示:
在这里插入图片描述

编码

首先创建我们所有需要使用的系统类,如灯光类DVD 类爆米花机类等,如下所示:

package edu.hebeu.appearance.childsys;

public class DVDPlayer {
	
	private static DVDPlayer instance = new DVDPlayer();
	
	private DVDPlayer() {}
	
	public static DVDPlayer getInstance() {
		return instance;
	}
	
	public void on() {
		System.out.println("DVD开启...");
	}
	
	public void off() {
		System.out.println("DVD关闭");
	}
	
	public void play() {
		System.out.println("DVD正在播放...");
	}
	
	public void pause() {
		System.out.println("DVD暂停");
	}
	
	public void set() {
		System.out.println("DVD选择节目...");
	}
	
	// ......
	
}

package edu.hebeu.appearance.childsys;

public class Light {

	private static Light instance = new Light();
	
	private Light() {}
	
	public static Light getInstance() {
		return instance;
	}
	
	public void on() {
		System.out.println("灯光打开...");
	}
	
	public void off() {
		System.out.println("灯光关闭");
	}
	
	public void dim() {
		System.out.println("灯光调暗...");
	}
	
	public void bright() {
		System.out.println("灯光调亮...");
	}
	
	// ......
	
}

package edu.hebeu.appearance.childsys;

public class Popcorn {
	
	private static Popcorn instance = new Popcorn();
	
	private Popcorn() {}
	
	public static Popcorn getInstance() {
		return instance;
	}
	
	public void on() {
		System.out.println("爆米花机打开...");
	}
	
	public void off() {
		System.out.println("爆米花机关闭");
	}
	
	public void pop() {
		System.out.println("爆米花机正在出爆米花...");
	}
	
	// ......
	
}

package edu.hebeu.appearance.childsys;

public class Projector {
	
	private static Projector instance = new Projector();
	
	private Projector() {}
	
	public static Projector getInstance() {
		return instance;
	}
	
	public void on() {
		System.out.println("投影仪打开...");
	}
	
	public void off() {
		System.out.println("投影仪关闭");
	}
	
	public void fox() {
		System.out.println("投影仪正在聚焦...");
	}
	
	// ......
	
}

package edu.hebeu.appearance.childsys;

public class Screen {
	
	private static Screen instance = new Screen();
	
	private Screen() {}
	
	public static Screen getInstance() {
		return instance;
	}
	
	public void up() {
		System.out.println("屏幕收起");
	}
	
	public void down() {
		System.out.println("屏幕放下");
	}
	
	// ......
	
}

package edu.hebeu.appearance.childsys;

public class Stereo {

	private static Stereo instance = new Stereo();
	
	private Stereo() {}
	
	public static Stereo getInstance() {
		return instance;
	}
	
	public void on() {
		System.out.println("立体声打开...");
	}
	
	public void off() {
		System.out.println("立体声关闭");
	}
	
	public void up() {
		System.out.println("立体声调大...");
	}
	
	public void down() {
		System.out.println("立体声调小...");
	}
	
	// ......
	
}

此时所有的系统类就创建完毕了,之后我们创建本模式中的外观类,用来给使用方提供统一的接口,抽取特定的方法,为使用方屏蔽掉内部复杂的细节

package edu.hebeu.appearance;

import edu.hebeu.appearance.childsys.DVDPlayer;
import edu.hebeu.appearance.childsys.Light;
import edu.hebeu.appearance.childsys.Popcorn;
import edu.hebeu.appearance.childsys.Projector;
import edu.hebeu.appearance.childsys.Screen;
import edu.hebeu.appearance.childsys.Stereo;

public class HomeAppearance {
	
	private DVDPlayer dvdPlayer;
	private Popcorn popcorn;
	private Projector projector;
	private Screen screen;
	private Stereo stereo;
	private Light light;
	
	public HomeAppearance() {
		dvdPlayer = DVDPlayer.getInstance();
		popcorn = Popcorn.getInstance();
		projector = Projector.getInstance();
		screen = Screen.getInstance();
		stereo = Stereo.getInstance();
		light = Light.getInstance();
	}
	
	public void ready() {
		popcorn.on();
		screen.down();
		projector.on();
		stereo.on();
		dvdPlayer.on();
		dvdPlayer.set();
	}
	
	public void off() {
		dvdPlayer.off();
		popcorn.off();
		projector.off();
		screen.up();
		stereo.off();
		light.off();
	}
	
	public void play() {
		popcorn.pop();
		light.on();
		light.dim();
		dvdPlayer.play();
	}
	
	public void pause() {
		dvdPlayer.pause();
	}
	
}

此时,外观模式的搭建就完成了,我们可以通过如下的测试类进行调用测试

package edu.hebeu.appearance;

public class Client {
	public static void main(String[] args) throws InterruptedException {
		HomeAppearance homeAppearance = new HomeAppearance();
		homeAppearance.ready();
		System.out.println(); System.out.println();
		Thread.sleep(1500);
		
		homeAppearance.pause();
		System.out.println(); System.out.println();
		Thread.sleep(1500);
		
		homeAppearance.play();
		System.out.println(); System.out.println();
		Thread.sleep(2000);
		
		homeAppearance.off();
	}
}

测试

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值