┌─────────────────────────────────────┐ │ <<interface>> │ │ LoadBalancingStrategy │ ← Strategy ├─────────────────────────────────────┤ │ + getInstance(List<Server>): Server │ └─────────────────────────────────────┘ △ │ implements │ ┌──────────────────┬────────────────────┐ │ RandomStrategy │ RoundRobinStrategy │ ← Concrete Strategies ├──────────────────┼────────────────────┤ │+ getInstance() │+ getInstance() │ └──────────────────┴────────────────────┘ ┌────────────────────────────────────────────────┐ │ ServiceDiscovery │ ← Context ├────────────────────────────────────────────────┤ │ - loadBalancingStrategy: LoadBalancingStrategy │ │ + ServiceDiscovery(LoadBalancingStrategy) │ │ + doRequest(List<Server>): void │ └────────────────────────────────────────────────┘ ┌─────────────────────────────┐ │ Server │ ← Domain Object ├─────────────────────────────┤ │ - id: String │ │ + Server(String) │ │ + doRequest(): void │ └─────────────────────────────┘
Strategy Interface
:public interface LoadBalancingStrategy { Server getInstance(final List<Server> servers); }
Concrete Strategies
:public class RandomStrategy implements LoadBalancingStrategy { private final Random random = new Random(); public Server getInstance(final List<Server> servers) { final int index = random.nextInt(servers.size()); return servers.get(index); } }Round Robin Strategy:
public class RoundRobinStrategy implements LoadBalancingStrategy { private final AtomicInteger index = new AtomicInteger(0); public Server getInstance(final List<Server> servers) { final int index = Math.abs(this.index.getAndIncrement()); return servers.get(index % servers.size()); } }
Context
:public class ServiceDiscovery { private final LoadBalancingStrategy loadBalancingStrategy; public ServiceDiscovery(LoadBalancingStrategy loadBalancingStrategy) { this.loadBalancingStrategy = loadBalancingStrategy; } public void doRequest(final List<Server> servers) { loadBalancingStrategy.getInstance(servers).doRequest(); } }
Domain Object
:public class Server { private final String id; public Server(final String id) { this.id = id; } public void doRequest() { System.out.println("Server: " + id); } }
public class StrategyPatternTest { public static void main(String[] args) { // list of available servers final List<Server> servers = new ArrayList<>(); servers.add(new Server("server1")); servers.add(new Server("server2")); servers.add(new Server("server3")); // Service Discovery with different load balancing strategies final ServiceDiscovery serviceDiscovery1 = new ServiceDiscovery(new RoundRobinStrategy()); final ServiceDiscovery serviceDiscovery2 = new ServiceDiscovery(new RandomStrategy()); System.out.println("-- RoundRobin Strategy:"); IntStream.iterate(0, i -> i + 2).limit(6).forEach(i -> serviceDiscovery1.doRequest(servers)); System.out.println("-- Random Strategy:"); IntStream.iterate(0, i -> i + 2).limit(6).forEach(i -> serviceDiscovery2.doRequest(servers)); } }