设计模式之适配器与外观模式(二)

好了,经过上次的学习,咱们已经知道适配器模式是如何将一个类的接口转换成另外一个符合客户指望的接口。同时也知道在Java中要作到这一点,必须将一个不兼容接口的对象包装起来,变成兼容的对象。编程

咱们如今要看一个改变接口的新模式,可是它改变接口的缘由是为了简化接口。这个模式被巧妙地命名为外观模式(Facade-Pattern),之因此这么称呼,是由于它将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观。ide

繁琐的看电影步骤

还记得咱们以前说过的命令模式中,一个遥控器能控制不少家电的过程吧。简单的开关咱们都会,复杂的模式,就比较麻烦,好比看电影的步骤:工具

  1. 打开爆米花机
  2. 开始爆米花
  3. 将灯光调暗
  4. 放下屏幕
  5. 打开投影机
  6. 将投影机的输入切换到DVD
  7. 将投影机设置在宽屏模式
  8. 打开功放
  9. 将功放的输入设置为DVD
  10. 将攻放设置为环绕立体声
  11. 将攻放音量调到中
  12. 打开DVD播放器
  13. 开始播放DVD

看一个电影,真的是如此繁琐。并且看完电影以后,还得过去把这些步骤都关闭。是用你的家庭影院居然变得如此复杂!让咱们看看外观模式如何解决这团混乱,好让你轻松享受。学习

灯光、相机、外观!

你须要的正是一个外观:有了外观模式,经过实现一个提供更合理的接口的外观类,你能够将一个复杂的子系统变得容易使用。this

  1. 咱们为家庭影院系统建立一个外观,命名为HomeTheaterFacade,它对外暴露出几个简单的方法,例如watchMovie()
  2. 这个外观类将家庭影院诸多组件视为一个子系统,经过调用这个子系统,来实现watchMovie()方法
  3. 如今,你的客户代码能够调用此家庭影院外观所提供的方法,而没必要再调用这个子系统的方法。
  4. 外观只是提供你更直接的操做,并未将原来的子系统阻隔起来。若是你须要子系统类的更高层的功能呢,仍是可使用原来的子系统的

构造家庭影院外观

好了,那接下来就到实战阶段啦。spa

第一步是使用组合让外观可以访问子系统中全部的组件设计

public class HomeTheaterFacade {
	Amplifier amp;
	Tuner tuner;
	DvdPlayer dvd;
	CdPlayer cd;
	Projector projector;
	TheaterLights lights;
	Screen screen;
	PopcornPopper popper;
 
	public HomeTheaterFacade(Amplifier amp, Tuner tuner, DvdPlayer dvd, CdPlayer cd, Projector projector, Screen screen, TheaterLights lights, PopcornPopper popper) {
 
		this.amp = amp;
		this.tuner = tuner;
		this.dvd = dvd;
		this.cd = cd;
		this.projector = projector;
		this.screen = screen;
		this.lights = lights;
		this.popper = popper;
	}
 
    // 将咱们以前手动进行的每项任务依次处理。这里每项任务都是委托子系统中相应的组件处理的
	public void watchMovie(String movie) {
		System.out.println("Get ready to watch a movie...");
		popper.on();
		popper.pop();
		lights.dim(10);
		screen.down();
		projector.on();
		projector.wideScreenMode();
		amp.on();
		amp.setDvd(dvd);
		amp.setSurroundSound();
		amp.setVolume(5);
		dvd.on();
		dvd.play(movie);
	}
 
 
	public void endMovie() {
		System.out.println("Shutting movie theater down...");
		popper.off();
		lights.on();
		screen.up();
		projector.off();
		amp.off();
		dvd.stop();
		dvd.eject();
		dvd.off();
	}
}
复制代码

有了这个基础,后面观赏电影就变得简单了。code

public class HomeTheaterTestDrive {
	public static void main(String[] args) {
		Amplifier amp = new Amplifier("Top-O-Line Amplifier");
		Tuner tuner = new Tuner("Top-O-Line AM/FM Tuner", amp);
		DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp);
		CdPlayer cd = new CdPlayer("Top-O-Line CD Player", amp);
		Projector projector = new Projector("Top-O-Line Projector", dvd);
		TheaterLights lights = new TheaterLights("Theater Ceiling Lights");
		Screen screen = new Screen("Theater Screen");
		PopcornPopper popper = new PopcornPopper("Popcorn Popper");
 
        // 根据子系统全部的组件来实例化外观
		HomeTheaterFacade homeTheater = 
				new HomeTheaterFacade(amp, tuner, dvd, cd, 
						projector, screen, lights, popper);
 
        // 使用简化的接口,并开启电影,而后关闭电影
		homeTheater.watchMovie("Raiders of the Lost Ark");
		homeTheater.endMovie();
	}
}
复制代码

就这样,咱们完成了外观模式的处理。当你使用完,是否是以为很简单了呢。cdn

定义外观模式

想要用外观模式,咱们建立了一个接口简化而统一的类,用来包装子系统中一个或多个复杂的类。外观模式至关直接,很容易理解,这方面和许多其余的模式不太同样。但这并不会下降它的威力:外观模式容许咱们让客户和子系统之间避免紧耦合。并且外观模式也帮咱们遵循一个新的面向对象原则。对象

外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

最少知识原则:只和你的密友谈话。这个原则系统咱们在设计中,不要让太多的类耦合在一块儿,省得修改系统中的一部分,会影响到其余部分。若是许多类之间相互依赖,那么这个系统就会变成一个易碎的系统,他须要花许多成本维护,也会由于太复杂而不容易被其余人了解。

咱们来作一个对比你们就知道啦

// 不采用这个原则,咱们须要调用两次方法才能获取到最终的信息
public float getTemp() {
    Thermometer thermometer = station.getThermometer();
    return thermometer.getTemperature();
}

// 采用这个原则,咱们加进一个方法,这样就能够减小咱们所依赖的类的数目
public float getTemp() {
    return station.getTemperature();
}
复制代码

设计箱内的工具

由于此次学习的内容比较简单,我就在这篇里进行总结了。

  • OO基础

    抽象、封装、继承、多态

  • OO原则

    封装变化

    多用组合,少用继承

    针对接口编程,不针对实现编程

    为交互对象之间的松耦合设计而努力

    依赖抽象,不要依赖具体类

    类应该对扩展开放,对修改关闭

    只和朋友交谈

  • OO模式

    『策略模式』、『观察者模式』、『装饰者模式』、『抽象工厂模式』、『工厂方法模式』、『单例模式』、『命令模式』

    适配器模式』将一个类的接口,转换成客户指望另外一个接口。适配器让本来不兼容的类合做无间。

    外观模式』提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

此次学习的适配器和外观,虽然篇幅很少,可是在日常写代码的过程当中仍是常用的,尤为是适配器模式,大家以为呢?因此,这一块还得巩固好,这样对于后面编写代码,理解代码的根源颇有帮助的哦。下次,咱们开启模板方式模式之旅。

PS:小编在介绍适配器模式的时候,只举例说明了对象适配器。其实还有一个类适配器,可是那个是须要用到多重继承的,考虑到Java没有实际场景,这里就略过了。感兴趣的朋友能够继续深刻研究下。

爱生活,爱学习,爱感悟,爱挨踢

相关文章
相关标签/搜索