(十二),外观模式

最后更新于:2022-04-01 09:57:22

终于考试完了,瞬间感觉轻松了许多,又可以安心地写代码了,下面进入今天的正题–外观模式。 外观模式,也称门面模式,顾名思义,就是一个对象封装了一系列相关的操作(行为),使得这些操作仅对外提供(暴露)方法(接口),客户端根据这些外观(暴露的接口)就可以简单地完成一系列操作,达到了客户端无需知道内部实现细节,只需知道对象的外观就可以实现一系列行为,简单来说就是面向对象的封装。这一系列行为也就是一个系统的功能。 定义:通过一个统一的对象实现一个系统的外部与内部的通讯,提供了一个高层次的接口,使得系统功能更加透明,更加容易使用。 使用场景: 1. 为一个复杂系统提供一个简单的接口。为一个复杂系统提供一个简单的接口,对外部隐藏系统的内部实现,隔离变化,使得当这个系统因为不断演化而不断的修改,定制也可以更加容易地扩展使用,即对外部的使用是一样的,客户端无需知道内部发生了什么变化,隐藏了系统的内部实现,这也就是封装的好处了。 1. 简化子系统之间的依赖,降低它们之前的耦合。当不同的子系统需要使用其他系统的功能的时候,那么我们就需要构建一个层次结构的系统,这时我们通过外观模式为这些子系统提供一个通讯接口,即每层的入口点。 优点: 1. 因为对客户端隐藏了系统的细节,减少了客户端对于系统的耦合,能够拥抱变化。 1. 对系统一系列功能进行了整合,封装,使得系统更加容易使用。 缺点: 1. 外观类接口膨胀。因为我们外观类需要封装一系列相关的功能,这一系列相关的功能可能需要不同的类实现,那么我们不是简单地给这个外观类提供实现不同功能类,而是为每个实现不同功能的类提供一个接口,然后再使用的时候给这些接口提供实现类,这样可以便于扩展,反之,外观类接口必然膨胀,也增加了程序员的一定的负担。 1. 违背了开闭原则,当业务出现变更的时候,可能需要直接修改外观类(通常是修改外观类中的接口的实现类)。 下面以现代智能机模拟实现外观模式 代码实现: 虚拟手机(接口)—-接打电话功能接口 ~~~ public interface Phone { /** * 打电话 */ public void call(); /** * 挂断 */ public void handup(); } ~~~ 虚拟相机(接口)—-拍照功能接口 ~~~ /** * 照相机 * @author lt * */ public interface Camera { public void open(); public void takePicture(); public void close(); } ~~~ 真实的手机(实现类) ~~~ /** * 以前的旧手机,非智能,只能打电话和挂电话 * @author lt * */ public class PhoneImpl implements Phone{ @Override public void call() { System.out.println("打电话"); } @Override public void handup() { System.out.println("挂断电话"); } } ~~~ 真实的相机(实现类) ~~~ /** * 三星相机 * @author lt * */ public class SamsungCamera implements Camera{ @Override public void open() { System.out.println("打开相机"); } @Override public void takePicture() { System.out.println("拍到了一个美女"); } @Override public void close() { System.out.println("相机关闭了"); } } ~~~ 现代智能机(Android/Iphone)—-外观类 ~~~ /** * 现代智能机 --- 集照相,视频聊天,打电话于一身 * @author lt * */ public class SmartPhone { // 对应实现完成手机功能接口的实现类 public Phone phone = new PhoneImpl(); // 对应实现相机功能接口的实现类 public Camera camera = new SamsungCamera(); public void call() { phone.call(); } public void hangup() { phone.handup(); } public void takePicture() { openCamera(); camera.takePicture(); closeCamera(); } public void openCamera() { camera.open(); } public void closeCamera() { camera.close(); } /** * 视频通话 */ public void videoChat() { openCamera(); System.out.println("和妹子视频聊天"); closeCamera(); } } ~~~ SmartPhone是外观类,这里具体是现代智能机,具有接打电话,拍照等功能,是这个模式核心类;Phone和Camera是两个特定功能的接口,分别是接打电话的功能,拍照功能,相应的实现类是PhoneIml和SamsungCamera。这里给外观类整了两个接口,即Phone和Camera,这样做的目的是以后要修改接打电话和拍照功能的实现时(如新的硬件)只需要将外观类SmartPhone中的相应功能的接口实现类改变一下就可以了,其他的都不用改,这也就是面向接口编程的好处,和J2EE中的Service,Dao层都提供一个接口和相应实现类一样,目的是一样的,即便于修改扩展。 测试: ~~~ public class Test { public static void main(String[] args) { SmartPhone iphone7s = new SmartPhone(); // 用7s拍照 iphone7s.takePicture(); // 用7s视频聊天 iphone7s.videoChat(); } } ~~~ 运行结果: ![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-17_56ea5b37e63ed.jpg "") 可以看到,现代的智能机既有一般手机的功能,也有相机的功能,使得我们只需要一部智能机就不需要专门为打电话买一个手机,专门为拍照买一个相机了,一部手机统统搞定,而且避免了许多麻烦,如我们点击屏幕的相机(系统内置App)系统自动打开了相机,拍照完了以后系统自动将相机关闭,视频聊天也一样,这使得我们使用更加简单,更加方便。 总结: 外观模式使用也非常多,面向对象中的封装也通常是使用了外观模式,封装不一定使用了外观模式,但外观模式一定需要封装。通过外观模式,使得复杂系统功能更加丰富,使用更加简单。通过一个外观类就可以操作整个系统,减少了用户的使用成本,同时因为内部面向接口编程,使得使扩展维护更加简单,从而使得系统可以容易地面对多变的场景,提升了系统的扩展性灵活性。
';