2012-02-20 3 views
2

Я хочу использовать Strategy Pattern, чтобы реализовать какое-то индивидуальное поведение форматирования для участников в сторонних классах. Я хочу, чтобы третья сторона должна была сделать не более чем аннотацию членов класса, чтобы указать, следует ли им использовать стратегию форматирования (A, B или C), а затем вызвать функцию «format» с экземпляром своего класса. Затем моя функция формата должна использовать аннотации, чтобы идентифицировать членов, требующих форматирования, и какие из моих стратегий формата использовать.Можно ли реализовать «Стратегический шаблон» с помощью аннотаций Java?

public class ThirdPartyClass 
{ 
    @FormatStrategy(fmt=unsigned8,offset=0) 
    int memberA; 

    @FormatStrategy(fmt=unsigned16,offset=1) 
    int memberB; 

    @FormatStrategy(fmt=unsigned16,offset=3) 
    int memberB; 
} 

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

С уважением

ответ

1

Я предполагаю, что вы обработку этого класса с отражением, как вы понятия не имеете, какие поля они собираются объявили?

т.е. вы будете иметь что-то вроде:

for (Field f : inputInstance.getClass().getDeclaredFields()) { 
    FormatStrategy fs = f.getAnnotation(FormatStrategy.class); 
    getImplementationOf(fs).run(); 
} 

Какая часть Вас беспокоит больше всего? Реализация метода getImplementationOf()? Это был бы стандартный «заводский» метод для стратегий? Как вы заметили, нет возможности напрямую кодировать логику в самой аннотации.

3

Я считаю, что это можно сделать с аннотациями, точно так, как вы это предложили. Это будет пример реализации, он также использует AbstractFactory шаблон:

class ThirdPartyClass { 
    @FormatStrategy(fmt="unsigned8",offset=0) 
    int memberA; 

    @FormatStrategy(fmt="unsigned16",offset=1) 
    int memberB; 

    @FormatStrategy(fmt="unsigned16",offset=3) 
    int memberC; 
} 

@Target(ElementType.FIELD) 
@Retention(RetentionPolicy.RUNTIME) 
@interface FormatStrategy{ 
    String fmt() default "unsigned8"; 
    int offset()default 0; 
} 

interface FormattingStrategy{ 
    String formatNumber(int number); 
} 

class BasicFormattingStrategy implements FormattingStrategy{ 
    private String fmt; 
    private int offset; 

    private BasicFormattingStrategy(String fmt, int offset) { 
     this.fmt = fmt; 
     this.offset = offset; 
    } 

    @Override 
    public String formatNumber(int number) { 
     // do formatting here 
     return "formatted number"; 
    } 

} 

interface StrategyFactory{ 
    FormattingStrategy getStrategy(FormatStrategy fmtStrategy); 
} 

class DefaultStrategyFactory implements StrategyFactory{ 

    @Override 
    public FormattingStrategy getStrategy(FormatStrategy fmtStrategy) { 
     // right now only one strategy implementation exists, but may have many. 
     return new BasicFormattingStrategy(fmtStrategy.fmt(), fmtStrategy.offset()); 
    } 

} 

Здесь будет код, который на самом деле использует стратегию:

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException{ 
    StrategyFactory factory = new DefaultStrategyFactory(); 
    ThirdPartyClass obj = new ThirdPartyClass(); 
    Class<ThirdPartyClass> clazz = (Class<ThirdPartyClass>) obj.getClass(); 
    for(Field field : clazz.getDeclaredFields()){ 
     FormatStrategy fmtStrategy = field.getAnnotation(FormatStrategy.class); 
     if(fmtStrategy != null){ 
      FormattingStrategy strategy = factory.getStrategy(fmtStrategy); 
      String formattedNumber = strategy.formatNumber(field.getInt(obj)); 
      // use the formatted number 
     } 
    } 
} 

Очевидно, что вы хотите сделать фактическую обработку исключений/проверка ошибок.

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