菜鸟教程 -- 学的不仅是技术,更是梦想!

设计模式
(追記) (追記ここまで)

外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

介绍

意图

为一个复杂的子系统提供一个一致的高层接口。这样,客户端代码就可以通过这个简化的接口与子系统交互,而不需要了解子系统内部的复杂性。

主要解决的问题

  • 降低客户端与复杂子系统之间的耦合度。
  • 简化客户端对复杂系统的操作,隐藏内部实现细节。

使用场景

  • 当客户端不需要了解系统内部的复杂逻辑和组件交互时。
  • 当需要为整个系统定义一个清晰的入口点时。

实现方式

  • 创建外观类:定义一个类(外观),作为客户端与子系统之间的中介。
  • 封装子系统操作:外观类将复杂的子系统操作封装成简单的方法。

关键代码

  • Facade类:提供高层接口,简化客户端与子系统的交互。
  • 子系统类:实现具体的业务逻辑,被Facade类调用。

应用实例

  1. 医院接待:医院的接待人员简化了挂号、门诊、划价、取药等复杂流程。
  2. Java三层架构:通过外观模式,可以简化对表示层、业务逻辑层和数据访问层的访问。

优点

  1. 减少依赖:客户端与子系统之间的依赖减少。
  2. 提高灵活性:子系统的内部变化不会影响客户端。
  3. 增强安全性:隐藏了子系统的内部实现,只暴露必要的操作。

缺点

  • 违反开闭原则:对子系统的修改可能需要对外观类进行相应的修改。

使用建议

  • 在需要简化复杂系统访问时使用外观模式。
  • 确保外观类提供的方法足够简单,以便于客户端使用。

注意事项

  • 外观模式适用于层次化结构,可以为每一层提供一个清晰的入口。
  • 避免过度使用外观模式,以免隐藏过多的细节,导致维护困难。

结构

外观模式涉及以下核心角色:

  • 外观(Facade):

    • 提供一个简化的接口,封装了系统的复杂性。外观模式的客户端通过与外观对象交互,而无需直接与系统的各个组件打交道。
  • 子系统(Subsystem):

    • 由多个相互关联的类组成,负责系统的具体功能。外观对象通过调用这些子系统来完成客户端的请求。
  • 客户端(Client):

    • 使用外观对象来与系统交互,而不需要了解系统内部的具体实现。

实现

我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。下一步是定义一个外观类 ShapeMaker

ShapeMaker 类使用实体类来代表用户对这些类的调用。FacadePatternDemo 类使用 ShapeMaker 类来显示结果。

外观模式的 UML 图

步骤 1

创建一个接口。

Shape.java

publicinterfaceShape{voiddraw(); }

步骤 2

创建实现接口的实体类。

Rectangle.java

publicclassRectangleimplementsShape{ @Overridepublicvoiddraw(){System.out.println("Rectangle::draw()"); }}

Square.java

publicclassSquareimplementsShape{ @Overridepublicvoiddraw(){System.out.println("Square::draw()"); }}

Circle.java

publicclassCircleimplementsShape{ @Overridepublicvoiddraw(){System.out.println("Circle::draw()"); }}

步骤 3

创建一个外观类。

ShapeMaker.java

publicclassShapeMaker{privateShapecircle; privateShaperectangle; privateShapesquare; publicShapeMaker(){circle = newCircle(); rectangle = newRectangle(); square = newSquare(); }publicvoiddrawCircle(){circle.draw(); }publicvoiddrawRectangle(){rectangle.draw(); }publicvoiddrawSquare(){square.draw(); }}

步骤 4

使用该外观类画出各种类型的形状。

FacadePatternDemo.java

publicclassFacadePatternDemo{publicstaticvoidmain(String[]args){ShapeMakershapeMaker = newShapeMaker(); shapeMaker.drawCircle(); shapeMaker.drawRectangle(); shapeMaker.drawSquare(); }}

步骤 5

执行程序,输出结果:

Circle::draw()
Rectangle::draw()
Square::draw()
AI 思考中...

4 篇笔记 写笔记

  1. #0

    感觉电脑的例子更形象:

    电脑整机是 CPU、内存、硬盘的外观。有了外观以后,启动电脑和关闭电脑都简化了。

    直接 new 一个电脑。

    在 new 电脑的同时把 cpu、内存、硬盘都初始化好并且接好线。

    对外暴露方法(启动电脑,关闭电脑)。

    启动电脑(按一下电源键):启动CPU、启动内存、启动硬盘

    关闭电脑(按一下电源键):关闭硬盘、关闭内存、关闭CPU

    更多参考内容

    8年前 (2018年03月21日)
  2. #0

    圣光教徒

    120***[email protected]

    50

    我把楼上那哥们说的电脑例子写了一哈

    /** * 电脑接口 */
    public interface Computer {
     void open();
    }
    /** * CPU类 */
    class Cpu implements Computer {
     @Override
     public void open() {
     System.out.println("启动CPU");
     }
    }
    /** * 内存类 */
    class Ddr implements Computer {
     @Override
     public void open() {
     System.out.println("启动内存");
     }
    }
    /** * 硬盘类 */
    class Ssd implements Computer {
     @Override
     public void open() {
     System.out.println("启动硬盘");
     }
    }
    /** * 外观类 */
    public class Facade {
     private Computer cpu;
     private Computer ddr;
     private Computer ssd;
     /** * 启动cpu */
     public void onCPU() {
     cpu = new Cpu();
     cpu.open();
     }
     /** * 启动内存 */
     public void onDDR() {
     ddr = new Ddr();
     ddr.open();
     }
     /** * 启动硬盘 */
     public void onSSD() {
     ssd = new Ssd();
     ssd.open();
     }
    }
    public class FacadeTest34 {
     public static void main(String[] args) {
     Facade facade = new Facade();
     facade.onSSD();
     }
    }

    圣光教徒

    120***[email protected]

    7年前 (2019年06月19日)
  3. #0

    Lonnie

    354***[email protected]

    3

    Swift 实现:

    class Facade {
     struct Rectangle: Shape {
     func draw() {
     print("Rectangle::draw()")
     }
     }
     struct Square: Shape {
     func draw() {
     print("Square::draw()")
     }
     }
     struct Circle: Shape {
     func draw() {
     print("Circle::draw()")
     } 
     }
     struct ShapeMaker {
     private let circle = Circle()
     private let rectangle = Rectangle()
     private let square = Square()
     func drawCircle() {
     circle.draw()
     }
     func drawRectangle() {
     rectangle.draw()
     }
     func drawSquare() {
     square.draw()
     }
     } 
     func execute() {
     let maker = ShapeMaker()
     maker.drawCircle()
     maker.drawRectangle()
     maker.drawSquare()
     }
    }

    Lonnie

    354***[email protected]

    7年前 (2019年12月11日)
  4. #0

    Siskin.xu

    sis***@sohu.com

    2

    Python 方式:

    #Facade Pattern with Python code
    from abc import abstractmethod,ABCMeta
    # 创建一个接口
    class Shape(metaclass=ABCMeta):
     def draw(self):
     pass
    # 创建实现接口的实体类
    class Rectangle(Shape):
     def draw(self):
     print("Rectangle.draw()")
    class Circle(Shape):
     def draw(self):
     print("Circle.draw()")
    class Square(Shape):
     def draw(self):
     print("Square.draw()")
    # 创建外观类Facade
    class ShapeMaker():
     _circle = ""
     _rectangle = ""
     _square = ""
     def __init__(self):
     self._circle = Circle()
     self._rectangle = Rectangle()
     self._square = Square()
     
     def drawCircle(self):
     self._circle.draw()
     def drawRectangle(self):
     self._rectangle.draw()
     def drawSquare(self):
     self._square.draw()
    # 调用输出
    if __name__ == '__main__':
     shapeMaker = ShapeMaker()
     shapeMaker.drawCircle()
     shapeMaker.drawRectangle()
     shapeMaker.drawSquare()

    Siskin.xu

    sis***@sohu.com

    6年前 (2020年02月28日)

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /