Sobes.tech
Назад к вопросам
Senior
4

Как реализовать паттерн Strategy для динамического выбора сервиса по типу сущности в Spring (задача на код)?

Компании, где спрашивали
СБЕРСБЕР

Ответ от нейросети

sobes.tech AI

В Spring паттерн Strategy можно реализовать через интерфейс и набор бинов, каждый из которых отвечает за обработку определённого типа сущности. Для динамического выбора сервиса по типу сущности удобно использовать Map с ключом — типом, а значением — реализацией.

Пример:

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 -> {
                    // Предполагается, что supports возвращает true только для одного типа
                    // Можно добавить метод getType() для более чистой реализации
                    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());
    }
}

// Использование
@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);
    }
}

Такой подход позволяет легко добавлять новые стратегии, просто создавая новые реализации интерфейса и регистрируя их как Spring-бины.