设计模式系列4---对外包办的门面模型

说到门面这个词, 在我国的文化就很有内涵啦!
不过Facade 这个词有时候翻译为外观。
到底该怎么理解这个门面模型呢?

我们可以看一个公司的架构

enter image description here

董事长同他的总经理说他要把今年的销售额翻30倍吧。总经理听了脸都青了,但没办法,还是得干活,说行,然后就把指标发下去了,让下面的干活去。即把实际做的事情分割给不同部门,然后自己又在办公室继续玩电脑了。

这样对于发号施令的董事长,不需要知道具体的细节,只需要记得找总经理负责这事就好了。
就是苦了这个总经理,需要了解所有的部门情况,分割不同的事情给下面的人干活去。

所以我们可以简化这个流程成这样的,老板说要去赚钱,总经理找了技术部开发了个杀手级应用,然后销售部门就负责去卖,从而达到赚钱的效果。

这样我们的demo可以这么写:

public class Boss {

    public static void main(String[] args) {

        MakeProfitManager makeProfitManager = new ManagerA();
        makeProfitManager.makeMoreMoney();
    }
}

public class ManagerA extends MakeProfitManager {

    TechnologDepartment technologDepartment = new TechnologDepartment();
    SalesDepartment salesDepartment = new SalesDepartment(); 

    @Override
    public void makeMoreMoney() { 
            //技术部的开发了一个厉害的产品
            technologDepartment.releaseAmazingProduct();
            //销售的买了产品,赚了钱
            salesDepartment.saleProductMakeProfits(); 
        }
    }
}


public abstract class MakeProfitManager {
    public abstract void makeMoreMoney();
}  

public class TechnologDepartment {
    public void releaseAmazingProduct() {
    }
}

public class SalesDepartment {

    public void saleProductMakeProfits() {

    }
}    

通过这样的门面写法,我们老板就只需要找到能赚钱的经理,告诉他去给我赚钱就好了。
如果这个经理看了下这个业绩,不怎样,可以悄悄的升级下方案,老板也不用操心。

public class ManagerA extends MakeProfitManager {

    TechnologDepartment technologDepartment = new TechnologDepartment();
    SalesDepartment salesDepartment = new SalesDepartment();
    WaterArmyDepartment waterArmyDepartment = new WaterArmyDepartment();

    @Override
    public void makeMoreMoney() {

        for (int i = 0; i < 3; i++) {
            //技术部的开发了一个厉害的产品
            technologDepartment.releaseAmazingProduct();
            //销售的买了产品,赚了钱
            salesDepartment.saleProductMakeProfits();
            //找水军去帮忙干活
            waterArmyDepartment.MakeRumour();
        }
    }
}

public class WaterArmyDepartment {

    public void MakeRumour() {

    }
}

这样我们的经理A直接开发三个产品去卖,还请了水军,机智如他啊!


这是大公司的样子,如果是小公司的话可能是这样的

public class Boss {

    public static void main(String[] args) {

        //老板找来了技术和销售的人。
        TechnologDepartment technologDepartment = new TechnologDepartment();
        SalesDepartment salesDepartment = new SalesDepartment();            
        //开了个会,要求他们去开发一个好产品,然后去叫销售的把他卖出去。    
        technologDepartment.releaseAmazingProduct();          
        salesDepartment.saleProductMakeProfits();            
    }
}

具体的整个实现过程都要求老板去落实,去跟进,这对于老板来说很累,而且效果不一定好,毕竟老板还有很多事要做的,把握公司大方向等等。更何况有时候,老板脑热,发现请水军很有效果,就修改了下流程。

 public class Boss {

    public static void main(String[] args) {
        TechnologDepartment technologDepartment = new TechnologDepartment();
        SalesDepartment salesDepartment = new SalesDepartment();
        WaterArmyDepartment waterArmyDepartment = new WaterArmyDepartment();

        technologDepartment.releaseAmazingProduct();
        salesDepartment.saleProductMakeProfits();
        waterArmyDepartment.MakeRumour();                         
    }
}

这样的频繁修改显然不怎么好,如果这个老板就是我们要写的客户端,每次接口修改,为了实现一个赚钱方法,我们都要去加这么多方法的话,很显然不妥妥的。所以我们能感觉到了门面模式的威力了嘛?

当然了,门面除了这样的整合功能外,他和我们的代理一样,有一个功效,就是屏蔽部分内容。

实际情况

上面的案例只是为了说情况而夸张写的案例,实际我们可能并不会这么写。
毕竟我们是偏向于OCP原则的,像上面那样的修改应该是要关闭的
而且一般更多的是一个函数值对应某一个类的一个方法。

    public class ManagerA extends MakeProfitManager {

        SalesDepartment salesDepartment = new SalesDepartment();

        @Override
        public void makeMoreMoney() {
             salesDepartment.saleProductMakeProfits();
        }
}

例如像上面这样的,最终这个总经理只是督促销售部门去多卖点产品赚钱而已。
希望你能意会到我的意思。

屏蔽部分内容

假设有一天,总经理出去赌钱,结果赔惨了,但一时半会手头紧,一时起了坏主意,想到挪用公款,就叫产品部的去做个别的产品,叫销售的去卖,不过不让老板知道。

public class ManagerB extends MakeProfitManager {

    TechnologDepartment technologDepartment = new TechnologDepartment();
    SalesDepartment salesDepartment = new SalesDepartment();

    @Override
    public void makeMoreMoney() {

        for (int i = 0; i < 3; i++) {
            //技术部的开发了一个厉害的产品
            technologDepartment.releaseAmazingProduct();
            //销售的买了产品,赚了钱
            salesDepartment.saleProductMakeProfits(); 
        }
        makePrivateMoney();
    }

    private void makePrivateMoney() {
        technologDepartment.releasePrivateProduct();
        salesDepartment.salePrivateProduct();
    }
}


public abstract class MakeProfitManager {
    public abstract void makeMoreMoney();
}

public class TechnologDepartment {
    public void releaseAmazingProduct() {
    }
    //偷偷开发产品
    public void releasePrivateProduct() {
    }
}

public class SalesDepartment {

    public void saleProductMakeProfits() {
    }

    //偷偷卖产品
    public void salePrivateProduct() {
    }
}

我们看到,整个过程,这个总经理还偷偷的搞了外快,但董事长不知道。
这就是屏蔽了部分内容,上一层不知道背后的逻辑,尽管这方法是public的。
后面还有别的模式也有类似的功效,因为有这么一个“中间人”但在中间。

后记

这个门面模式某种程度和代理还是挺像的。
例如极端情况下,这个门面里面只有一个实际干活的类时候。

热评文章