外观模式(门面模式)---脸有时比才华更重要

        声明:文章内容根据大牛博客的内容,自己理解后,给自己做的学习笔记,文末会附上大牛博客地址链接。有需要沟通交流的可加我QQ群:425120333
        外观模式也称作门面模式,是指对外提供一个专门操作内部子系统的外观类,外观类本身是并不涉及具体的业务逻辑的。举个生活中常见的例子,
    平时大街上的自动售货机,就可以说是使用了外观模式,用户只要选择相应的物品就可以买到自己想要的商品,至于怎么买到的,用户不用关心,
    由自动售货机内部自己实现。
public class VendingMachine {
    public static void main(String[] args) {
        //自动售货机的橱窗
        ShowCase showCase = new ShowCase();
        //买水
        showCase.buyWater();
        //买汽水
        showCase.buySoda();
        //买果汁
        showCase.buyJuice();
    }
}

/**
 * @introduce:展示的橱窗,相当于外观类
 * 
 */
class ShowCase {
    SellWater water = new SellWater();
    SellSoda soda = new SellSoda();
    SellJuice juice = new SellJuice();

    void buyWater() {
        water.method();
    }

    void buySoda() {
        soda.method();
    }

    void buyJuice() {
        juice.method();
    }
}

/**
 * @introduce:出售水
 * 
 */
class SellWater {
    void method() {
        System.out.println("获得了水");
    }
}

/**
 * @introduce:出售汽水
 * 
 */
class SellSoda {
    void method() {
        System.out.println("获得了汽水");
    }
}

/**
 * @introduce:出售果汁
 * 
 */
class SellJuice {
    void method() {
        System.out.println("获得了果汁");
    }
}

控制台输出:
获得了水
获得了汽水
获得了果汁

    代码很简单,结果也很明显,上面的就是最简单的外观模式了,通过外观类,避免了高层模块和底层模块的直接接触(解耦)。
    由于很多人一次性买的种类不是只有一种,要求向外提供个同时能购买水和果汁的按钮(或者是其他组合类似),这时代码应该怎么改,
我的第一想法是在外观类中添加个方法
    void buyWaterAndJuice() {
        water.method();
        juice.method();
    }
    只要在橱窗类中调用该方法,就能满足要求了。虽然要求是满足了不过这里会产生一个倒依赖的问题:要同时购买水和果汁就只能通过橱窗类,
相当于底层系统要依赖外观类才能被访问。这是不符合外观类的设计原则的,也违反了单一职责原则,想想如果别的对方发现该系统很好用,
只会将你的内部实现方法拿过去,不可能将你的橱窗也搬过去。而不将橱窗也拿过去就没法提供同时能购买水和果汁的功能了(因为该方法写在橱窗类中了)。
    写了这么多,就是为了说明一件事,外观类不要参与到具体的业务逻辑,只是提供个访问内部系统的路径就好。上面的问题(同时能购买水和果汁的功能)要解决也简单,
重新构建一个出售水和果汁的类。
/**
 * @introduce:出售水和果汁
 * 
 */
class SellWaterAndJuice {
    SellWater water = new SellWater();
    SellJuice juice = new SellJuice();

    void method() {
        water.method();
        juice.method();
    }
}
外观类改为:
/**
 * @introduce:展示的橱窗,相当于外观类
 * 
 */
class ShowCase {
    SellWater water = new SellWater();
    SellSoda soda = new SellSoda();
    SellJuice juice = new SellJuice();
    SellWaterAndJuice waterAndJuice = new SellWaterAndJuice();

    void buyWater() {
        water.method();
    }

    void buySoda() {
        soda.method();
    }

    void buyJuice() {
        juice.method();
    }

    void buyWaterAndJuice() {
         waterAndJuice.method(); 
    }
}
这样一来,自动售货机就提供了同时购买水和果汁的功能,也避免了上面描述的倒依赖问题。
参考大牛链接:http://www.cnblogs.com/zuoxiaolong/p/pattern12.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值