昆明java培训
达内昆明广州春城路

18487146383

热门课程

JAVA程序之外观模式

  • 时间:2016-11-04
  • 发布:昆明Java培训
  • 来源:java教程

定义

外观模式,为子系统中的一组接口提供一个一致的界面,定义一个高层的接口,这个接口使得这一子系统更加容易使用。

昆明Java培训机构的老师发现,乍一看外观模式和代理模式很相似,但是真正理解了却又不太一样,具体的区别后面再说,外观模式更注重的是给一个子系统一个门面,客户端程序通过这个门面调用子系统中的功能,在这个门面中可以对子系统中的功能进行组合调度,也可以直接暴露出子系统中的一个功能,另外外观模式让子系统和客户端程序进行了松耦合,客户端程序只知道门面类,不知道具体的子系统,符合迪米特法则,另外,门面类只是对子系统的一个调度,因此不能通过门面类来扩展子系统的功能,如果要扩展子系统的功能还是需要在原来的子系统中进行扩展的。

类图

外观模式的类图主要包含两个重要角色:

子系统角色:注意这是一个子系统,并不是几个类的组合,相对于几个类的组合来说,子系统的概念要相对大一点;

外观类:外观类和子系统是聚合关系,外观类可以有一个也可以有多个(根据具体的功能来创建多个外观类),外观角色提供客户端定制的服务,将客户端的一个完整的功能作为一个行为,然后调用子系统完成;

代码实现

假设我们的子系统中只有三个类(模拟子系统),并且根据依赖倒置原则,高层模块和底层模块要依赖抽象,因此我们给子系统中的类和外观类都加上抽象接口(注意:这样做的结果就是系统中的类文件数量变多了,会相对的增加系统的复杂性,并不是必须的需要这么做)

子系统类

public interface InterfaceA {

public void methodA();

}

public class ClassA implements InterfaceA{

@Override

public void methodA() {

System.out.println("子系统类A的方法A");

}

}

其他两个类跟这个类类似,不再贴出详细代码。

外观类

public class Facade {

private ClassA classa;

private ClassB classb;

private ClassC classc;

public Facade(){

super();

classa = new ClassA();

classb = new ClassB();

classc = new ClassC();

}

public void methodAB(){

classa.methodA();

classb.methodB();

}

public void methodAC(){

classa.methodA();

classc.methodC();

}

public void methodBC(){

classb.methodB();

classc.methodC();

}

}

测试类

public static void main(String[] args) {

Facade facade = new Facade();

facade.methodAB();

facade.methodAC();

facade.methodBC();

System.out.println("--------华丽的分割线:以下为不使用外观模式的代码---------");

InterfaceA ia = new ClassA();

ia.methodA();

InterfaceB ib = new ClassB();

ib.methodB();

InterfaceC ic = new ClassC();

ic.methodC();

}

上述的测试中昆明Java培训机构的老师同时给出了不使用外观模式的代码,可以看到,使用外观模式在客户端只需要知道外观类即可,但是不使用外观模式,客户端就需要和子系统中的具体类交互,这会增加子系统和客户端的耦合度,并且也不符合迪米特法则。

优缺点

通过以上的测试类,我们可以简单的概括一下外观模式的一些优缺点。

优点

对客户端而言,不知道子系统中的组件,降低了系统的耦合度,符合迪米特法则;

为客户端访问子系统提供了统一的入口,但是又不妨碍客户端直接调用子系统中的组件;

虽然给子系统提供了外观类,但是外观类并不影响子系统中的功能,切子系统并不知道外观类的存在;

合理使用外观类可以更好的划分访问的层次;

外观类将这个子系统和客户端以及其他子系统进行隔离,提高了子系统的可移植性;

缺点

如果不存在抽象外观类,子系统扩展以后可能需要修改外观类的代码,违反了开闭原则;

过多的外观类或者不合理的外观类会增加系统的复杂性,给客户端的调用造成困扰;

使用场景

在设计初期阶段,应该要有意识的将不同的两个层进行分离,层和层之间创建外观类,为复杂的子系统提供一个简单的访问接口,降低耦合度;

需要为一个复杂的子系统提供简单接口的时候也可以使用外观模式,此时不管子系统如何发生变化,抽象外观类中的基本行为并不发生变化,当客户端需要定制服务的时候可以选择实现抽象外观类,在实现类中按照客户端的需求调用子系统的特定组件或方法,当然如果抽象外观类中的方法不满足客户端的需求,客户端也可以直接调用子系统的组件或方法;

在开发阶段,子系统往往随着不断的重构演化而变得越来越复杂,增加外观类可以提供一个简单的接口,减少他们之间的依赖。

外观接口如果需要暴露给客户端很多的功能的话,可以使用多个外观接口,将不同的功能放在不同的接口中,这样就会形成一个外观层,类似于我们平时所使用的dao层或者service层,service层将action层和dao层进行了隔离。

昆明Java培训机构的老师给大家总结总结

外观模式是一个结构型模式,通过创建一个外观类,隔离了客户端和子系统,符合迪米特法则,常常用于一个子系统需要向外提供服务时,但是是否选择使用外观模式还取决于子系统在向外提供服务时是否需要依赖很多的类,其次,子系统并不是单单几个类的组合,这个点是需要注意的,因为称之为子系统,其必然属于相对较大的范围,另外还要注意的是子系统在向外提供的服务是否稳定,如果是多变得或者说子系统本身就不够稳定,那么使用外观模式并不是一个很好的选择,还有要注意的一点就是在外观类中是不能扩展子系统的功能的,子系统功能的扩展只能是基于其原有类的基础上进行扩展。

和代理模式的区别

刚看外观模式我真的没看出来和代理模式的区别,都是通过另外一个类来完成非本身的功能,但是两者之间还是有很大的区别的:

首先,代理模式中代理类是需要实现和被代理类一样的接口的,但是外观模式不需要;

其次,代理模式中是对被代理的类中的方法进行加工,或者说修饰,但是也仅仅是一个方法,但是在外观模式中,外观类中的方法更倾向于将客户端的一个完整功能作为一个行为,也就是说外观类中的方法可能要调用更多的子系统中的方法,但是代理模式仅仅是在被代理类中的方法的基础上添加一些行为,比如添加日志等。

第三,代理模式中对于我们关心的方法可以自己处理,比如说数据库连接的关闭我们可以在代理类中处理成归还,但是在外观模式中,外观类仅仅是组合或者调度子系统的方法,并不能对原来的方法进行修改或者扩展。

上一篇:使用Swagger2构建强大的RESTful API文档
下一篇:java集合你对它有多少了解呢?

dubbo服务的线程模型

dubbo服务的负载均衡

dubbo服务的集群容错

dubbo服务的启动检查

选择城市和中心
贵州省

广西省

海南省

台湾