1.外观模式
提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用.
2代码实现
比如我们要看电影,需要进行很多操作,播放dvd,准备好爆米花,打开灯光.播放屏幕等....
我们先定义扩音器,播放器等底层组件
package appearance; public class Amplifer { void on() { System.out.println("amp on"); } void off() { System.out.println("amp off"); } void setDvd(DvdPlayer dvd) { System.out.println("amp setDvd"); } void setSurroundSound(DvdPlayer dvd) { System.out.println("amp setDvd"); } void setVolume(int i) { System.out.println("amp surroundSound "+i); } }
package appearance; public class CdPlayer { }
package appearance; public class DvdPlayer { public void on() { System.out.println("Dvdplayer on"); } public void play(String movie) { System.out.println("Dvdplayer play " + movie); } public void stop() { System.out.println("Dvdplayer stop"); } public void eject() { System.out.println("Dvdplayer eject"); } public void off() { System.out.println("Dvdplayer off"); } }
package appearance; public class PopcornPopper { void on () { System.out.println(" PopcornPopper on "); } void off () { System.out.println(" PopcornPopper off "); } void pop () { System.out.println(" PopcornPopper pop "); } }
package appearance; public class Projector { public void on() { System.out.println("Projector on"); } public void off() { System.out.println("Projector off"); } public void wideScreenMode() { System.out.println("Projector WideScreenMode"); } }
package appearance; public class Screen { public void down() { System.out.println("Screen down"); } public void up() { System.out.println("Screen on"); } }
package appearance; public class TheaterLights { public void dim(int i) { System.out.println("Threater lights dim " + i); } public void on() { System.out.println("Threater lights on " ); } }
package appearance; public class Tuner { }
虽然我们可以直接调用这些组件,但是把这些组件封装到一个统一的接口中调用会更容易使用,而且调用者和子系统之间的耦合也通过外观模式解耦了,调用者依赖的不是底层组件,而是通过底层组件组合而成的外观模式组件.
接下来就定义关键的外观模式组件
package appearance; public class HomeTheaterFacade { Amplifer amp;//扩音器 Tuner tuner;//调音器 DvdPlayer dvd;//dvd播放器 CdPlayer cd;//cd播放器 Projector projector;//投影机 TheaterLights lights;//剧场灯光 Screen screen;//屏幕 PopcornPopper popper;//爆米花 public HomeTheaterFacade(Amplifer amp, Tuner tuner, DvdPlayer dvd, CdPlayer cd, Projector projector, TheaterLights lights, Screen screen, PopcornPopper popper) { super(); this.amp = amp; this.tuner = tuner; this.dvd = dvd; this.cd = cd; this.projector = projector; this.lights = lights; this.screen = screen; this.popper = popper; } public void watchMovie(String movie) { System.out.println("Watch movie...."); popper.on(); popper.pop(); lights.dim(10); screen.down(); projector.on(); projector.wideScreenMode(); amp.on(); amp.setDvd(new DvdPlayer()); amp.setVolume(5); dvd.on(); dvd.play(movie); } public void endWatchMovie() { System.out.println("Movie end...."); popper.off(); lights.on(); screen.up(); projector.off(); amp.off(); dvd.stop(); dvd.eject(); dvd.off(); } }
老生常谈,还是通过组合的方式来实现外观模式,怪不得第一个模式要讲策略模式,因为组合真的是构成了设计模式很大一部分.
3.总结
外观模式主要是把各个子系统的功能封装提供一个统一的子系统,其实平常编码也经常用,只是没有定义它为外观模式.