设计模式-外观模式

简介: 设计模式-外观模式

设计模式-外观模式

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

角色

外观模式主要包含如下角色:

  • Facade(外观角色):统一的高层接口,通过该角色将客户端的请求委托到不同的子系统。
  • SubSystem(子系统角色):相当于零件,多个零件组合完成一个功能。每个功能就是一个子系统。

场景分析

这是我们平时开发用的最多的模式之一,可以说我们每天都在用这个模式在写代码,只是我们可能没有意识到。

根据 “单一职责原则” ,在软件中将一个系统划分为若干个子系统有利于降低系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。

外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。 外观模式的目的在于降低系统的复杂程度。

外观模式从很大程度上提高了客户端使用的便捷性,使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能。

  • 比如通过在线商城买东西:判断是否有货-创建订单-支付扣款-物流创建-通知消息-用户积分新增。我们的一个下单操作可能会涉及很多系统之间的调用,而对外我们只是通过一个下单接口。
  • 去茶馆喝茶跟自己泡茶喝:去茶馆直接说像喝茶就什么茶都有了,还有美女倒茶。而自己泡茶要先烧水、洗茶具、温茶具、倒茶、洗茶具。
  • 比如电脑开机与关机。通过一个按钮就可以启动 CPU、内存、磁盘…用户不必跟每个硬件打交道。

代码实战

现在我们就模拟开关机通过外观模式。

我们的 CPU 、Disk、Memory 其实就是我们不同的 Service ,所以我们先定义出各个子系统的业务功能。

定义我们的子系统角色

public class CPU {
    public void startup(){
        System.out.println("cpu startup!");
    }
    public void shutdown(){
        System.out.println("cpu shutdown!");
    }
}
public class Disk {
    public void startup(){
        System.out.println("disk startup!");
    }
    public void shutdown(){
        System.out.println("disk shutdown!");
    }
}
public class Memory {
    public void startup(){
        System.out.println("memory startup!");
    }
    public void shutdown(){
        System.out.println("memory shutdown!");
    }
}

定义外观角色

/**
 * 外观类:给客户端提供了一个视图
 * Created by unique on 2017/5/14.
 */
public class ComputerFacade {
    private CPU cpu = new CPU();
    private Memory memory = new Memory();
    private Disk disk = new Disk();
    private ComputerFacade() {
    }
    // 单例模式
    private static class Holder {
        private static ComputerFacade instance = new ComputerFacade();
    }
    public static ComputerFacade getInstance() {
        return Holder.instance;
    }
    /**
     * 开机一步到位,用户不必根各个硬件打交道,就像一个开关搞定
     */
    public void startup(){
        System.out.println("start the computer!");
        cpu.startup();
        memory.startup();
        disk.startup();
        System.out.println("start computer finished!");
    }
    public void shutdown(){
        System.out.println("begin to close the computer!");
        cpu.shutdown();
        memory.shutdown();
        disk.shutdown();
        System.out.println("computer closed!");
    }
}

这样我们就可以通过 外观类实现开机,而不必去与每个硬件打交道。

定义我们的 客户端类调用开机与关机。

public class UserClient {
    public static void main(String[] args) {
        ComputerFacade facade = ComputerFacade.getInstance();
        facade.startup();
        System.out.println("时间到了,可以关机了.....");
        facade.shutdown();
    }
}

我们可以看到打印结果,只要调用一个方法就实现了繁琐的细节。

start the computer!
cpu startup!
memory startup!
disk startup!
start computer finished!
时间到了,可以关机了.....
begin to close the computer!
cpu shutdown!
memory shutdown!
disk shutdown!
computer closed!

缺点

  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

优点

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


相关文章
|
1月前
|
设计模式 存储 uml
C++ 设计模式实战:外观模式和访问者模式的结合使用,派生类访问基类的私有子系统
C++ 设计模式实战:外观模式和访问者模式的结合使用,派生类访问基类的私有子系统
29 1
|
6月前
|
设计模式 uml
结构型设计模式03-外观模式
结构型设计模式03-外观模式
20 0
|
3月前
|
设计模式 Go 开发工具
Golang设计模式——03外观模式
Golang设计模式——03外观模式
21 0
|
3月前
|
设计模式 Java 应用服务中间件
设计模式 -结构型模式_门面模式(外观模式) Facade Pattern 在开源软件中的应用
设计模式 -结构型模式_门面模式(外观模式) Facade Pattern 在开源软件中的应用
31 1
|
4月前
|
设计模式 前端开发 Java
Java设计模式【十一】:外观模式
Java设计模式【十一】:外观模式
22 0
|
1月前
|
设计模式 uml
设计模式之外观模式
设计模式之外观模式
|
1月前
|
设计模式 应用服务中间件 智能硬件
【设计模式】外观模式
【设计模式】外观模式
|
6月前
|
设计模式 Java 数据库连接
【设计模式——学习笔记】23种设计模式——外观模式Facade(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——外观模式Facade(原理讲解+应用场景介绍+案例介绍+Java代码实现)
49 0
|
3月前
|
设计模式 Java
聊聊Java设计模式-外观模式
外观(Facade)模式,又叫做门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问的模式。
35 1
聊聊Java设计模式-外观模式
|
3月前
|
设计模式 前端开发 数据库
【设计模式】之外观模式
外观模式是一种简化复杂系统接口的设计模式,在前端开发中有着广泛的应用。它可以帮助我们封装复杂的子系统,并提供一个简单易用的接口给客户端。通过使用外观模式,我们可以提高代码的可维护性、可读性和扩展性。但是需要注意避免过度使用外观模式,以免造成不必要的性能问题。
41 1