浅谈Java设计模式系列0x09---外观模式

浅谈Java设计模式系列0x06—适配器模式
浅谈Java设计模式系列0x07—桥接模式
浅谈Java设计模式系列0x08—装饰器模式

本次我给大家介绍的同样是一种对象结构型模式—–外观模式;

外观模式是什么鬼

外观模式为子系统的一组接口提供一个统一的高层接口,使得子系统更容易使用,这是维基百科上的定义;
但这定义根本看不懂有木有,所以我就以我的理解给大家解释一下外观模式是什么鬼;
我们先看一下下面这张图片:
外观模式
很明显当我们要自己泡咖啡的时候,我们要自己烧开水,自己冲咖啡;
但当我们要到Starbucks喝咖啡时星巴克里的服务员会帮我们做所有泡咖啡的事情,我们只有Oder一杯咖啡便可轻松的等待咖啡的到来;
这里的Starbucks就是我们为子系统提供的一个统一的高层接口,这里可以很清晰的看到外观模式的好处;

模式结构

  • 外观角色(Facade) :客户端可调用其方法,外观角色可以知道相关子系统(SubSystem)的功能和职责,它将客户发来的请求委派到相应的子系统对象处理;
  • 子系统角色(SubSystem) : 实现具体的业务逻辑;

什么时候能用

在以下情况下可以使用外观模式:

  • 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统;
  • 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性;
  • 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度;

代码示例

我们就以上面泡咖啡作为我们的例子;
代码参考
各个子系统:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 子系统一
*/

public class Water {
//将水煮沸
public void boil(){
System.out.println("the water is boiling...");
}
}
/**
*子系统2
*/

public class Cup {
//将具体的Coffee倒入杯子里
public void fillWithCoffee(Coffee coffee){
coffee.makeCoffee();
System.out.println("the coffee is ready!");
}
}

咖啡子系统:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* Coffee接口,每一类的Coffee都实现这个接口
*/

public interface Coffee {
void makeCoffee();
}
/**
* 拿铁咖啡
*/

public class Latte implements Coffee{
@Override
public void makeCoffee() {
System.out.println("making a Latte Coffee...");
}
}
/**
* 摩卡咖啡
*/

public class Mocha implements Coffee {
@Override
public void makeCoffee() {
System.out.println("making a Mocha Coffee...");
}
}
/**
* 卡布奇诺咖啡
*/

public class Cappuccino implements Coffee {
@Override
public void makeCoffee() {
System.out.println("making a Cappuccino Coffee...");
}
}

外观角色:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* 外观角色 Starbucks咖啡店
*/

public class Starbucks {
//子系统1
private Water water = new Water();
//子系统2
private Cup cup = new Cup();
//子系统3
private Coffee coffee;


public void makeLatte() {
water.boil();
coffee = new Latte();
cup.fillWithCoffee(coffee);
}

public void makeCappuccino() {
water.boil();
coffee = new Cappuccino();
cup.fillWithCoffee(coffee);
}

public void makeMocha() {
water.boil();
coffee = new Mocha();
cup.fillWithCoffee(coffee);
}
}

测试类:

1
2
3
4
5
6
7
8
9
10
/**
* 测试类
*/

public class Client {
public static void main(String [] args)
{

Starbucks starbucks=new Starbucks();
starbucks.makeLatte();
}
}

运行结果:

1
2
3
the water is boiling...
making a Latte Coffee...
the coffee is ready!

总结

外观模式为子系统提供了统一的高层接口,减少了处理对象数目并使子系统使用更加容易,降低了系统的耦合度;
但在增加新的子系统时可能需要修改外观类或客户端,违背了开闭原则;

参考

设计模式:深入浅出外观模式