2012-02-20 12 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

これはアノテーションを使用して行うことができます。これは、あなたが提案した方法とまったく同じです。あなたは、実際の例外処理を行うことになるでしょう、明らかに

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

:ここ

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

} 

が実際に戦略を使用するコードのようになります。これは、サンプル実装だろう、それはまた、 AbstractFactoryパターンを使用しています/エラーチェック。

関連する問題