策略模式是设计模式里面比较简单的设计模式,其特点简单又实用,并且可以让你的代码看起来高大上,维护代码时还方便扩张
多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if…else 语句、switch…case 语句
简单介绍
策略模式(Strategy Pattern)是一种行为设计模式,它在运行时选择算法或行为。它定义了一系列的算法,并将每个算法封装起来,使它们可以相互替换。这样,算法的变化可以独立于使用算法的客户,这么说会有些抽象,下面会举个例子的
主要组成部分:
1,策略接口(Strategy Interface):定义了所有支持的算法的公共操作
2,具体策略类(Concrete Strategy Classes):实现了策略接口,提供了具体的算法实现
3,上下文(Context):持有一个策略对象的引用。使用策略对象来执行特定的算法
一个例子
我们举个例子来说明策略模式的必要性,现在有一个需求:我们需要做一个旅游平台,现在需要提供机票、火车票、酒店、门票等产品的下单、查询、退款接口,因为这些产品的行为都是类似的,所以我们不打算为他们分别提供接口,而是收口到一个 contrllor 中,我们先来看看使用 if else 去处理,会发生什么:
public class TravelService {
@Resource
private FlightOrderService flightOrderService;
@Resource
private TrainOrderService trainOrderService;
@Resource
private HotelOrdeService hotelOrdeService;
@Resource
private TicketOrdeService ticketOrdeService;
public String placeOrder(String productType, Order order) {
if ("flight".equals(productType)) {
return flightOrderService.processFlightOrder(order);
} else if ("train".equals(productType)) {
return trainOrderService.processTrainOrder(order);
} else if ("hotel".equals(productType)) {
return hotelOrdeService.processHotelOrder(order);
} else if ("ticket".equals(productType)) {
return ticketOrdeService.processTicketOrder(order);
} else {
return "Unsupported product type";
}
}
public String queryOrder(String productType, String orderId) {
if ("flight".equals(productType)) {
return flightOrderService.queryFlightOrder(orderId);
} else if ("train".equals(productType)) {
return trainOrderService.queryTrainOrder(orderId);
} else if ("hotel".equals(productType)) {
return hotelOrdeService.queryHotelOrder(orderId);
} else if ("ticket".equals(productType)) {
return ticketOrdeService.queryTicketOrder(orderId);
} else {
return "Unsupported product type";
}
}
public String refundOrder(String productType, String orderId) {
if ("flight".equals(productType)) {
return flightOrderService.refundFlightOrder(orderId);
} else if ("train".equals(productType)) {
return trainOrderService.refundTrainOrder(orderId);
} else if ("hotel".equals(productType)) {
return hotelOrdeService.refundHotelOrder(orderId);
} else if ("ticket".equals(productType)) {
return ticketOrdeService.refundTicketOrder(orderId);
} else {
return "Unsupported product type";
}
}
}
可以看到上面代码有如下问题:
1,扩展性有限:如果我想要再引入动物园票啥的业务,我需要再额外写 else if(这里举的例子比较简单,改动起来比较简单,但是在实际的工程中,需要改动的地方太多了)
2,过多的 if else,会导致代码的甬余
改用策略模式后,我们再看看:
先提供一个抽象的策略接口,定义订单行为:
public interface OrderStrategy {
String placeOrder(Order order);
String queryOrder(String orderId);
String refundOrder(String orderId);
}
写四个类实现订单接口:
public class FlightOrderStrategy implements OrderStrategy {
@Override
public String placeOrder(Order order) {
return "Flight order processed: " + order;
}
@Override
public String queryOrder(String orderId) {
return "Flight order queried: " + orderId;
}
@Override
public String refundOrder(String orderId) {
return "Flight order refunded: " + orderId;
}
}
public class TrainOrderStrategy implements OrderStrategy {
@Override
public String placeOrder(Order order) {
return "Train order processed: " + order;
}
@Override
public String queryOrder(String orderId) {
return "Train order queried: " + orderId;
}
@Override
public String refundOrder(String orderId) {
return "Train order refunded: " + orderId;
}
}
public class HotelOrderStrategy implements OrderStrategy {
@Override
public String placeOrder(Order order) {
return "Hotel order processed: " + order;
}
@Override
public String queryOrder(String orderId) {
return "Hotel order queried: " + orderId;
}
@Override
public String refundOrder(String orderId) {
return "Hotel order refunded: " + orderId;
}
}
public class TicketOrderStrategy implements OrderStrategy {
@Override
public String placeOrder(Order order) {
return "Ticket order processed: " + order;
}
@Override
public String queryOrder(String orderId) {
return "Ticket order queried: " + orderId;
}
@Override
public String refundOrder(String orderId) {
return "Ticket order refunded: " + orderId;
}
}
上下文类:
public class TravelService {
private OrderStrategy strategy;
public TravelController(OrderStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(OrderStrategy strategy) {
this.strategy = strategy;
}
public String placeOrder(Order order) {
return strategy.placeOrder(order);
}
public String queryOrder(String orderId) {
return strategy.queryOrder(orderId);
}
public String refundOrder(String orderId) {
return strategy.refundOrder(orderId);
}
}
客户端代码
public class Client {
public static void main(String[] args) {
TravelController controller = new TravelController(new FlightOrderStrategy());
Order order = new Order("12345", "Flight to Paris");
System.out.println(controller.placeOrder(order)); // 输出: Flight order processed: Order{id='12345', description='Flight to Paris'}
System.out.println(controller.queryOrder("12345")); // 输出: Flight order queried: 12345
System.out.println(controller.refundOrder("12345")); // 输出: Flight order refunded: 12345
// 动态更换策略
controller.setStrategy(new HotelOrderStrategy());
Order hotelOrder = new Order("67890", "Hotel in New York");
System.out.println(controller.placeOrder(hotelOrder)); // 输出: Hotel order processed: Order{id='67890', description='Hotel in New York'}
System.out.println(controller.queryOrder("67890")); // 输出: Hotel order queried: 67890
System.out.println(controller.refundOrder("67890")); // 输出: Hotel order refunded: 67890
}
}
以上,我们使用了策略模式分离算法和业务逻辑,将不同产品的处理逻辑分离到不同的策略类中,使代码更清晰、更易于维护