Sobes.tech
Senior

How to implement the Strategy pattern for dynamically selecting a service based on entity type in Spring (coding task)?

sobes.tech AI

Answer from AI

In Spring, the Strategy pattern can be implemented through an interface and a set of beans, each responsible for handling a specific type of entity. For dynamic selection of a service based on the entity type, it is convenient to use a Map with the key as the type and the value as the implementation.

Example:

public interface EntityService {
    boolean supports(String entityType);
    void process();
}

@Service
public class UserService implements EntityService {
    @Override
    public boolean supports(String entityType) {
        return "USER".equalsIgnoreCase(entityType);
    }

    @Override
    public void process() {
        System.out.println("Processing user entity");
    }
}

@Service
public class OrderService implements EntityService {
    @Override
    public boolean supports(String entityType) {
        return "ORDER".equalsIgnoreCase(entityType);
    }

    @Override
    public void process() {
        System.out.println("Processing order entity");
    }
}

@Component
public class EntityServiceFactory {
    private final Map<String, EntityService> serviceMap;

    public EntityServiceFactory(List<EntityService> services) {
        serviceMap = services.stream()
            .collect(Collectors.toMap(
                s -> {
                    // It is assumed that supports returns true only for one type
                    // You can add a getType() method for a cleaner implementation
                    if (s.supports("USER")) return "USER";
                    if (s.supports("ORDER")) return "ORDER";
                    return "UNKNOWN";
                },
                Function.identity()));
    }

    public EntityService getService(String entityType) {
        return serviceMap.get(entityType.toUpperCase());
    }
}

// Usage
@Autowired
private EntityServiceFactory factory;

public void handleEntity(String entityType) {
    EntityService service = factory.getService(entityType);
    if (service != null) {
        service.process();
    } else {
        throw new IllegalArgumentException("Unsupported entity type: " + entityType);
    }
}

This approach makes it easy to add new strategies by simply creating new interface implementations and registering them as Spring beans.