外观模式

锦通  金牌会员 | 2023-9-27 14:34:54 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 915|帖子 915|积分 2745

外观模式

案例引入

要求,组建一个家庭影院,DVD播放器,投影仪,自动屏幕,环绕立体声,爆米花机,实现家庭影院的功能。过程为,直接用遥控器,统筹各设备开关,开爆米花机,放下屏幕,开投影仪,开音响,开dvd,选dvd,取爆米花,调暗灯光,播放电影,观影结束后,关闭各设备。
传统方式实现案例


无具体代码
传统方式实现案例分析


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


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


类图说明


  • 1.外观类,为调用者,提供统一的接口,外观类知道那些子系统负责处理请求,从而将调用者的请求代理给适当子系统的对象。、
  • 2.调用者,外观接口的使用者。
  • 3.子系统的集合,指模块或者子系统,处理Facede对象指派的任务,是功能的实际提供者。
外观模式实现案例

代码
  1. /**
  2. * @author 长名06
  3. * @version 1.0
  4. * 界面类
  5. */
  6. public class HomeTheaterFacade {
  7.     private DVDPlayer dvdPlayer = DVDPlayer.getDvdPlayer();
  8.     public Popcorn popcorn = Popcorn.getPopcorn();
  9.     public Projector projector = Projector.getProjector();
  10.     public Stereo stereo = Stereo.getStereo();
  11.     public Screen screen = Screen.getScreen();
  12.     public TheaterLight theaterLight = TheaterLight.getTheaterLight();
  13.     public void ready(){
  14.         popcorn.on();
  15.         popcorn.pop();
  16.         dvdPlayer.on();
  17.         projector.on();
  18.         screen.down();
  19.         stereo.on();
  20.         theaterLight.dim();
  21.     }
  22.     public void play(){
  23.         dvdPlayer.play();
  24.     }
  25.     public void end(){
  26.         popcorn.off();
  27.         dvdPlayer.off();
  28.         projector.off();
  29.         screen.up();
  30.         stereo.off();
  31.         theaterLight.off();
  32.     }
  33.     public void pause(){
  34.         dvdPlayer.pause();
  35.         stereo.setVolume();
  36.     }
  37. }
  38. /**
  39. * @author 长名06
  40. * @version 1.0
  41. * 爆米花机
  42. */
  43. public class Popcorn {
  44.     private static Popcorn popcorn = new Popcorn();
  45.     public static Popcorn getPopcorn(){
  46.         return popcorn;
  47.     }
  48.     private Popcorn(){
  49.     }
  50.     public void on(){
  51.         System.out.println("爆米花机 打开");
  52.     }
  53.     public void off(){
  54.         System.out.println("爆米花机 关闭");
  55.     }
  56.     public void pop(){
  57.         System.out.println("爆米花机 爆米花中");
  58.     }
  59. }
  60. /**
  61. * @author 长名06
  62. * @version 1.0
  63. * 投影仪
  64. */
  65. public class Projector {
  66.     private static Projector projector = new Projector();
  67.     public static Projector getProjector(){
  68.         return projector;
  69.     }
  70.     private Projector() {
  71.     }
  72.     public void on(){
  73.         System.out.println("投影仪 打开");
  74.     }
  75.     public void off(){
  76.         System.out.println("投影仪 关闭");
  77.     }
  78.     public void focus(){
  79.         System.out.println("投影仪 聚焦");
  80.     }
  81. }
  82. /**
  83. * @author 长名06
  84. * @version 1.0
  85. * 投影屏幕
  86. */
  87. public class Screen {
  88.     private static Screen screen = new Screen();
  89.     public static Screen getScreen(){
  90.         return screen;
  91.     }
  92.     private Screen() {
  93.     }
  94.     public void down(){
  95.         System.out.println("放下 投影屏幕");
  96.     }
  97.     public void up(){
  98.         System.out.println("升起 投影屏幕");
  99.     }
  100. }
  101. /**
  102. * @author 长名06
  103. * @version 1.0
  104. * 立体声
  105. */
  106. public class Stereo {
  107.     private static Stereo stereo = new Stereo();
  108.     public static Stereo getStereo() {
  109.         return stereo;
  110.     }
  111.     private Stereo() {
  112.     }
  113.     public void on() {
  114.         System.out.println("立体声 打开");
  115.     }
  116.     public void off() {
  117.         System.out.println("立体声 关闭");
  118.     }
  119.     public void setVolume(){
  120.         System.out.println("立体声 设置音量");
  121.     }
  122. }
  123. /**
  124. * @author 长名06
  125. * @version 1.0
  126. * 灯光
  127. */
  128. public class TheaterLight {
  129.     private static TheaterLight theaterLight = new TheaterLight();
  130.     public static TheaterLight getTheaterLight(){
  131.         return theaterLight;
  132.     }
  133.     private TheaterLight() {
  134.     }
  135.     public void on(){
  136.         System.out.println("打开灯光");
  137.     }
  138.     public void off(){
  139.         System.out.println("关闭灯光");
  140.     }
  141.     public void dim(){
  142.         on();//先打开再调暗
  143.         System.out.println("调暗灯光");
  144.     }
  145.     public void bright(){
  146.         System.out.println("调量灯光");
  147.     }
  148. }
  149. /**
  150. * @author 长名06
  151. * @version 1.0
  152. * dvd播放器
  153. */
  154. public class DVDPlayer {
  155.     private static DVDPlayer dvdPlayer = new DVDPlayer();
  156.     public static DVDPlayer getDvdPlayer(){
  157.         return dvdPlayer;
  158.     }
  159.     private DVDPlayer(){
  160.     }
  161.     public void on(){
  162.         System.out.println(" dvd播放器 打开");
  163.     }
  164.     public void off(){
  165.         System.out.println(" dvd播放器 关闭");
  166.     }
  167.     public void pause(){
  168.         System.out.println(" dvd播放器 暂停");
  169.     }
  170.     public void play(){
  171.         System.out.println(" dvd播放器 播放");
  172.     }
  173. }
  174. //调用者
  175. public class Client {
  176.     public static void main(String[] args) {
  177.         HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
  178.         homeTheaterFacade.ready();
  179.         System.out.println("--------");
  180.         homeTheaterFacade.play();
  181.         System.out.println("--------");
  182.         homeTheaterFacade.pause();
  183.         System.out.println("--------");
  184.         homeTheaterFacade.end();
  185.     }
  186. }
复制代码
外观模式在Mybatis框架的源码分析
  1.   //org.apache.ibatis.session.Configuration类的方法
  2.   public MetaObject newMetaObject(Object object) {
  3.     return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
  4.   }
  5. //MetaObject的forObject方法
  6. public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
  7.     if (object == null) {
  8.       return SystemMetaObject.NULL_META_OBJECT;
  9.     } else {
  10.       return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
  11.     }
  12.   }
  13. //会调用到MetaObject类中的该方法
  14. private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
  15.     this.originalObject = object;
  16.     this.objectFactory = objectFactory;
  17.     this.objectWrapperFactory = objectWrapperFactory;
  18.     this.reflectorFactory = reflectorFactory;
  19.     if (object instanceof ObjectWrapper) {
  20.       this.objectWrapper = (ObjectWrapper) object;
  21.     } else if (objectWrapperFactory.hasWrapperFor(object)) {
  22.       this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
  23.     } else if (object instanceof Map) {
  24.       this.objectWrapper = new MapWrapper(this, (Map) object);
  25.     } else if (object instanceof Collection) {
  26.       this.objectWrapper = new CollectionWrapper(this, (Collection) object);
  27.     } else {
  28.       this.objectWrapper = new BeanWrapper(this, object);
  29.     }
  30.   }
复制代码
外观模式的注意事项和细节


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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

锦通

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表