外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。
uml类图
类图解析:
facade:为调用端提供统一的调用接口,外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象。
client:外观接口的调用者。
subsystem集合:指模块或者子系统,处理facade对象指派的任务,他是功能的实际提供者。
外观模式案例:背景介绍:
组建一个家庭影院:dvd播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能,通过直接用遥控器(统筹各设备开关)进行控制,其过程为:
开爆米花机
放下屏幕
开投影仪
开音响
开dvd,选dvd
拿爆米花
调暗灯光
播放
观影结束后,关闭各种设备.
dvd、popcorn、projector、screen、stereo、theaterlight代码如下:
public class dvdplayer { // 使用单例模式 private static final 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 class popcorn { private static final 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("爆米花做好了..."); }}
public class projector { private static final 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 focus() { system.out.println("投影仪聚焦中..."); }}
public class screen { private static final screen instance = new screen(); private screen(){} public static screen getinstance() { return instance; } public void up() { system.out.println("屏幕上升..."); } public void down() { system.out.println("屏幕下降..."); }}
public class stereo { private static final 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("立体音响音量-..."); }}
public class theaterlight { private static final theaterlight instance = new theaterlight(); private theaterlight(){} public static theaterlight 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("灯光亮度调亮..."); }}
hometheaterfacade(统筹各设备开关)
public class hometheaterfacade { private dvdplayer dvdplayer; private popcorn popcorn; private projector projector; private stereo stereo; private screen screen; private theaterlight theaterlight; public hometheaterfacade() { this.dvdplayer = dvdplayer.getinstance(); this.popcorn = popcorn.getinstance(); this.projector = projector.getinstance(); this.stereo = stereo.getinstance(); this.screen = screen.getinstance(); this.theaterlight = theaterlight.getinstance(); } /** * 准备开始 */ public void ready() { popcorn.on(); popcorn.pop(); screen.down(); projector.on(); projector.focus(); 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(); }}
client(测试)
public class client { public static void main(string[] args) { hometheaterfacade hometheaterfacade = new hometheaterfacade(); system.out.println("----------准备开始-----------"); hometheaterfacade.ready(); system.out.println("----------开始播放-----------"); hometheaterfacade.play(); system.out.println("----------播放暂停-----------"); hometheaterfacade.pause(); system.out.println("----------播放结束-----------"); hometheaterfacade.end(); }}
实现结果:
外观模式的注意事项和细节外观模式对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统使用的复杂性。
外观模式对客户端与子系统的耦合关系-解耦,让子系统内部的模块更易维护和扩展
通过合理的使用外观模式,可以帮我们更好的划分访问的层次。
当系统需要进行分层设计时,可以考虑使用facade模式。
在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个facade类,来提供遗留系统的比较清晰简单的接口,让新系统与facade类交互,提高复用性。
不能过多的或者不合理的使用外观模式,使用外观模式好,还是直接调用模块好。要以让系统有层次,利于维护为目的。
以上就是java设计模式:外观模式实例分析的详细内容。