在软件开发中,我们经常遇到需要根据不同的条件执行不同的行为的情况。例如,在电商系统中,可能需要根据不同的商品类型(如电子产品、书籍、食品等)来决定如何处理商品的信息展示、库存管理、价格计算等。这时,策略模式可以成为一个非常有用的工具。
什么是策略模式?
策略模式是一种行为设计模式,它使你能够在运行时改变对象的行为。在策略模式中,一组行为被封装为不同的类,每个类代表一种算法或行为。然后,上下文(Context)使用一个接口或抽象类来引用这些策略之一,以便可以在运行时切换策略。
实战:根据商品类型进行不同处理
步骤1:定义策略接口
首先,我们需要定义一个策略接口,这个接口将定义所有策略共有的行为。
Java
深色版本
1package com.example.demo.strategy;
2
3import com.example.demo.model.Product;
4
5public interface ProductStrategy {
6
7 /**
8 * 根据商品类型处理商品信息
9 *
10 * @param product 商品对象
11 */
12 void handleProduct(Product product);
13
14}
步骤2:实现具体的策略
接下来,我们需要为每种商品类型实现具体的策略。
电子产品处理策略
Java
深色版本
1package com.example.demo.strategy;
2
3import com.example.demo.model.Product;
4
5public class ElectronicsProductStrategy implements ProductStrategy {
6
7 @Override
8 public void handleProduct(Product product) {
9 System.out.println("Handling electronics product: " + product.getName());
10 // 电子产品的特殊处理逻辑
11 }
12}
书籍处理策略
Java
深色版本
1package com.example.demo.strategy;
2
3import com.example.demo.model.Product;
4
5public class BookProductStrategy implements ProductStrategy {
6
7 @Override
8 public void handleProduct(Product product) {
9 System.out.println("Handling book product: " + product.getName());
10 // 书籍的特殊处理逻辑
11 }
12}
步骤3:创建策略工厂
为了简化策略的选择过程,我们将使用Map来存储策略实例,而不是使用switch语句。
Java
深色版本
1package com.example.demo.factory;
2
3import com.example.demo.strategy.BookProductStrategy;
4import com.example.demo.strategy.ElectronicsProductStrategy;
5import com.example.demo.strategy.ProductStrategy;
6import org.springframework.beans.factory.annotation.Autowired;
7import org.springframework.context.ApplicationContext;
8import org.springframework.stereotype.Component;
9
10import java.util.Map;
11import java.util.concurrent.ConcurrentHashMap;
12
13@Component
14public class ProductStrategyFactory {
15
16 private final Map<String, ProductStrategy> strategies;
17
18 @Autowired
19 public ProductStrategyFactory(ApplicationContext applicationContext) {
20 this.strategies = new ConcurrentHashMap<>();
21 strategies.put("electronics", applicationContext.getBean(ElectronicsProductStrategy.class));
22 strategies.put("book", applicationContext.getBean(BookProductStrategy.class));
23 }
24
25 public ProductStrategy getProductStrategy(String type) {
26 ProductStrategy strategy = strategies.get(type.toLowerCase());
27 if (strategy == null) {
28 throw new IllegalArgumentException("Unsupported product type: " + type);
29 }
30 return strategy;
31 }
32}
步骤4:创建上下文
上下文类将负责选择正确的策略,并调用它来处理商品。
Java
深色版本
1package com.example.demo.context;
2
3import com.example.demo.factory.ProductStrategyFactory;
4import com.example.demo.model.Product;
5import com.example.demo.strategy.ProductStrategy;
6import org.springframework.beans.factory.annotation.Autowired;
7import org.springframework.stereotype.Component;
8
9@Component
10public class ProductContext {
11
12 private final ProductStrategyFactory strategyFactory;
13
14 @Autowired
15 public ProductContext(ProductStrategyFactory strategyFactory) {
16 this.strategyFactory = strategyFactory;
17 }
18
19 public void handleProduct(Product product) {
20 ProductStrategy strategy = strategyFactory.getProductStrategy(product.getType());
21 strategy.handleProduct(product);
22 }
23}
步骤5:创建商品实体类
创建一个简单的商品实体类来存储商品的基本信息。
Java
深色版本
1package com.example.demo.model;
2
3public class Product {
4
5 private String name;
6 private String type;
7
8 public Product(String name, String type) {
9 this.name = name;
10 this.type = type;
11 }
12
13 public String getName() {
14 return name;
15 }
16
17 public String getType() {
18 return type;
19 }
20}
步骤6:创建控制器
创建一个控制器来演示如何根据商品类型选择并调用相应的策略。
Java
深色版本
1package com.example.demo.controller;
2
3import com.example.demo.context.ProductContext;
4import com.example.demo.model.Product;
5import org.springframework.beans.factory.annotation.Autowired;
6import org.springframework.web.bind.annotation.*;
7
8@RestController
9@RequestMapping("/products")
10public class ProductController {
11
12 private final ProductContext productContext;
13
14 @Autowired
15 public ProductController(ProductContext productContext) {
16 this.productContext = productContext;
17 }
18
19 @PostMapping("/{type}")
20 public String handleProduct(@RequestBody Product product, @PathVariable String type) {
21 product.setType(type); // 设置商品类型
22 productContext.handleProduct(product);
23 return "Product handled successfully.";
24 }
25}
步骤7:测试
启动Spring Boot应用,并发送一个POST请求到/products/{type},其中{type}是商品类型,如electronics或book。
Bash
深色版本
1curl -X POST "http://localhost:8080/products/electronics" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\":\"iPhone 13\", \"type\":\"electronics\"}"
结论
通过上述步骤,我们实现了根据不同商品类型动态选择处理策略的能力。策略模式使得我们可以灵活地扩展和更改系统的处理逻辑,而不需要修改现有代码。这对于需要支持多种商品类型的电商系统来说是非常有用的。