2013-07-13 19 views
12

Say Używam sprężynę, mam następujące strategie ...Strategia wzór z ziaren wiosennych

Interfejs

public interface MealStrategy { 
    cook(Meat meat); 
} 

Pierwsza strategia

@Component 
public class BurgerStrategy implements 
MealStrategy { 
    @Autowired CookerDao cookeryDao; 

    @Override 
    public void cook(Meat meat) { 
     cookeryDao.getBurger(meat); 
    } 
} 

Następny strategia ...

@Component 
public class SausageStrategy implements 
MealStrategy { 
    @Autowired CookerDao cookeryDao; 

    @Override 
    public cook(Meat meat) { 
     return cookeryDao.getSausage(meat); 
    } 
} 

Cont ext ...

@Component 
@Scope("prototype") 
public class MealContext { 
    private MealStrategy mealStrategy; 

    public void setMealStrategy(MealStrategy strategy) { 
     this.strategy = strategy; 
    } 

    public void cookMeal(Meat meat) { 
     mealStrategy.cook; 
    } 
} 

teraz powiedzieć to kontekst był dostępny za pośrednictwem kontrolera mvc, jak ...

@Autowired 
private MealContext mealContext; 

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

Jeżeli kontekst być składnikiem? Kiedy to robię, pojawia się błąd informujący, że loadOnStartup istnieje, że istnieje strategia UNIqueBean, że strategia może być, jak można się spodziewać. Czy wszystkie fasole muszą być składnikami jak wyżej lub czy moje adnotacje są nieprawidłowe?

Moje największe pytanie brzmi: czy możesz użyć takiego kontekstu w aplikacji Spring MVC? Problem z używaniem @Scope (prototypu) też oznacza, że ​​wywołania cookeryDao w strategii zwracają zerowy wskaźnik, ponieważ Dao nie są wstrzykiwane.

W jaki sposób zaimplementować powyższy wzór za pomocą sprężyny, a także być bezpieczny dla wątków? Czy to, co próbuję, jest możliwe?

+0

Co to jest dokładnie twój problem? wszystko to działa dla mnie – morgano

+0

Chcę wiedzieć, czy to bezpieczne dla wątku mieć kontekst, jak zrobiłem – david99world

+0

również powyższe nie będzie działać, ponieważ jak zrobiłem "nowe" jest poza kontekstem Spring? – david99world

Odpowiedz

16

Używałbym prostej iniekcji Dependency.

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

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

Controller

Wariant A:

@Resource(name = "burger") 
MealStrategy burger; 

@Resource(name = "sausage") 
MealStrategy sausage; 

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

Wariant B:

@Autowired 
BeanFactory bf; 

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

Możesz tworzyć JSR-330 kwalifikatorów zamiast nazw tekstowych złapać błędy ortograficzne podczas kompilacji czas.

Zobacz także:

How to efficiently implement a strategy pattern with spring?

@Resource vs @Autowired

20

Ponieważ beton strategia jest bardzo często określane w czasie wykonywania na podstawie dostarczonych parametrów lub tak, chciałbym zaproponować coś w następujący sposób.

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

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

Następnie należy wprowadzić wszystkie takie strategie do mapy (z nazwą fasoli jako kluczem) w danym kontrolerze i wybrać odpowiednią strategię na żądanie.

@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); 

    ... 
} 
+1

Ta odpowiedź daje bardziej rzeczywistą implementację wzorca strategii – Cuga

Powiązane problemy