2015-01-26 3 views
3

Допустим, мы вынуждены извлекать данные по классу: Торговля. Этот торговый класс имеет множество параметров, таких как A, B, C ....Какой шаблон дизайна применять

class A { retrieveTradeDataWithA(); and many more methods which do something } 

class B { retrieveTradeDataWithB(); and many more methods which do something } 

class LetsSaySomeResource { 

    @Inject 
    private A classAInstance; 
    @Inject 
    private B classBInstance; 

    public void getTradeDataBasedOnA(){ 
    classAInstance.retrieveTradeDataWithA(); 
    } 
    public void getTradeDataBasedOnB(){ 
    classBInstance.retrieveTradeDataWithB(); 
    } 
} 

Теперь требование мы хотим загрузить некоторые данные о торговле на основе A и B, так и в дальнейшем, возможно, больше классов, как A и B будут добавлены для получения данных на основе этого. Как сделать дизайн более гибким?

Мол,

public void getDataBasedOnAandB(){ 
} 

Или позже класса C может прийти, поэтому я не хочу, чтобы держать инъекционные фильтры, как A, B .... Может кто-нибудь помочь в этом?

+0

привет, я отредактировал свое требование, чтобы быть немного более ясным, надеюсь, что это может помочь мне дать мне идею – bhupen

+0

Я подозреваю, что что-то подобное может вам помочь - http://coders-kitchen.com/2013/01/24/ jee-and-dynamic-dependency-injection/ –

ответ

4

Сначала нужно создать интерфейс, который будет определять контракт на что-то делать:

public interface IData { 
    void doSomething(); 
} 

Затем создать конкретные реализации, чтобы сделать что-то:

public class DataA implements IData { 

    @Override 
    public void doSomething() { 
     // TODO Do something for A 

    } 

} 

public class DataB implements IData { 

    @Override 
    public void doSomething() { 
     // TODO Do something for B 
    } 

} 

И, наконец, класс, который будет на самом деле что-то сделать:

public class DataDAO { 
    private List<IData> dataList; 

    public DataDAO(List<IData> dataList) { 
     this.dataList = dataList; 
    } 

    public void doSomething() { 
     for(IData data : dataList) { 
      data.doSomething(); 
     } 
    } 
} 

Теперь давайте рассмотрим ваши варианты использования:

сделать что-то для A:

List<IData> dataAList = new ArrayList<IData>(); 
dataList.add(new DataA()); 
DataDAO dataADAO = new DataDAO(dataAList); 
dataADAO.doSomething(); 

сделать что-то для A и B:

List<IData> dataAList = new ArrayList<IData>(); 
dataList.add(new DataA()); 
dataList.add(new DataB()); 
DataDAO dataADAO = new DataDAO(dataAList); 
dataADAO.doSomething(); 
+0

Привет, я думаю, что это не может решить проблему для параметров AandB, если я хочу фильтровать вместе. Я отредактировал свое требование, чтобы быть немного более ясным, надеюсь, что это может помочь мне дать некоторую идею. – bhupen

+0

С приведенным выше решением вам не нужно продолжать вводить фильтры. Вам просто нужно создать список конкретной реализации IData, как я уже показал в последнем абзаце моего ответа. – CKing

1

Это может выглядеть примерно так:

class LetsSaySomeResource { 
    @Resource 
    private Map<String, DataAccessInterface> instanceToDataAccessMapping; 

    public DateAggregationResult getDataFor(String... instanceNames) { 
     DataAggregationResult result = new DataAggregationResult(); // some list or whatever 
     for (String instanceName : instanceNames) { 
      Data data = instanceToDataAccessMapping.get(instanceName).getData(); 
      /** 
      * Add this data to aggregation result here 
      */ 
     } 
     return result; 
    } 
} 
+0

какой о doSomthingForAandB? Ваш ответ может касаться только doSomethingForA или doSomthingForB, но не обоих. См. Мой ответ. – CKing

+0

Вы можете разрешить передачу нескольких методов instanceNames в Resource и агрегировать результат перед возвратом фактических данных. Здесь я не вижу никаких проблем. – SimY4

+0

Да, но getDataFor является одномерным. Что я имею в виду, так это то, что он может работать только на instanceName за раз, поэтому неважно, сколько записей будет на карте. Вызывающему нужно будет вызвать этот метод getDataFor несколько раз, который делает карту бессмысленной. Теперь, если вы собираетесь перебирать карту в методе getDataFor, это имеет смысл. Но опять же, зачем использовать карту, когда вы можете использовать список? – CKing

0

Попробуйте что-то вроде decorator pattern. Если ваши классы будут расти со временем, всегда основываясь на предыдущих требованиях, вы можете добавить дополнительные вычисления, украсив их.

Ваш пример по-прежнему очень абстрактный, поэтому трудно определить, являются ли ваши дополнительные классы взаимозависимыми или просто «расширенными» (простое наследование будет выполнено).

Или полностью отсоединенный, поэтому что-то вроде SimY4 могло бы помочь (используйте, например, вариант visitor pattern).

+0

Использование списка исключает необходимость использования шаблона декоратора. – CKing

0

Я думаю, шаблон шаблона дизайна был бы полезен здесь. http://en.wikipedia.org/wiki/Template_method_pattern

Вы можете определить свой шаблонный метод в базовом классе и позволить подклассам, реализующему этот класс, определить свой собственный алгоритм для этого. Прочитайте ссылку на wiki, и вы найдете свой выход.

Смежные вопросы