今天要向大家介绍的设计模式是外观模式。外观模式,听上去好像很高大上的样子,其实是非常简单的。
在《大话设计模式》 这本书中举的是股票与基金的例子。我又不炒股,对这些也不太敏感,于是就换一个更加通俗易懂的例子来解释一下这个模式吧~
比如我们买了一张新的手机卡后都需要办理一些业务。但是,在运营商提供的众多业务中寻找最适合自己的难免有些困难。这时,我们就会去请教营业厅的客户服务经理,把自己的需求告诉他/她,让他们帮助我们进行选择组合。
把上面这个例子对应到软件开发中,如果我们不去找客户服务经理,而是单干的话,由于要面对许多业务,而且我们并不能很清楚的了解每一项业务具体是做什么的,这样就加大了选择难度,映射到软件领域,耦合性就大大增加。如果寻求专业人士帮助,这个耦合性就会减少。
以上说的这些就是外观模式:
外观模式,为子系统中的一组接口提供一个一致的界面。此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 ——《大话设计模式》
这个模式很好的体现了面向对象设计思想中依赖倒转原则 和迪米特法则。
知识点补充:
1. 依赖倒转原则:可以简单理解为编程的时候要面向接口编程,而不是面向实现编程。
2. 迪米特法则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
上面提及的办理手机业务的例子,利用外观模式的UML类图如下:
这个Facade类的作用就是对ServiceA、ServiceB、ServiceC三款服务进行操作包装,Facade类作为一个桥梁的作用连接外界和内部的子系统。对于用户而言,无需知道这三款服务的存在。所以不难看出,这个Facade类可以做为一个高级的接口对外,开发者可以根据它提供的方法进行编程;同时,这个Facade类又掌管着若干个不相干的类,通过Facade进行组织调用,这正体现了上面说的两大原则。
实现代码如下:
import java.util.*;
//业务A 这里可以理解为某项具体业务,下同
class ServiceA
{
public void subscribe()
{
System.out.println("购买了业务A");
}
public void unsubscribe()
{
System.out.println("退订了业务A");
}
}
//业务B
class ServiceB
{
public void subscribe()
{
System.out.println("购买了业务B");
}
public void unsubscribe()
{
System.out.println("退订了业务B");
}
}
//业务C
class ServiceC
{
public void subscribe()
{
System.out.println("购买了业务C");
}
public void unsubscribe()
{
System.out.println("退订了业务C");
}
}
//外观类 这里可以理解为客户服务经理
class Facade
{
private ServiceA sa;
private ServiceB sb;
private ServiceC sc;
public Facade()
{
sa = new ServiceA();
sb = new ServiceB();
sc = new ServiceC();
}
public void buyPackageA()
{
sa.subscribe();
sc.subscribe();
}
public void buyPackageB()
{
sb.subscribe();
sa.subscribe();
}
public void unsubscribeA()
{
sa.unsubscribe();
sc.unsubscribe();
}
public void unsubscribeB()
{
sb.unsubscribe();
sa.unsubscribe();
}
}
public class Main
{
public static void main(String[] args)
{
Facade face = new Facade();
face.buyPackageB();
face.unsubscribeB();
}
}
运行结果如下: