[英]How to get a list of all implemented classes in Strategy Pattern?
我想設計一個允許用戶從文件類型列表中選擇以保存文件的系統。 我有一個名為Word的類,以及一個名為SaveFileType的接口。 每個文件類型都實現了SaveFileType,它具有saveFile()方法。 我們的想法是,當“程序員”想要添加新的文件類型時,不必更改應用程序中的任何代碼。
我面臨的問題是Word類沒有我需要向用戶顯示的所有可用文件類型的列表。
下面的一些示例代碼:
詞類:
public class Word {
SaveFileAs saveFileAs;
Document currentDocument;
public Word(Document currentDocument) {
this.currentDocument = currentDocument;
}
public void saveFile() {
// Print all available filetypes
// No actual file-saving logic is needed.
}
}
Word97類:
public class Word97 implements SaveFileAs {
@Override
public void saveFile(Document currentDocument) {
// Do some Java wizardry here.
System.out.println("Document named '" + currentDocument.getTitle() + "' has been saved as filetype 'Word97' " );
}
}
主要課程:
public class Main {
public static void main(String[] args) {
Document notes = new Document("Notes", "This is a note.");
Word wordProgram = new Word(notes);
// saveFile should print out a list of all possible filetypes.
wordProgram.saveFile();
}
}
如果Word
類知道所有類型,那將是不好的。 即使單詞使用它,它也是另一個類的工作。 一種解決方案是創建一個將字符串擴展名映射到策略的新類。 並且可以列舉這些策略:
public final class DocumentTypeMap implements Iterable<SaveFileAs> {
private final Map<String, SaveFileAs> docTypes = new HashMap<>;
public void register(String extension, SaveFileAs saveFileAs) {
docTypes.put(extension, saveFileAs);
}
public Iterator<SaveFileAs> iterator() {
return docTypes.values().iterator();
}
}
用法:
DocumentTypeMap map = new DocumentTypeMap();
map.register(".doc", new Word97()); //etc.
Word word = new Word(map); //inject the dependency of a pre-configured map into the word class.
然后,當Word
類在保存期間需要正確的策略時,它可以使用DocumentTypeMap
上的方法(此處未提供)來獲取正確的策略。 我想這可能是延伸的。
策略是在運行時更改實現,您無法獲得所有實現。 這將是另一個班級的任務。 你還需要在Word
類中以某種方式使用setStrategy(Strategy)
這樣的方法,這就是為什么你選擇了正確的模式?
要獲得所有實現,您可以使用ServiceLoader
。 我想在圖片中添加一個枚舉。
所以示例代碼如下所示:
Word
類中的方法:
void setSaveFileStrategy(AvailableStrategy strategy){
this.saveFileAs = strategy.strategy();
}
枚舉:
enum AvailableStrategy{
Word97( Word97.class),
//.... once new strategy was introduced, you need add an entry here.
WordXml( WordXml.class);
private Class<saveFileAs> strategyClass;
AvailableStrategies(Class<saveFileAs> strategyClass) {
this.strategyClass = strategyClass;
}
saveFileAs strategy() throws IllegalAccessException, InstantiationException {
return strategyClass.newInstance() ;
}
}
我想你知道如何獲得所有枚舉實例(可用的策略)。
請注意,代碼未經過編譯和測試,僅用於顯示想法。 異常處理被忽略了。
如果您希望能夠在不更改任何代碼的情況下添加文檔類型,則意味着必須在代碼之外定義文檔類型列表,在文件中定義屬性文件,並且您的代碼必須讀取屬性文件以了解所有可用文件類型。
然后,您需要在此屬性文件中添加哪個類實現如何保存特定文檔類型,並實現一個實例化給定其名稱的類的工廠,以及根據所選類型關聯右實例的類。
對於屬性文件,您可以使用以下條目:
ext_1 = .DOC
ext_2 = .XML
ext_3 = .RTF
class_1 = Word97的
class_2 = WordXML
class_3 = RTF ......
這樣的文件很容易解析,以便知道類型列表以及必須使用哪個類來保存文檔。 要了解如何從其名稱實例化類,請參閱類Class
和方法newInstance
。
這是一種“老方式”,也許注射是最新的解決方案。
在你的UML模型中,我將添加讀取屬性文件的類,從其名稱實例化類的類,以及將右實例與Word相關聯的類。 要對屬性文件建模,可能會使用實例objet,因為屬性文件是ResourceBundle的一個實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.