声明:文章内容根据大牛博客的内容,自己理解后,给自己做的学习笔记,文末会附上大牛博客地址链接。有需要沟通交流的可加我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