مشکل اینجاست که در الگوهایی مانند استراتژی و حالت (State) شما باید بر اساس نیازِ کاربر (هر بار) از یکی از پیاده سازی های یک واسط (interface) استفاده کنید؛ بنابراین در config های spring نمی توانید از همان ابتدا مشخص کنید که چه پیاده سازیی مدنظر است.
باید دو کار انجام دهید:
-
دسترسی به bean های تعریف شده با استفاده از واسط BeanFactoryAware (که کلاس Context تان باید آن را پیاده سازی (implements) کند) و کلاس BeanFactory (به عنوان فیلد در داخل کلاس Context تان باید تعریف شود). دقت شود که با پیاده سازی واسط BeanFactoryAware، به طور خودکار، BeanFactory نیز در کلاس Context تان inject می شود.
-
یک Enum برای قرار دادن نوع های مختلف پیاده سازی تعریف کنید که فیلدی به نام beanName (نام bean متناظر با آن پیاده سازی) داشته باشد.
مثال (مرتب سازی آرایه با الگوریتم های مختلف):
تعریف bean های spring ای:
<bean id="sortContext" class="x.y.z.SortContext">
</bean>
<bean id="bubbleSort" class="x.y.z.BubbleSort">
</bean>
<bean id="insertionSort" class="x.y.z.InsertionSort">
</bean>
<bean id="quickSort" class="x.y.z.QuickSort">
</bean>
واسط و کلاس های پیاده سازی کننده آن:
interface SortStrategy
{
void sort(Double[] array, boolean reverse);
}
class BubbleSort implements SortStrategy
{
@Override
public void sort(Double[] array, boolean reverse)
{
// TODO bubble-sort implementation
}
}
class InsertionSort implements SortStrategy
{
@Override
public void sort(Double[] array, boolean reverse)
{
// TODO insertion-sort implementation
}
}
class QuickSort implements SortStrategy
{
@Override
public void sort(Double[] array, boolean reverse)
{
// TODO quick-sort implementation
}
}
تعریف Enum برای bean ها:
enum SortType
{
BUBBLE_SORT("bubbleSort"),
INSERTION_SORT("insertionSort"),
QUICK_SORT("quickSort");
private String beanName;
private SortType(String beanName)
{
this.beanName = beanName;
}
public String getBeanName()
{
return beanName;
}
}
تعریف کلاس Context:
public class SortContext implements BeanFactoryAware
{
private BeanFactory beanFactory;
public void sort(Double[] array, boolean reverse, SortType sortType)
{
SortStrategy sortStrategy = beanFactory.getBean(sortType.getBeanName(),SortStrategy.class);
sortStrategy.sort(array,reverse);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException
{
this.beanFactory = beanFactory;
}
}