2013-07-13 203 views
12

說我使用的是春天,我有以下策略......策略模式

接口

public interface MealStrategy { 
    cook(Meat meat); 
} 

一是戰略

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

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

下一頁戰略...

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

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

Cont轉...

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

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

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

說現在正在通過一個MVC控制器,就像訪問此背景下...

@Autowired 
private MealContext mealContext; 

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

應的背景是組件?當我這樣做時,我得到一個錯誤,說loadOnStartup有一個nonUniqueBean,該策略可能是,如你所料。是否所有的bean都需要像上面那樣的組件,或者我的註釋是不正確的?

我最大的疑問是你可以在Spring MVC應用程序中使用這樣的上下文嗎?我使用@Scope(原型)時遇到的問題是,這意味着cookeryDao調用策略會返回一個空指針,因爲Dao不會被注入。

我將如何使用彈簧實現上述模式並且線程安全?我正在嘗試什麼?

+0

什麼是你的問題?所有這一切對我有用 – morgano

+0

我想知道是否線程安全有一個像我已經完成的上下文 – david99world

+0

上述也不會工作,因爲我已經做了'新'這是在春天的上下文之外? – david99world

回答

16

我會用簡單的依賴注入。

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

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

控制器

選項A:

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

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

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

選項B:

@Autowired 
BeanFactory bf; 

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

您可以選擇創建JSR-330預選賽,而不是文本名稱趕上編譯過程中的拼寫錯誤時間。

參見:

How to efficiently implement a strategy pattern with spring?

@Resource vs @Autowired

20

由於具體的策略是基於所提供的參數左右的運行時間往往很確定,我會如下建議什麼的。

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

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

然後注入所有這樣的策略成在給定的控制裝置的圖(與bean的名稱作爲關鍵字)和請求選擇相應的策略。

@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

這個答案給出了一個更加真實的戰略實施模式 – Cuga