Java设计模式概述之结构型模式(外观模式)

六、外观模式(Facade)

概述

外观模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。外观模式的中的外观是一个抽象的概念,泛指外部的对象。外观对象中包含了若干的内部对象,内部的各个对象存在某些逻辑关联,从而组成简单或复杂的内部系统。外观模式使外观对象将若干内部对象的逻辑细节封装,使得外界不必直接调用内部对象,只需通过调用外观对象来实现某些功能。

这里写图片描述

应用场景

  • 需要一个的外观类来集成另一些类,实现一个系统,并通过该外观类的一些方法使得客户端能与外观类的内部系统间接交互。
  • 客户端与一些子系统的耦合度较高(存在继承关系等)。引入一个外观类,隐藏子系统的细节,从而降低客户端与子系统的耦合。

优势

  • 使客户端调用子系统更加方便
  • 客户端与外观类是松耦合关系,而外观类中子系统中的各类是紧耦合关系。

劣势

  • 违背开闭原则:对扩展开放;对修改关闭。

实例

下面是一个有关外观模式的实例。大家知道,一套完整电脑有:显示器、键盘、鼠标、主板、中央处理器、显卡、声卡、网卡、硬盘、内存条、电源。其中最重要的是主板,主板控制着各个电脑元件的启动与关闭。我们将主板类作为外观类,包装其他所有的电脑元器件。还定义了一个客户端类,用于开启或关闭电脑。

图片描述

代码:

/**
 * @author Hanlin Wang
 */

public class FacadeMode {
    public static void main(String[] args) {
        User user = new User();
        user.start();
        System.out.println("----");
        user.stop();

        /*
         *  运行结果:
         *  
         *  booting...
            CPU Start..
            Memory Start..
            Disk Start..
            booting finished
            ----
            shutdowning...
            CPU Stop..
            Memory Stop..
            Disk Stop..
            shutdowning finished
         */
    }
}

//定义接口
interface Function{
    void start();
    void stop();
}

//定义CPU、Memory、Disk类
class CPU implements Function{

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("CPU Start..");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("CPU Stop..");
    }

}

class Memory implements Function{

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("Memory Start..");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("Memory Stop..");
    }

}

class Disk implements Function{

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("Disk Start..");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("Disk Stop..");
    }

}

//定义Computer类
class Computer implements Function{
    private CPU cpu;
    private Memory memory;
    private Disk disk;
    public Computer(){
        cpu = new CPU();
        memory = new Memory();
        disk = new Disk();
    }
    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("booting...");
        cpu.start();
        memory.start();
        disk.start();
        System.out.println("booting finished");
    }
    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("shutdowning...");
        cpu.stop();
        memory.stop();
        disk.stop();
        System.out.println("shutdowning finished");
    }
}

//定义User类
class User implements Function{
    private Computer pc;
    public User(){
        pc = new Computer();
    }
    @Override
    public void start() {
        // TODO Auto-generated method stub
        pc.start();
    }
    @Override
    public void stop() {
        // TODO Auto-generated method stub
        pc.stop();
    }
}

介于电脑元件太多,上面代码删减了一部分。其中,User类为客户端类,Computer类相当于这里的外观类(主板,Mainboard),CPU、Memory、Disk为子类。Computer外观类通过包装CPU、Memory、Disk类,实现内部子系统的集成,并对外提供一个公共的开关机方法,从而实现客户端与CPU、Memory、Disk通过Computer类间接交互,实现低耦合。

问题

1、背景

外观模式违背了开闭原则。也就是说,若修改了外观类内部封装的子系统的代码,可能会使外观类被迫需要修改相应的代码。这样做不利与后期外观类拓展,影响了外观类的可拓展性。

现在抛出一个应用场景:某台电脑不需要使用Disk(硬盘)了,这样会造成外观类中的子系统的相关代码发生改变,违背了开闭原则。

怎么办?

2、解决方案

思路:依据“可扩展,不修改”的原则,我们只需要定义一个抽象的外观类,里面建立大概的子系统的逻辑框架,不实现具体的逻辑,让抽象外观类的子类去继承实现具体的逻辑即可。这正是整体与个体的思想,我们可以通过整体去扩展个体,但不能因为个体而修改整体的代码,这就是开闭原则的精髓所在。

这里写图片描述

定义一个抽象类AbstractComputer、定义两个普通类Computer、ComputerWithoutDisk继承AbstractComputer。Computer中实现由CPU、Disk、Memory组成的子系统;ComputerWithoutDisk中实现由CPU、Memory组成的子系统。

代码:

/**
 * @author Hanlin Wang
 */

public class FacadeMode {
    public static void main(String[] args) {
        User user = new User();
        user.start();
        System.out.println("\n\n\n");
        user.stop();
    }
}

//定义接口
interface Function{
    void start();
    void stop();
}

//定义CPU、Memory、Disk类
class CPU implements Function{

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("CPU Start..");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("CPU Stop..");
    }

}

class Memory implements Function{

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("Memory Start..");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("Memory Stop..");
    }

}

class Disk implements Function{

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("Disk Start..");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("Disk Stop..");
    }

}

//定义抽象外观类:AbstractComputer
abstract class AbstractComputer implements Function{
    public CPU cpu;
    public Memory memory;
    public Disk disk;
}

//定义Computer类
class Computer extends AbstractComputer{
    public Computer(){
        cpu = new CPU();
        memory = new Memory();
        disk = new Disk();
    }
    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("booting...");
        cpu.start();
        memory.start();
        disk.start();
        System.out.println("booting finished");
    }
    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("shutdowning...");
        cpu.stop();
        memory.stop();
        disk.stop();
        System.out.println("shutdowning finished");
    }
}

//定义ComputerWithoutDisk类
class ComputerWithoutDisk extends AbstractComputer{
    public ComputerWithoutDisk() {
        cpu = new CPU();
        memory = new Memory();
    }
    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("booting...");
        cpu.start();
        memory.start();
        System.out.println("booting finished");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("shutdowning...");
        cpu.stop();
        memory.stop();
        System.out.println("shutdowning finished");
    }

}

//定义User类
class User implements Function{
    private Computer pc;
    private ComputerWithoutDisk pc2;
    public User(){
        pc = new Computer();
        pc2 = new ComputerWithoutDisk();
    }
    @Override
    public void start() {
        // TODO Auto-generated method stub
        pc.start();
        System.out.println("\n\n\n"+"-----ComputerWithoutDisk-----");
        pc2.start();
    }
    @Override
    public void stop() {
        // TODO Auto-generated method stub
        pc.stop();
        System.out.println("\n\n\n"+"-----ComputerWithoutDisk-----");
        pc2.stop();
    }
}

执行结果如下:

booting…
CPU Start..
Memory Start..
Disk Start..
booting finished

—–ComputerWithoutDisk—–
booting…
CPU Start..
Memory Start..
booting finished

shutdowning…
CPU Stop..
Memory Stop..
Disk Stop..
shutdowning finished

—–ComputerWithoutDisk—–
shutdowning…
CPU Stop..
Memory Stop..
shutdowning finished

posted @ 2017-02-07 15:34  晚樨  阅读(315)  评论(0编辑  收藏  举报