Apex Design Patterns - 外观模式

Posted by Peter Dong on December 2, 2021

外观模式

外观模式(Facade Pattern)是一种结构型设计模式,它为复杂的子系统提供一个简化的接口,使得子系统更加易于使用。

定义

外观模式通过创建一个统一的类,为复杂的子系统提供一个更简单的接口。这个类通常被称为”外观类”(Facade),它封装了子系统的复杂性,并向客户端提供了一个更简单的接口。

优势

  1. 简化接口,提高易用性
  2. 降低客户端与子系统的耦合
  3. 提供了一个访问子系统的统一入口
  4. 隐藏了系统的复杂性
  5. 提高了代码的可维护性和可读性

为什么使用外观模式?

在复杂的系统中,可能存在许多相互依赖的类和接口。直接使用这些类可能会导致以下问题:

  1. 客户端代码变得复杂,难以维护
  2. 系统的学习曲线变陡,新开发人员难以快速上手
  3. 子系统的变化可能会影响到多个客户端

通过使用外观模式,我们可以提供一个简单的接口,隐藏底层系统的复杂性,从而使客户端代码更加简洁和易于理解。

问题示例

假设你需要在 Salesforce 中实现一个绘图功能,可以绘制圆形、矩形和正方形。每种形状都有自己的复杂实现。

外观模式解决方案

让我们使用外观模式来实现这个需求:

1. 定义形状接口

首先,我们定义一个通用的形状接口:

1
2
3
public interface Shape {
    void draw();
}

2. 实现具体形状类

然后,我们为不同的形状实现具体的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Circle implements Shape {
    public void draw() {
        System.debug('Circle::draw()');
    }
}

public class Rectangle implements Shape {
    public void draw() {
        System.debug('Rectangle::draw()');
    }
}

public class Square implements Shape {
    public void draw() {
        System.debug('Square::draw()');
    }
}

3. 创建外观类

接下来,我们创建一个外观类来封装所有形状的绘制操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ShapeFacade {
    private Shape circle;
    private Shape rectangle;
    private Shape square;

    public ShapeFacade() {
        circle = new Circle();
        rectangle = new Rectangle();
        square = new Square();
    }

    public void drawCircle() {
        circle.draw();
    }

    public void drawRectangle() {
        rectangle.draw();
    }

    public void drawSquare() {
        square.draw();
    }
}

4. 使用外观类

现在,客户端代码可以通过外观类来轻松地使用绘图功能:

1
2
3
4
5
6
7
8
9
public class Client {
    public static void drawShapes() {
        ShapeFacade shapeMaker = new ShapeFacade();
        
        shapeMaker.drawCircle();
        shapeMaker.drawRectangle();
        shapeMaker.drawSquare();
    }
}

外观模式的优势

  1. 简化接口:客户端只需要与外观类交互,而不需要了解底层的复杂实现。
  2. 解耦:外观类将客户端与子系统分离,降低了耦合度。
  3. 灵活性:可以在不影响客户端代码的情况下修改或扩展子系统。
  4. 封装复杂性:隐藏了系统的复杂性,使得系统更易于使用和维护。
  5. 单一职责:外观类专注于提供一个简单的接口,而具体实现则由各个子系统负责。

在 Salesforce 中的应用

在 Salesforce Apex 开发中,外观模式可以在以下场景中发挥作用:

  1. 复杂的 DML 操作:创建一个外观类来封装一系列相关的 DML 操作,简化数据操作流程。
  2. 集成外部系统:使用外观模式来封装与外部系统的复杂交互,提供一个简单的接口给其他开发者使用。
  3. 报表生成:创建一个外观类来封装复杂的报表生成逻辑,包括数据查询、处理和格式化。
  4. 批处理操作:使用外观模式来简化复杂的批处理操作,提供一个统一的接口来启动和管理批处理任务。
  5. 复杂的业务逻辑:当系统中存在复杂的业务规则和流程时,可以使用外观模式来提供一个简化的接口。

示例:Salesforce 外部系统集成外观

以下是一个在 Salesforce 中使用外观模式集成外部系统的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ExternalSystemFacade {
    private ExternalSystemAPI api;
    private DataTransformer transformer;
    private DataValidator validator;

    public ExternalSystemFacade() {
        api = new ExternalSystemAPI();
        transformer = new DataTransformer();
        validator = new DataValidator();
    }

    public void sendData(List<SObject> records) {
        List<ExternalData> transformedData = transformer.transform(records);
        List<ExternalData> validData = validator.validate(transformedData);
        api.send(validData);
    }

    public List<SObject> fetchData() {
        List<ExternalData> rawData = api.fetch();
        List<ExternalData> validData = validator.validate(rawData);
        return transformer.transformBack(validData);
    }
}

在这个例子中,ExternalSystemFacade类封装了与外部系统交互的复杂性,包括数据转换、验证和 API 调用。客户端代码只需要与这个外观类交互,而不需要了解底层的实现细节。

注意事项

  1. 避免过度使用外观模式,不要让外观类变成了新的复杂子系统。
  2. 外观模式不应该完全封闭对子系统的访问,仍应允许客户端在需要时直接访问子系统。
  3. 在设计外观类时,要注意平衡便利性和灵活性。

结论

外观模式是一种强大的设计模式,特别适合于简化复杂系统的接口。在 Salesforce Apex 开发中,合理使用外观模式可以提高代码的可读性、可维护性和可扩展性。通过提供一个统一的简化接口,我们可以使系统更易于使用,同时保持底层实现的灵活性。

记住,设计模式是工具,不是规则。在应用外观模式时,要根据具体情况和需求来决定,确保它真正为你的应用带来价值,而不是增加不必要的复杂性。


Buy Me a Coffee