门面模式也叫外观模式


门面模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。门面模式又称为外观模式,它是一种对象结构型模式。


举几个.生活中的例子:

1:去奶茶店买奶茶,我们只需要跟业务员说我要**奶茶,等会业务人员就把**奶茶给你了,咱们每个人来到店里只需要业务员说你要什么奶茶(前提是店里有的),您只要稍等一会,业务员便会给你的。整个过程咱们每个客人来只需要面对业务员就好了,不需要关注奶茶是怎么泡的。

业务员就是门面模式中的门面

2:病人去医院看病,医院搞个接待人员,所有的病人来医院只要找接待员就好了,至于后面的挂号、缴费、取药等工作,只是有接待人员去跟医院相关部门打交道,

接待人员就是门面模式中的门面


Java代码实现


/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 水
 */
public class Water {
public void getWater() {
        System.out.println("取水");
    }
}
/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 茶叶
 */
public class Tea {
public void getRedTea() {
        System.out.println("去红茶");
    }

public void getGreenTea() {
        System.out.println("去绿茶");
    }

public void getMilkTea() {
        System.out.println("去奶茶");
    }
}
/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 泡茶
 */
public class MakeTea {
public void makeTea(){
        System.out.println("泡茶");
    }
}
/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 打包
 */
public class PackingTea {
public void packingTea() {
        System.out.println("包装");
    }
}
/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 销售人员==门面
 */
public class SaleMen {

public void saleRedTea() {
        Water water = new Water();
        water.getWater();//获取水
        Tea tea = new Tea();
        tea.getRedTea();//获取红茶材料
        MakeTea makeTea = new MakeTea();
        makeTea.makeTea();//泡茶
        PackingTea packingTea = new PackingTea();
        packingTea.packingTea();//打包
    }

public void saleGreenTea() {
        Water water = new Water();
        water.getWater();//获取水
        Tea tea = new Tea();
        tea.getGreenTea();//获取绿茶材料
        MakeTea makeTea = new MakeTea();
        makeTea.makeTea();//泡茶
        PackingTea packingTea = new PackingTea();
        packingTea.packingTea();//打包
    }

public void saleMilkTea() {
        Water water = new Water();
        water.getWater();//获取水
        Tea tea = new Tea();
        tea.getMilkTea();//获取奶茶材料
        MakeTea makeTea = new MakeTea();
        makeTea.makeTea();//泡茶
        PackingTea packingTea = new PackingTea();
        packingTea.packingTea();//打包
    }
}


以上代码是水、茶叶、取茶、泡茶、打包相关的。

现在有三个客户来买茶:


/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 客户A要买绿茶
 */
public class CustomerA {
public static void main(String[] args) {
        SaleMen saleMen=new SaleMen();
        saleMen.saleGreenTea();
    }
}

结果: 


/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 客户B要买红茶
 */
public class CustomerB {
public static void main(String[] args) {
        SaleMen saleMen=new SaleMen();
        saleMen.saleRedTea();
    }
}

结果:

 

/**
 * @auther: lawt
 * @date: 2018/10/29 22
 * @Description: 客户C要买奶茶
 */
public class CustomerC {
public static void main(String[] args) {
        SaleMen saleMen = new SaleMen();
        saleMen.saleMilkTea();
    }
}

结果:



门面模式优缺点


优点

  • 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
    实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。

  • 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。

  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点

  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。

  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。