特点与定义
- 定义
外观模式(Facade Pattern)用于隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。
这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
参与角色
- 外观角色(Facade):客户端调用他的方法,外观角色中包含一个或者多个子系统的功能,客户端只需要调用外观模式,即可对各个子系统对象进行处理。
- 子系统角色(SubSystem):一个软件系统中有一个或者对多个子系统,它可以是一个单独的类或者集合,一种实现方法。
使用场景
- 为复杂的模块或子系统提供外界访问的模块;
- 子系统相互独立;
- 在层析结构中,可以使用外观模式定义系统的每一层的入口。
实现分析
现在我们来实现去餐馆吃饭的操作,吃一顿饭需要:点菜,买菜,洗菜,切菜,炒菜,端菜,吃菜,结账这么多操作,现在我们一一来实现。
去餐馆吃饭
public class FacadeTest { public static void main(String[] args) { System.out.println("去餐馆吃饭"); //点菜 Work selectFood = new SelectFood(); selectFood.handle(); //买菜 Work buyFood = new BuyFood(); buyFood.handle(); //洗菜 Work cleanFood = new CleanFood(); cleanFood.handle(); //切菜 Work cutFood = new CutFood(); cutFood.handle(); //炒菜 Work cooking = new Cooking(); cooking.handle(); //端菜 Work send = new Send(); send.handle(); //吃菜 System.out.println("吃菜"); //结账 System.out.println("结账"); } }
餐馆工作人员
//厨房人员工作接口 interface Work { void handle(); } //点菜 class SelectFood implements Work{ @Override public void handle() { System.out.println("点菜"); } } //买菜 class BuyFood implements Work{ @Override public void handle() { System.out.println("买菜"); } } //助理洗菜 class CleanFood implements Work{ @Override public void handle() { System.out.println("洗菜"); } } //助理切菜 class CutFood implements Work{ @Override public void handle() { System.out.println("切菜"); } } //厨师做菜 class Cooking implements Work{ @Override public void handle() { System.out.println("炒菜"); } } //上菜 class Send implements Work { @Override public void handle() { System.out.println("上菜"); } }
上述代码非常复杂,客户端与每一个具体的子模块都进行了交互,如果子模块发生改变还要求客户需要发生改变。对于客户端而言,我们只需要点菜、吃菜、结账即可。所以现在我们加入外观模式,来重构我们的代码。
加入外观模式
class EatFacade { public void facade() { //点菜 new SelectFood().handle(); //买菜 new BuyFood().handle(); //洗菜 new CleanFood().handle(); //切菜 new CutFood().handle(); //炒菜 new Cooking().handle(); //端菜 new Send().handle(); } }
调整客户端
public class FacadeTest { public static void main(String[] args) { System.out.println("去餐馆吃饭"); //外观模式 EatFacade eatFacade = new EatFacade(); eatFacade.facade(); //吃菜 System.out.println("吃菜"); //结账 System.out.println("结账"); } }
外观模式的目的不是给予子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散耦合,从而让外部能够更简单地使用子系统。