1、外观模式介绍:
外观模式在开发过程中的运用频率非常高, 尤其是在现阶段各种第三方SDK很大概率会使用外观模式. 通过一个外观类使得整个系统的接口只有一个统一的高层接口, 通过一个外观类使得整个系统的接口只有一个统一的高层接口, 这样能够降低用户的使用成本, 也对用户屏蔽了很多实现细节. 当然, 在我们开发的过程中, 外观模式也是我们封装api的常用手段, 例如网络模块, ImageLoader模块等.
2、外观模式定义:
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行.门面模式提供一个高层次的接口, 使得子系统更易于使用;
3、外观模式的使用场景:
(1) 为一个复杂子系统提供一个简单接口. 子系统往往因为不断演化而变得越来越复杂, 甚至可能被替换, 大多数模式使用时都会产生更多, 更小的类, 在这使用子系统更具有可重用性的同时也更容易对子系统进行定制、修改, 这种易变性使得子系统的具体实现变得尤为重要. Facade可以提供一个简单统一的接口, 对外隐藏子系统的具体实现、隔离变化;
(2) 当你需要构建一个层次结构的子系统时, 使用Facade模式定义子系统中每层的入口点. 如果子系统之间是相互依赖的, 你可以让它们仅通过Facade接口进行通信, 从而简化了它们之间的依赖关系;
4、优缺点:
优点:
(1) 对客户程序隐藏子系统细节, 因而减少了客户对于子系统的耦合, 能够拥抱变化;
(2) 外观类对子系统的接口封装, 使得系统更易于使用;
缺点:
(1) 外观类接口膨胀. 由于子系统的接口都有外观类统一对外暴露, 使得外观类的api接口较多, 在一定程度上增加了用户使用成本;
(2) 外观类没有遵循开闭原则, 当业务出现变更时, 可能需要直接修改外观类;
5、代码示例:
public class MobilePhone {
private Phone mPhone = new PhoneImpl();
private Camera mCamera = new SamsungCamera();
public void videoChat() {
System.out.println("videoChat");
mCamera.open();
mPhone.dail();
}
publicvoid hangup() {
mPhone.hangup();
}
public void takePicture() {
mCamera.open();
mCamera.takePicture();
}
public void closeCamera(){
mCamera.close();
}
}
public interface Phone {
public void dail();
public void hangup();
}
class PhoneImpl implements Phone {
@Override
public void dail() {
System.out.println("dail");
}
@Override
public void hangup() {
System.out.println("hangup");
}
}
public interface Camera {
public void open();
public void takePicture();
public void close();
}
class SamsungCamera implements Camera {
@Override
public void open() {
System.out.println("open");
}
@Override
public void takePicture() {
System.out.println("takePicture");
}
@Override
public void close() {
System.out.println("close");
}
}
public class Test {
public static void main(String[] args) {
MobilePhone mp = new MobilePhone();
mp.takePicture();
mp.videoChat();
}
}
MobilePhone类中含有两个子系统, 也就是拨号系统和拍照系统, MobilePhone将这两个系统封装起来, 为用户提供一个统一的操作接口, 也就是说用户只需要通过MobilePhone这个类就可以操作打电话和拍照这两个功能. 用户不需要知道有Phone这个接口以及它的实现类是PhoneImpl, 同样也不需要知道Camera相关的信息, 通过MobilePhone就可以包揽一切. 而在MobilePhone中也封装了两个子系统的交互, 例如视频电话时需要先打开摄像头, 然后再开始拨号, 如果没有这一步的封装, 每次用户实现视频通话功能时都需要手动打开摄像头、进行拨号, 这样会增加的使用成本, 外观模式使得这些操作更加简单, 易用;
从上述代码中可以看到, 外观模式就是统一接口封装. 将子系统的逻辑, 交互隐藏起来, 为用户提供一个高层次的接口, 使得系统更加易用, 同时也对外隐藏了具体的实现, 这样即使具体的子系统也发送了变化, 用户不会感知到, 因为用户使用的是Facade接口, 内部的变化对于用户来说并不可见. 这样一来就将变化隔离开来, 使得系统也更为灵活;
网友评论