Spring Boot 应用程序中的策略和工厂模式

211 阅读3分钟

策略和工厂模式是任何应用程序中最有用的设计模式。

如果您的分支代码包含大量“if 和 else”,那么策略模式是最佳选择。借助 Spring Boot 强大的依赖注入,当需要不同的对象子类型时,工厂模式就可以派上用场。

比如说:您正在使用 Spring Boot 构建一个报表微服务。对于此示例,假设一个带有 GET 端点的 REST 控制器将为不同类型的报告请求提供数据。我不会针对不同的图表请求使用大量的“if 和 else”,而是将演示工厂模式和策略模式的组合如何完美契合。

REST Controller

先来看一下 ReportController 代码。控制器有一个用于“Engine”类别的端点和另一个用于“ESS”类别的端点。

image.png

Report Service

报表服务是为各种类别的报表提供服务的组件。正如您所看到的,我为每个类别都有一个工厂类。来自服务的调用会调用工厂方法来获取带有reportId 的适当报告数据,并且userId 具有输入。

image.png

工厂模式和策略模式包结构

image.png

工厂模式

工厂模式是一种创建型模式,是许多框架中使用最广泛的模式之一。

报告 ID 可以是字符串或整数。但是,包含报告 ID 的枚举对于类型安全来说是最好的。下面的屏幕截图显示了引擎报告的枚举,每个枚举对应一个报告 ID。

image.png

比如下面这个 Factory 类,其中包含一个包含服务类的 Map:每个服务类对应一个报告 ID。报告 ID 枚举用作映射的键,以将报告 ID 与报告 ID 的服务类相关联。

传统的Java应用程序使用新的运算符来创建Service实例。但是,由于这是一个 Spring Boot 应用程序,Spring 框架会在启动期间扫描某种类型的 Service 类并填充 Map。

image.png

策略模式的起点是一个具有两个方法的接口。一种方法是获取报告 ID 枚举,另一种方法是根据用户 ID 获取实际报告数据。我创建了一个默认方法并添加了代码,以便在实际实现完成之前获取每个报告 ID 的一些模拟数据。当实际实现完成后,将不再使用此默认方法。此外,拥有默认方法可确保向后兼容性,而不会破坏代码。

image.png

服务类:Enum 类中的每个报告 ID 对应一个服务类

下面主要是两个服务类:每个服务类对应一个实现引擎报告接口的报告 ID 枚举类。

最初,我没有在 Service 类中添加实际的实现。这可以正常工作,因为我们在接口中有一个默认方法,可以从 JSON 文件返回模拟数据。

image.png

image.png

实际实现的服务类

下面是服务调用的实际实现,这将绕过接口中的默认方法。

image.png

服务类的 UML 图

image.png

image.png

image.png

image.png

当以简洁的方式设计解决方案时,工厂和策略模式的组合是一个很棒的模式,而不必在代码中使用笨拙的“if 和 else”。