设计模式(行为型模式)策略模式

一、简介

  策略模式(Strategy Pattern)是一种行为设计模式,它允许定义一系列算法,将每个算法封装到独立的类中,并使它们可以相互替换。这使得算法可以独立于使用它们的客户端进行变化。

  在策略模式中,算法被视为一个策略。这些策略被封装到各自的类中,并通过接口或抽象类暴露统一的方法,使得这些策略可以相互替换。然后,客户端可以根据需要选择使用的策略。

  这种模式使得算法可以独立于其使用者变化。它使得代码更加灵活、可扩展,并且更易于维护,因为新的算法可以在不修改现有客户端代码的情况下添加。

总之,策略模式允许定义一系列算法并使它们可以相互替换,从而提供了更大的灵活性和可扩展性。

二、策略模式

  Nginx 支持多种负载均衡策略,你可以根据需要选择适合你应用场景的策略,那些嵌套的ifelse我就不去写了。接下里我们简单演示使用策略模式来选择不同的负载均衡策略。

2.1、负载均衡接口

  定义一个策略接口

// 负载均衡策略
public interface LoadBalancingStrategy {

    String chooseServer(List<String> servers);
}

2.2、轮询策略

// 轮询策略
public class RoundRobinStrategy implements LoadBalancingStrategy {
    private int currentIndex;

    public RoundRobinStrategy() {
        this.currentIndex = 0;
    }

    @Override
    public String chooseServer(List<String> servers) {
        String selectedServer = servers.get(currentIndex);
        currentIndex = (currentIndex + 1) % servers.size();
        return selectedServer;
    }
}

2.3、随机策略

// 随机策略
public class RandomStrategy implements LoadBalancingStrategy {
    private Random random;

    public RandomStrategy() {
        this.random = new Random();
    }

    @Override
    public String chooseServer(List<String> servers) {
        int randomIndex = random.nextInt(servers.size());
        return servers.get(randomIndex);
    }
}

2.4、Hash策略

// hash策略
public class HashStrategy implements LoadBalancingStrategy {

    public HashStrategy() {
    }

    @Override
    public String chooseServer(List<String> servers) {
        // 在实际应用中,这里可以根据客户端信息计算哈希值
        // 这里简化演示,假设使用客户端信息的哈希码模拟
        int hashCode = Math.abs(ThreadLocalRandom.current().nextInt());
        int index = hashCode % servers.size();
        return servers.get(index);
    }
}

2.5、策略工厂

  策略工厂在这里是可以避免重复创建对象,节省内存,实际你可以根据需求进行相应处理。

public class StrategyFactory {

    private static final Map<String, LoadBalancingStrategy> STRATEGY_MAP = new HashMap<>();

    static {
        STRATEGY_MAP.put("Round", new RoundRobinStrategy());
        STRATEGY_MAP.put("Random", new RandomStrategy());
        STRATEGY_MAP.put("Hash", new HashStrategy());
    }

    public static LoadBalancingStrategy getStrategy(String type) {
        // 获取策略
        if (STRATEGY_MAP.containsKey(type)) {
            return STRATEGY_MAP.get(type);
        }
        return null;
    }
}

2.6、使用

  演示如果调用不同的策略

import java.util.Arrays;
import java.util.List;

public class StrategyPatternExample {

    public static void main(String[] args) {
        List<String> servers = Arrays.asList("订单服务1", "订单服务2", "订单服务3");

        LoadBalancingStrategy strategy = StrategyFactory.getStrategy("Round");
        String selectedServerRoundRobin = strategy.chooseServer(servers);
        System.out.println("轮询策略调用的服务: " + selectedServerRoundRobin);

        LoadBalancingStrategy randomStrategy = StrategyFactory.getStrategy("Random");
        String selectedServerRandom = randomStrategy.chooseServer(servers);
        System.out.println("随机策略调用的服务: " + selectedServerRandom);

        LoadBalancingStrategy hashStrategy = StrategyFactory.getStrategy("Hash");
        String selectedServerHash = hashStrategy.chooseServer(servers);
        System.out.println("Hash模式调用的服务: " + selectedServerHash);
    }
}

运行结果:

轮询策略调用的服务: 订单服务1
随机策略调用的服务: 订单服务3
Hash模式调用的服务: 订单服务3

轮询策略调用的服务: 订单服务1
随机策略调用的服务: 订单服务3
Hash模式调用的服务: 订单服务2

三、优点与缺点

  策略模式的优点和缺点如下:

优点

  • 灵活性和可扩展性: 策略模式允许在运行时选择算法,使得算法可以相互替换,从而提供了更大的灵活性和可扩展性。
  • 避免条件语句: 策略模式可以减少条件语句的使用,因为每个算法都被封装在单独的类中,使得客户端代码更简洁、可读性更高。
  • 单一职责原则: 每个策略类都包含一个独立的算法,符合单一职责原则,使得代码更易于理解和维护。
  • 代码复用: 策略模式可以促进代码的重用,因为相似的算法可以被不同的对象使用。

缺点

  • 类数量增加: 策略模式可能会增加类的数量,因为每个策略通常需要一个单独的类,可能导致类的数量增加,使得代码复杂化。
  • 客户端必须了解所有策略: 客户端需要了解所有的策略类,并在运行时选择合适的策略,可能会增加理解和维护的难度。
  • 策略的选择: 如果没有清晰的判断标准或者策略选择逻辑较为复杂,可能会增加使用该模式的复杂度。
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值