十一、外观模式

一、外观模式

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

类型:结构型

使用场景
1.子系统越来越复杂,增加外观模式提供简单高层调用接口
2.构建多层系统结构,利用外观对象作为每层的入口,简化层间调用

优点
1.简化调用过程,无需深入了解子系统,防止带来风险
2.减少系统依赖,松散耦合
3.更好的划分访问层次
4.符合迪米特法则,即最少知道原则
5.结合抽象工厂,可以做到开闭原则,更好的扩展

缺点
1.增加子系统,扩展子系统行为容易引起风险。
2.不符合开闭原则—结合抽象工厂可避免

假设场景
以电商订单结算为例子,结算订单需要调用多个模块:
1.查询账户余额是否够
2.余额满足支付的情况下金额完成支付
3.清除购物车记录,修改订单状态完成支付
4.进入物流模块,显示物流信息

场景分析
这些每一个都与订单结算相关联,我们需要一一调用来完成结算功能。这样非常麻烦,就可以在这些操作的基础上增加一个高层接口,我们只需传入用户信息,在这个高层接口里面完成一系列的检验支付功能,由这个高层接口来判断是否满足订单结算功能,而不用与这一组接口产生耦合。只需调用这个高层接口,高层接口反馈支付成功还是不成功的信息,针对反馈结果进行处理。

开闭原则实现
上述场景来看,目前需要这四个步骤来完成订单结算,假设产品现在需要额外扩展一个积分功能,就需要对这个高层接口修改,或者某一个天积分功能不需要了,又要来注释掉积分模块的调用,这样不符合开闭原则。
可以再这个高层接口上再定义一层抽象接口,当需要增加积分功能时,重新额外扩展一个实现来完成积分功能的新增,只需在调用位置修改一下实现类,当不需要积分功能时将实现类替换回去即可。完全符合开闭原则。

二、代码实现

//账户类判断是否满足支付金额
public class Account {
    private Long balance;
    public Account(Long balance) {
        this.balance = balance;
    }
    public Account() {
    }
    public Long getBalance() {
        return balance;
    }
    public void setBalance(Long balance) {
        this.balance = balance;
    }
}

//是否可以支付
public class AccountService {

    public boolean isSettle(Account account, int purchaseMoney){
        if(account.getBalance()>=purchaseMoney){
            account.setBalance(account.getBalance()-purchaseMoney);
            System.out.println("支付完成,账户减少金额:"+purchaseMoney);
            return true;
        }else{
            return false;
        }
    }
}

//清除购物车记录
public class CartService {
    public void deleteRecore(){
        System.out.println("结算完成,清除购物车记录");
    }
}

//物流仓储模块,还缺少一个减少库存的函数
public class LogisticsService {
    public String  logistics(){
        System.out.println("进入物流系统");
        return UUID.randomUUID().toString();
    }
}

//结算完成-修改订单状态
public class OrderService {
    public void settleAccounts(){
        System.out.println("完成结算,修改订单状态");
    }
}


//高层接口调用---外观模式接口
public class OrderExchangeService {
    //假设spring 自动注入
    AccountService accountService = new AccountService();
    LogisticsService logisticsService = new LogisticsService();
    OrderService orderService = new OrderService();
    public String payment(Account account){
        String num = null;
        //假设订单价格是98
        int orderMoney = 98;
        boolean settle = accountService.isSettle(account, orderMoney);
        if(settle){
            orderService.settleAccounts();
            num = logisticsService.logistics();
        }
        return num;
    }
}

结合抽象工厂,完成积分功能扩展就不列举了,大概思路就是增加抽象高层接口,添加积分服务,实现抽象接口在里面添加积分服务的调用,main测试方法修改实现类即可。

大概就是这个道理,我没有做过电商系统其中很多细节可能不到位,这里目的是为了体验外观设计模式。

来源于:慕课网geely老师视频,其中大话设计模式一书中也有一个例子,其过程类似就不列举了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值