设计模式之——外观设计模式

    在软件开发中,有时候为了完成一项较为复杂的功能,一个客户类需要和多个业务类交互,而这些需要交互的业务类经常会作为一个整体出现,由于涉及到的类比较多,导致使用时代码较为复杂,此时,特别需要一个类似服务员一样的角色,由它来负责和多个业务类进行交互,而客户类只需与该类交互。它为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互。

    该模式经常使用,特别是项目越大的时候,在设计原则中,为了减少不同功能之间的依赖性,我们经常采用单一原则对功能做子模块的划分,保证各司其职互不干扰,这样就会导致客户端使用的时候会各种组合功能,导致冗杂,不方便维护,一动则动全身。

    鉴于整个系统对子系统有很强的依赖性这种情况,我们可以新增一个凌驾于子系统的接口,并提供可以访问子系统的入口,让客户端直接使用该高级层,不用关心 子系统具体是怎么实现的。

    咱们举个例子吧,我们吃饭,自己可以做吧,需要准备餐具、食材、然后自己炒。我们将这些步骤抽取出高级接口,那就是类似我们下馆子,这个高级接口就是服务员,我们只需要告诉服务员我们要吃啥就行,后厨相关人员就会做出来送到你的面前,我才不考虑他们是怎么做出来的呢,而且新增的接口并不影响各个子系统:

定义三个子系统:

package com.zndroid.dm.FacadeModel.SubSystem;

/**
 * Created by luzhenyu on 2017/9/8.
 */
/**餐具子系统*/
public class DishWasher {

    private String[] dishs = {"小碟子", "盘子", "鱼池", "蒸笼"};

    public boolean isHaveEmptyDish() {
        System.out.println("后厨餐具充足并已经消毒");
        return dishs.length == 0;
    }

    public String getDishs(int index) {
        return dishs[index];
    }

    public void setDishs(String[] dishs) {
        this.dishs = dishs;
    }
}
package com.zndroid.dm.FacadeModel.SubSystem;

/**
 * Created by luzhenyu on 2017/9/8.
 */
/**食材提供子系统*/
public class MaterialWasher {

    public String getFoodMaterial() {
        return "提供菜品原料";
    }
}
package com.zndroid.dm.FacadeModel.SubSystem;

/**
 * Created by luzhenyu on 2017/9/8.
 */

public class Chef {

    public String getFood(String index) {
        String res = "";
        switch (index) {
            case "蒸笼":
                res = "扬州小笼包";
                break;
            case "鱼池":
                res = "松鼠桂鱼";
                break;
            case "小碟子":
                res = "开胃花生米";
                break;
            case "盘子":
                res = "宫保鸡丁";
                break;
            default:
                res = "不会做";
                break;
        }

        return res;
    }
}
然后定义一个高级接口(服务员)用于访问子系统:

package com.zndroid.dm.FacadeModel;

/**
 * Created by luzhenyu on 2017/9/8.
 */

import com.zndroid.dm.FacadeModel.SubSystem.Chef;
import com.zndroid.dm.FacadeModel.SubSystem.DishWasher;
import com.zndroid.dm.FacadeModel.SubSystem.MaterialWasher;

/**类似服务员,用于提供访问子系统的高级接口*/
public class Facade {

    DishWasher dishWasher;
    MaterialWasher materialWasher;
    Chef chef;

    public Facade() {
        dishWasher = new DishWasher();//提供餐具的
        materialWasher = new MaterialWasher();//提供食材的
        chef = new Chef();//大厨
    }

    public void getFoooood() {
        if (!dishWasher.isHaveEmptyDish()) {
            materialWasher.getFoodMaterial();
            System.out.println(chef.getFood(dishWasher.getDishs(0)));
            System.out.println(chef.getFood(dishWasher.getDishs(1)));
            System.out.println(chef.getFood(dishWasher.getDishs(2)));
            System.out.println(chef.getFood(dishWasher.getDishs(3)));
        }
    }
}
来看一下使用:

/**
         * 外观模式
         * 为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
         * 它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。
         * 不管子系统实现有多么复杂,客户端毫不关注。
         *
         * 这个模式有个前提是,客户端和子系统有很大的依赖性,子系统之间相对独立,不然增加这个外观角色是没有必要的
         *
         * 优点
         * ①.对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。
         * 通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
         * ②.降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。
         * 一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
         * ③.只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
         * 缺点
         * ①.不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
         * ②.在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
         * */
        //半下午的就饿了
        //想法搞点吃的,自己做多麻烦 ,下馆子~
        //服务员  上菜
        Facade facade = new Facade();
        facade.getFoooood();
        log("----------------我是分割线-----------------");
运行结果:

[ ======================================== ]
后厨餐具充足并已经消毒
开胃花生米
宫保鸡丁
松鼠桂鱼
扬州小笼包
[ ----------------我是分割线----------------- ]
[ ======================================== ]

【欢迎上码】

【微信公众号搜索 h2o2s2】


猜你喜欢

转载自blog.csdn.net/luzhenyuxfcy/article/details/77895906
今日推荐