2012-02-20 83 views
2

我想使用Strategy Pattern來實現一些定製的格式行爲給第三方類的成員。我希望第三方必須做的不過是註釋類成員,以表明他們是否應該使用格式策略(A,B或C),然後用他們的類的實例調用我的'格式'函數。然後,我的格式函數應該使用註釋來標識需要格式化的成員以及我要使用哪種格式策略。可以使用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 
     } 
    } 
} 

顯然,你會想要做實際的異常處理/錯誤檢查。