在现实生活中,办一些复杂的事经常要经过多个部门。比如小学时报名。“去老师那报道”、“去交书本费”、“交保险费”....等等。
外观模式解决的就是系统中的这类情况,当一个系统功能强大了,子系统越来越多了。客户对系统的访问也越来越多。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
定义:外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观(Facade)模式是“迪米特法则”的典型应用
优点:
- 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类
- 减少了客户类处理对象的数量,使得子系统使用起来更加容易
- 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
缺点:
- 不能很好地限制客户使用子系统类,很容易带来未知风险。
- 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”
外观者模式的结构与实现
外观(Facade)模式的结构比较简单,主要是定义了一个高层接口。它包含了对各个子系统的引用,客户端可以通过它访问各个子系统的功能
结构:
- 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
- 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
- 客户(Client)角色:通过一个外观角色访问各个子系统的功能
实现:
实现场景:做一顿晚饭
package com.wly.DesignPatterns;
/**
* @program: StudyDome
* @author: yuanzhang
* @create: 2020-12-17 19:49
**/
public class FacadePattern {
public static void main(String[] args) {
Dinner dinner = new Dinner();
System.out.println("开始准备晚饭");
dinner.getDinner();
System.out.println("开吃");
}
}
/**
* @Annotation:外观角色
* @Author: yuanzhang
* @Date: 19:52
*/class Dinner{
private BuyMeat buyMeat = new BuyMeat();
private BuyVegetables buyVegetables = new BuyVegetables();
private CleanFood cleanFood = new CleanFood();
private CutMeat cutMeat = new CutMeat();
private CutVegetables cutVegetables = new CutVegetables();
private CookThoroughly cookThoroughly = new CookThoroughly();
public void getDinner(){
String meat = buyMeat.buyBeef();
String vegetables = buyVegetables.buyOkra();
cleanFood.CleanFood(meat+vegetables);
cutMeat.cutBeef(meat);
cutVegetables.cutOkra(vegetables);
cookThoroughly.cook(meat+vegetables);
}
}
/**
* @Annotation:子系统角色--买肉
* @Author: yuanzhang
* @Date: 19:57
*/
class BuyMeat{
public String buyBeef(){
System.out.println("买了两斤牛肉");
return "牛肉";
}
}
/**
* @Annotation:子系统角色--买蔬菜
* @Author: yuanzhang
* @Date: 19:57
*/
class BuyVegetables{
public String buyOkra(){
System.out.println("买了八两秋葵");
return "秋葵";
}
}
/**
* @Annotation:子系统角色--洗菜
* @Author: yuanzhang
* @Date: 19:57
*/
class CleanFood{
public String CleanFood(String food){
System.out.println("洗干净:"+food);
return "洗干净的"+food;
}
}
/**
* @Annotation:子系统角色--切肉
* @Author: yuanzhang
* @Date: 19:57
*/
class CutMeat{
public void cutBeef(String meat){
System.out.println("切肉:"+meat);
}
}
/**
* @Annotation:子系统角色--切蔬菜
* @Author: yuanzhang
* @Date: 19:57
*/
class CutVegetables{
public void cutOkra(String vegetables){
System.out.println("切蔬菜:"+vegetables);
System.out.println(vegetables+"不用切");
}
}
/**
* @Annotation:子系统角色--煮熟
* @Author: yuanzhang
* @Date: 19:57
*/
class CookThoroughly{
public void cook(String food){
System.out.println("将"+food+"煮熟");
}
}
输出
开始准备晚饭 买了两斤牛肉 买了八两秋葵 洗干净:牛肉秋葵 切肉:牛肉 切蔬菜:秋葵 秋葵不用切 将牛肉秋葵煮熟 开吃