门面模式
定义
门面模式亦成为外观模式(facade),旨在为调用者提供简单的接口,从而对调用者屏蔽底层的复杂组合逻辑。
示例分析
平时在购物商城浏览物品的时候,我们一般查看到以下信息(此处只是简单的描述,实际中远比这个复杂):
- 商品的基本信息(标题、图片、描述、备注、价格)
- 商品的优惠信息(优惠券、优惠价格)
- 商品的评论信息
这基本分别对应了:商品系统、营销系统、评论系统。
调用方和多个系统的交互关系如下:
我们发现调用方会和多个系统打交道,这会存在如下一些问题:
- 增加调用的复杂度,需要理解多个系统
- 代码复用差,多个调用方都需要和这么多系统进行交互。
此时我们应该想单独抽一个系统出来,这个系统和下方的多个系统进行交互,调用方只和这一个系统进行交互即可。这种方式即为门面模式。增加门面模式之后的系统交互关系如下:
代码如下所示:
// 客户端调用门面系统 public class Client { public static void main(String[] args) { FacadeSystem facadeSys = new FacadeSystem(); facadeSys.getProductAllInfo(); } } // 门店系统调用下游所有的系统 public class FacadeSystem { private MarketingSystem marketingSys; private CommentSystem commentSys; private ProductSystem productSys; public FacadeSystem() { marketingSys = new MarketingSystem(); commentSys = new CommentSystem(); productSys = new ProductSystem(); } public void getProductAllInfo() { System.out.println("门面系统查询所有下游系统的信息,包含:"); productSys.basicInfo(); marketingSys.discount(); commentSys.common(); } } // 评论系统 public class CommentSystem { public void common() { System.out.println("这是商品的评论信息"); } } // 影响系统 public class MarketingSystem { public void discount() { System.out.println("这是商品的优惠信息!"); } } // 商品系统 public class ProductSystem { public void basicInfo() { System.out.println("这是商品的基本信息!"); } }
优缺点
优点
- 减少系统依赖(调用方只和门面交互即可)
- 提供灵活性、安全性(门面对外屏蔽了下游具体实现)
缺点
- 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
- 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”