Java设计模式之外观模式/门面模式(Facade)

1. 外观模式

1.1 概述

       外观模式比较简单,是应用比较广泛的一种设计模式。

       举个栗子说明一下,比如说,现在我在家炒菜,我需要准备菜、调料、油等,然后再下锅炒,最后完成。但是,如果我们去饭店吃,只需要跟服务员说一下菜名,服务员就会为我们提供一份美味佳肴。本来如此繁复的一个工作,现在有了服务员的加入而变得简单,我们不需要和菜、调料等直接接触,也不需要了解具体的细节,就得到了我们想要的结果,这就应用到了今天要说到的模式——外观模式。

1.2 定义

外观模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。(引自《大话设计模式》)

1.3 结构图

这里主要涉及三个角色:

  • 外观角色(Facade):外观模式的核心。对外为客户提供一组可用的接口,对内熟悉每一个子系统的功能,并根据客户需求对子系统的功能进行组合。
  • 子系统角色(SubSystem):一个应用中可存在一个或多个子系统类,实现子系统功能,被外观角色所调用,处理Facade指派的功能。值得注意的是,子系统类中没有Facade的任何信息,即没有对Facade对象的引用。
  • 客户角色(Client):通过调用Facade完成需要实现的功能。

2. 实战应用

2.1 实例说明

简单举个例子说明。现在有一个网站要做登录模块,登录的信息有用户名、密码和图片验证码,忽略前台需要做的一些相关规则的正则校验,只考虑后端服务端的校验。那么,有如下步骤:

(1)图片验证码校验。

(2)用户是否存在。

(3)密码校验。

由于这三个步骤的功能是相互独立的,而且也有可能被其他模块所调用,也考虑到让设计符合单一职责,所以可以将这三部分写到三个类中。

2.2 类图

2.3 实现代码

子系统一

package main.mode.wgms;

public class PictureCode {
	
	public void CheckPictureCode() {
		System.out.println("校验图片验证码");
	}
}

子系统二

package main.mode.wgms;

public class UserInfo {
	
	public void checkUserName() {
		System.out.println("校验用户名是否存在");
	}
}

子系统三

package main.mode.wgms;

public class PwdInfo {
	
	public void checkPwd() {
		System.out.println("校验用户名密码是否匹配");
	}
}

外观类

package main.mode.wgms;

public class LoginFacade {
	private PictureCode code;
	private UserInfo user;
	private PwdInfo pwd;
	
	public LoginFacade() {
		code = new PictureCode();
		user = new UserInfo();
		pwd = new PwdInfo();
	}
	
	public void login(){
		System.out.println("进入登录功能......");
		code.CheckPictureCode();
		user.checkUserName();
		pwd.checkPwd();
		System.out.println("登录成功......");
	}
}

客户端类中调用Facade类

package main.mode.wgms;

public class Client {
	
	public static void main(String[] args) {
		LoginFacade login = new LoginFacade();
		login.login();
	}
}

结果

2.4 分析

(1)子系统之间相互独立,完成各自的功能。

(2)外观类按客户需求组合子系统的功能,完成客户所需功能。

(3)从客户端代码可以看出,客户不需要知道登录具体做了哪些操作,即不知道PictureCode、UserInfo、PwdInfo的存在,只需要调用LoginFacade完成登录功能即可。客户端不需要知道系统内部的组成,不需要了解内部实现的细节,使得客户端和子系统类之间解耦。

3. 总结

3.1 优点

  • 外观模式简单易用,完美地体现了依赖倒转原则和迪米特法则的思想。
  • 使客户端和子系统之间解耦,提高了子系统的易扩展性和复用性。
  • 客户端代码很简单。

3.2 缺点

  • 外观类违背了开放-封闭原则,增加新的子系统需要修改外观类的代码。

3.3 应用场景

  • 在分层架构中,可以通过外观类建立层与层之间的联系,减少层之间的联系,降低耦合性。
  • 客户端与子系统联系过多时,或者子系统需要不断的重构或修改时,可以增加外观类,将客户端与子系统解耦,增加子系统的可扩展性和复用性。
  • 当需要访问一个复杂或难以维护和扩展的遗留系统时,可以引入外观类,让外观类与遗留代码做交互。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章