设计模式-外观模式
定义:外观模式又叫门面模式,提供一个接口用于访问子系统的一群接口。
类型:结构型
应用场景
- 子系统越来越复杂,提供了高层调用,简化使用难度。
- 使用者无需知道具体子系统如何工作的。
优点
- 简化调用流程,无需知道子系统如何运作。避免风险(子系统更改了,调用者也要做相关的测试。若抽象出了上层接口了。只需要测试上层接口传入参数能够接收到预定的结果即可。)
- 减少外层调用者对子系统的强依赖关系,降低耦合度。
- 划分了系统的层次结构。
- 符合迪米特法则。
缺点
- 增加子系统、扩展子系统时候引发风险
针对缺点的扩展知识
替代方案:使用消息中间件(mq)。使用消息中间件主要特点是异步处理。
源码应用的场景
- apache的tomcat的RequestFacade 包装自己的Request
public class RequestFacade implements HttpServletRequest {
/**
* The wrapped request.
*/
protected Request request = null;
/**
* Construct a wrapper for the specified request.
*
* @param request The request to be wrapped
*/
public RequestFacade(Request request) {
this.request = request;
}
@Override
public void setAttribute(String name, Object o) {
if (request == null) {
throw new IllegalStateException(
sm.getString("requestFacade.nullRequest"));
}
request.setAttribute(name, o);
}
}
demo
UML
目录结构
Account 个人账户类
package structual.facade;
public class Account {
private String number;//账户号
private String name;//用户名称(其实应该是个用户的引用,简单demo将账户与用户耦合)
private int integral;//积分
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIntegral() {
return integral;
}
public void setIntegral(int integral) {
this.integral = integral;
}
@Override
public String toString() {
return "Account{" +
"number='" + number + '\'' +
", name='" + name + '\'' +
", integral=" + integral +
'}';
}
}
PointsGift 积分类
package structual.facade;
public class PointsGift {
private String name;//积分礼物名称
private Integer price;//礼物需要的积分
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
@Override
public String toString() {
return "PointsGift{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
AccountOperation 账户操作类(考虑到账户金额操作的线程安全性抽取操作类)
package structual.facade;
public class AccountOperation {
public static void accountPay(Account account,Integer price){
synchronized (AccountOperation.class){
account.setIntegral(account.getIntegral()-price);
}
}
}
QualifyService 校验积分是否够买商品
package structual.facade;
public class QualifyService {
public boolean isAvailable(Account account,PointsGift pointsGift){
return account.getIntegral() > pointsGift.getPrice()?true:false;
}
}
PointPaymentService 积分支付处理类
package structual.facade;
public class PointPaymentService {
public void pay(Account account,PointsGift pointsGift){
AccountOperation.accountPay(account,pointsGift.getPrice());
}
}
ShoppingFecade 购物的门面类(shopGift方法本质是调用积分比较服务、积分支付服务子系统)
package structual.facade;
public class ShoppingFecade {
private QualifyService qualifyService;
private PointPaymentService pointPaymentService;
/**
* 这里就是一个门面
* @param account
* @param pointsGift
*/
public void shopGift(Account account, PointsGift pointsGift){
qualifyService.isAvailable(account,pointsGift);
pointPaymentService.pay(account, pointsGift);
}
public void setQualifyService(QualifyService qualifyService) {
this.qualifyService = qualifyService;
}
public void setPointPaymentService(PointPaymentService pointPaymentService) {
this.pointPaymentService = pointPaymentService;
}
}