Bootstrap

设计模式——策略模式

设计模式——策略模式


策略模式是设计模式里面比较简单的设计模式,其特点简单又实用,并且可以让你的代码看起来高大上,维护代码时还方便扩张

多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 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
    }
}

以上,我们使用了策略模式分离算法和业务逻辑,将不同产品的处理逻辑分离到不同的策略类中,使代码更清晰、更易于维护

;