Java设计模式——外观模式

        外观模式说,也叫门面模式,这个模式简单也简单,说复杂也复杂。简单是因为,外观模式很好理解,有可能你已经用到过这个模式,只是你还不知道这个是外观模式。说复杂是因为外观模式是为了将复杂的逻辑封装起来,向外暴露出一个/多个简单的接口供使用者使用,而这个“复杂的逻辑”根据实际情况会有不同的难度。

一、定义

        为子系统提供若干个接口,外观模式提供一个高层级的接口,外界只需调用高层接口,就可以实现子系统若干接口的逻辑。而高层接口的使用者无需关心这若干个子系统做了什么。

        大白话:使用者只关心自己做什么,然后得到想要的结果,并不关心中间做了什么。

UML:

Facade:系统对外的统一接口

SystemA/B/C:子系统接口

二、使用场景

1、为一个复杂的子系统提供一个简单的接口。子系统往往因为不断的演化二变得越来越复杂,或者被替换,而Facade可以提供一个统一的接口,对外隐藏子系统的变化。

2、当你需要构建一个层次结构的子系统时,而子系统间又有相互依赖时,可以使用Facade定义每层的入口点,仅通过Facade进行通信,从而简化了子系统间的依赖关系。

        举个场景栗子:现在比较流行订餐送餐,比如X团,X了么,X度外卖······我现在想要订餐,那么我需要做的是:下单——吃饭,就这么简单。而中间可能有许许多多复杂的过程,并没有暴露给你,比如:下单——餐馆接单——餐馆做饭——餐馆将食物打包——叫来送餐骑手——骑手取餐——骑手送餐——半路车胎扎了——补车胎——继续送餐到你手里——吃饭,我们需要把中间复杂的过程,对使用者只暴露一个“下单”的接口,下单后自动完成中间的过程。

三、示例

          首先,把子系统的主接口定义好:

/**
 * 超类
 */
public abstract class Work {

    public abstract void doSomething();
}


        接下来,定义若干个子系统接口:

/**
 * 餐馆接单
 */
public class TakeOrder extends Work {
    @Override
    public void doSomething() {
        System.out.println("餐馆接单,接到一份鱼香肉丝盖饭!");
    }
}

 

/**
 * 餐馆做饭
 */
public class Cook extends Work {
    @Override
    public void doSomething() {
        System.out.println("餐馆做饭,做一份鱼香肉丝盖饭!");
    }
}

 

/**
 * 餐馆打包食物
 */
public class PackFood extends Work {
    @Override
    public void doSomething() {
        System.out.println("餐馆打包食物,打包一份鱼香肉丝盖饭!");
    }
}

 

/**
 * 餐馆叫来一个送餐员
 */
public class CallMan extends Work {
    @Override
    public void doSomething() {
        System.out.println("餐馆叫来一个送餐员!");
    }
}

 

/**
 * 送餐员取餐
 */
public class TakeFood extends Work {
    @Override
    public void doSomething() {
        System.out.println("送餐员取餐,取到一份鱼香肉丝盖饭!");
    }
}

 

/**
 * 送餐员送餐
 */
public class DeliveryFood extends Work {
    @Override
    public void doSomething() {
        System.out.println("送餐员送餐,一份鱼香肉丝盖饭!");
    }
}

 

/**
 * 送餐员车胎扎了
 */
public class TyresTiepUp extends Work {
    @Override
    public void doSomething() {
        System.out.println("送餐员车胎扎了!");
    }
}

 

/**
 * 送餐员补车胎
 */
public class FixTyres extends Work {
    @Override
    public void doSomething() {
        System.out.println("送餐员补车胎!");
    }
}

 

/**
 * 送餐员继续送餐
 */
public class DeliveryFood2 extends Work {
    @Override
    public void doSomething() {
        System.out.println("送餐员继续送餐,一份鱼香肉丝盖饭!");
    }
}

        够多,够复杂!但是作为你,你并不关心上面那些流程,毕竟是花了钱的,只管下单:

public class XTuan {

    /**
     * 下单
     */
    public void placeOrder() {
        //餐馆接单
        TakeOrder takeOrder = new TakeOrder();
        //餐馆做饭
        Cook cook = new Cook();
        //餐馆将食物打包
        PackFood packFood = new PackFood();
        //叫来送餐骑手
        CallMan callMan = new CallMan();
        //骑手取餐
        TakeFood takeFood = new TakeFood();
        //骑手送餐
        DeliveryFood deliveryFood = new DeliveryFood();
        //半路车胎扎了
        TyresTiepUp tyresTiepUp = new TyresTiepUp();
        //补车胎
        FixTyres fixTyres = new FixTyres();
        //继续送餐到你手里
        DeliveryFood2 deliveryFood2 = new DeliveryFood2();
        takeOrder.doSomething();
        cook.doSomething();
        packFood.doSomething();
        callMan.doSomething();
        takeFood.doSomething();
        deliveryFood.doSomething();
        tyresTiepUp.doSomething();
        fixTyres.doSomething();
        deliveryFood2.doSomething();
    }

}

我们关心的只是下载了外卖,然后订餐,然后吃:

    public static void main(String[] args) {
        //实例化一个X团外卖
        XTuan xt = new XTuan();
        System.out.println("下单啦~下一份鱼香肉丝吧!");
        xt.placeOrder();
        System.out.println("餐到手,可以吃了!");
    }

log:

12-21 15:51:23.470 29104-29104/? I/System.out: 下单啦~下一份鱼香肉丝吧!
12-21 15:51:23.470 29104-29104/? I/System.out: 餐馆接单,接到一份鱼香肉丝盖饭!
12-21 15:51:23.470 29104-29104/? I/System.out: 餐馆做饭,做一份鱼香肉丝盖饭!
12-21 15:51:23.470 29104-29104/? I/System.out: 餐馆打包食物,打包一份鱼香肉丝盖饭!
12-21 15:51:23.470 29104-29104/? I/System.out: 餐馆叫来一个送餐员!
12-21 15:51:23.470 29104-29104/? I/System.out: 送餐员取餐,取到一份鱼香肉丝盖饭!
12-21 15:51:23.470 29104-29104/? I/System.out: 送餐员送餐,一份鱼香肉丝盖饭!
12-21 15:51:23.470 29104-29104/? I/System.out: 送餐员车胎扎了!
12-21 15:51:23.470 29104-29104/? I/System.out: 送餐员补车胎!
12-21 15:51:23.470 29104-29104/? I/System.out: 送餐员继续送餐,一份鱼香肉丝盖饭!
12-21 15:51:23.470 29104-29104/? I/System.out: 餐到手,可以吃了!

        当然,这只是比较简单的用法,还有更多复杂的场景需要在实际项目中用到,这就需要熟能生巧了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值