中心思想是:模塊間去耦合。 java
舉例說明: spring
隨機顯示一個通過擾亂處理的不規則單詞,而用戶則要將擾亂後的單詞糾正爲正確的單詞。其中,一個類用來生成原始單詞,一個業務邏輯層用來擾亂單詞,還有一個用戶界面模塊負責將這個單詞展現給用戶看。定義接口以下: api
public interface Scrambler { public String scramble(String word); }
public interface WordLibrary { public String[] getWords(); }
public interface UI { public void display(); }實現:
public abstract class Anagrams extends javax.swing.JFrame implements UI { protected abstract WordLibrary getWordLibrary(); protected abstract Scrambler getScrambler(); public void display() { initWord(); setVisible(true); } }
public final class Launcher { private static Class<? extends WordLibrary> wordLibrary; private static Class<? extends Scrambler> scrambler; private static Class<? extends UI> ui; private Launcher() { } public static void registerWordLibrary(Class<? extends WordLibrary> libraryClass) { wordLibrary = libraryClass; } public static void registerScrambler(Class<? extends Scrambler> scramblerClass) { scrambler = scramblerClass; } public static void registerUI(Class<? extends UI> uiClass) { ui = uiClass; } public static UI launch() throws Exception { WordLibrary w = wordLibrary.newInstance(); Scrambler s = scrambler.newInstance(); return ui.getConstructor(WordLibrary.class, Scrambler.class).newInstance(w, s); } }
public class AnagramsWithConstructor extends Anagrams { private final WordLibrary library; private final Scrambler scrambler; public AnagramsWithConstructor(WordLibrary library, Scrambler scrambler) { this.library = library; this.scrambler = scrambler; } @Override protected WordLibrary getWordLibrary() { return library; } @Override protected Scrambler getScrambler() { return scrambler; } }
以上代碼註冊方式效率很是慢,特別是在要註冊的模塊很是多的狀況,都須要在系統啓動時就註冊,註冊多個模塊,就會進行不少模塊的編譯鏈接,效率很是慢。 ide
註冊的通用作法: ui
不少註冊代碼都是相同的,須要將其提取出來: this
private static Map<Class<?>,Object[]> instances = new LinkedHashMap<Class<?>,Object[]>(); public static void registerClass(Class<?> impl) { instances.put(impl, new Object[1]); } public static <T> T find(Class<T> whatType) { for (Map.Entry<Class<?>, Object[]> entry : instances.entrySet()) { if (whatType.isAssignableFrom(entry.getKey())) { if (entry.getValue()[0] == null) { try { entry.getValue()[0] = entry.getKey().newInstance(); } catch (Exception ex) { throw new IllegalStateException(ex); } } return whatType.cast(entry.getValue()[0]); } } return null; }
@Override protected WordLibrary getWordLibrary() { try { if (wordLibrary == null) { String implName=System.getProperty("org.apidesign.anagram.api.WordLibrary"); assert implName != null; Class<?> impl = Class.forName(implName); wordLibrary = (WordLibrary)impl.newInstance(); } return wordLibrary; } catch (Exception ex) { throw new IllegalStateException(ex); } }
@Override protected Scrambler getScrambler() { try { if (scrambler == null) { String implName = System.getProperty("org.apidesign.anagram.api.Scrambler"); assert implName != null; Class<?> impl = Class.forName(implName); scrambler = (Scrambler)impl.newInstance(); } return scrambler; } catch (Exception ex) { throw new IllegalStateException(ex); } }
配置文件有用XML的,好比Spring的配置文件: code
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" > <bean id="wordLibrary" class="org.apidesign.anagram.wordstatic.StaticWordLibrary" /> <bean id="scrambler" class="org.apidesign.anagram.scramblersimple.SimpleScrambler" /> <bean id="ui" class="org.apidesign.anagram.gui.AnagramsWithConstructor" autowire="autodetect" /> </beans>