设计模式-外观模式

定义:外观模式又叫门面模式,提供一个接口用于访问子系统的一群接口。

类型:结构型

应用场景

  1. 子系统越来越复杂,提供了高层调用,简化使用难度。
  2. 使用者无需知道具体子系统如何工作的。

优点

  1. 简化调用流程,无需知道子系统如何运作。避免风险(子系统更改了,调用者也要做相关的测试。若抽象出了上层接口了。只需要测试上层接口传入参数能够接收到预定的结果即可。)
  2. 减少外层调用者对子系统的强依赖关系,降低耦合度。
  3. 划分了系统的层次结构。
  4. 符合迪米特法则。

缺点

  1. 增加子系统、扩展子系统时候引发风险

针对缺点的扩展知识

替代方案:使用消息中间件(mq)。使用消息中间件主要特点是异步处理。

源码应用的场景

  1. 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;
    }

}