2013-07-13 5 views
12

は、私は次のような戦略を持って、私は春を使用していると言う...Strategyパターン

インタフェース

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 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; 
    } 
} 

は今、コンテキストがコンポーネントであるべき...のように、このような状況は、MVCコントローラを介してアクセスされていた

@Autowired 
private MealContext mealContext; 

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

を言うの?私がするときは、loadOnStartupというエラーが出ます。それは、あなたが期待していたように、戦略が可能なnonUniqueBeanです。すべての豆は上記のようなコンポーネントである必要がありますか、または私の注釈が間違っていますか?

私の最大の質問は、本当にSpring MVCアプリケーションのようなコンテキストを使用できますか?私が@Scope(プロトタイプ)を使用している問題は、Daoが注入されないので、戦略のcookeryDaoコールがnullポインタを返すことを意味します。

私は春を使用して上記のパターンを実装し、スレッドセーフでもありますか?私は何をしようとしていますか?

+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

関連する問題