tutorialspoint template strategy pattern java spring strategy-pattern

java - template - Patrón de estrategia con alubias.



strategy pattern template (2)

Dado que una estrategia concreta se determina muy a menudo en el tiempo de ejecución en función de los parámetros proporcionados, sugeriría algo como sigue.

@Component public class BurgerStrategy implements MealStrategy { ... } @Component public class SausageStrategy implements MealStrategy { ... }

Luego, inyecte todas estas estrategias en un mapa (con el nombre del bean como clave) en el controlador dado y seleccione la estrategia respectiva a petición.

@Autowired Map<String, MealStrategy> mealStrategies = new HashMap<>; @RequestMapping(method=RequestMethod.POST) public @ResponseBody Something makeMeal(@RequestParam(value="mealStrategyId") String mealStrategyId, Meat meat) { mealStrategies.get(mealStrategyId).cook(meat); ... }

Digamos que estoy usando la primavera, tengo las siguientes estrategias ...

Interfaz

public interface MealStrategy { cook(Meat meat); }

Primera estrategia

@Component public class BurgerStrategy implements MealStrategy { @Autowired CookerDao cookeryDao; @Override public void cook(Meat meat) { cookeryDao.getBurger(meat); } }

Siguiente estrategia ...

@Component public class SausageStrategy implements MealStrategy { @Autowired CookerDao cookeryDao; @Override public cook(Meat meat) { return cookeryDao.getSausage(meat); } }

Contexto...

@Component @Scope("prototype") public class MealContext { private MealStrategy mealStrategy; public void setMealStrategy(MealStrategy strategy) { this.strategy = strategy; } public void cookMeal(Meat meat) { mealStrategy.cook; } }

Ahora digamos que se estaba accediendo a este contexto a través de un controlador mvc, como ...

@Autowired private MealContext mealContext; @RequestMapping(method = RequestMethod.POST) public @ResponseBody Something makeMeal(Meat meat) { mealContext.setMealStrategy(new BurgerStrategy()) mealContext.cookMeal(meat); }

¿Debería el contexto ser un componente? Cuando lo hago, aparece un error que dice loadOnStartup y hay un nonBean que puede ser la estrategia, como es de esperar. ¿Todos los beans deben ser componentes como arriba o mis anotaciones son incorrectas?

Mi mayor consulta es si puedes usar un contexto como ese en una aplicación Spring MVC. El problema que tengo con el uso de @Scope (prototipo) también es que las llamadas a cookeryDao en las estrategias devuelven un puntero nulo ya que los Dao no se inyectan.

¿Cómo implementaría el patrón anterior usando el resorte y también sería seguro para los hilos? ¿Es lo que estoy intentando incluso posible?


Yo usaría inyección de dependencia simple.

@Component("burger") public class BurgerStrategy implements MealStrategy { ... } @Component("sausage") public class SausageStrategy implements MealStrategy { ... }

Controlador

Opción A:

@Resource(name = "burger") MealStrategy burger; @Resource(name = "sausage") MealStrategy sausage; @RequestMapping(method = RequestMethod.POST) public @ResponseBody Something makeMeal(Meat meat) { burger.cookMeal(meat); }

Opción B:

@Autowired BeanFactory bf; @RequestMapping(method = RequestMethod.POST) public @ResponseBody Something makeMeal(Meat meat) { bf.getBean("burger", MealStrategy.class).cookMeal(meat); }

Puede elegir crear calificadores JSR-330 en lugar de nombres textuales para detectar errores ortográficos durante el tiempo de compilación.

Ver también:

¿Cómo implementar eficientemente un patrón de estrategia con spring?

@Resource vs @Autowired