2012-12-22 46 views
2

我目前正在爲學校開展一個小項目。在我的Java應用程序中,我需要一個數據庫,並且我想讓我的應用程序能夠使用不同類型的數據庫。所以我目前實現了一個txt數據庫和一個PostgreSQL。將來,應該可以添加其他數據庫類型。像XML或MySQL,...更靈活的工廠

要創建一個數據庫實例,我設計了一個使用枚舉的工廠。它完美的工作,但它不真正在我的opionio靈活。所以,我做了一些研究,但沒有找到一個很好的例子,這對我來說很清楚。

這是我的枚舉:

public enum DatabaseType { 
    TXT, 
    SQL, 
    XML; 
} 

這是我廠:

public class DatabaseFactory {  

    public Database createDatabase(DatabaseType type, String databaseName) throws DatabaseException { 
     if(type.equals(DatabaseType.TXT)) { 
      return new FileDatabase(databaseName); 
     }else if(type.equals(DatabaseType.SQL)) { 
      return new SQLDatabase(databaseName); 
     }else if(type.equals(DatabaseType.XML)) { 
      return new XMLDatabase(databaseName); 
     }else { 
      //default 
      return new FileDatabase(databaseName); 
     } 
    } 
} 

我的目標是隻有編輯在今後的枚舉,而不觸及工廠本身。這應該給我足夠的靈活性,但我不知道我該如何做到這一點。

+3

一種選擇是將其放入枚舉本身。 –

+0

@DaveNewton,我想你仍然需要一個if-else-if或switch-case結構呢? –

+0

例如,請參閱Mattias的答案,或將枚舉映射到簡單的工廠(如果您需要額外的邏輯,則很好)等。您可以*使用if語句。 –

回答

1

使用反射:

您的枚舉:

public enum DatabaseType { 
    FILE(FileDatabase.class), 
    SQL(SQLDatabase.class); 

    private Database db; 

    DatabaseType(Class<Database> db) { 
     this.db = db; 
    } 

    /*package friendly*/ Class<Database> getDatabase() { 
     return this.db; 
    } 
} 

你的工廠:

public class DatabaseFactory { 

    public static Database create(DatabaseType type, String dbName) throws Exception { 
     Database db = null; 
     Constructor cons = type.getDatabase().getDeclaredConstructor(new Class[] { String.class }); 
     cons.setAccessible(true); 
     db = cons.newInstance(dbName); 

     return db; 
    } 

} 

您的數據庫實現者:

public class FileDatabase extends Database { 

    /* can only be instantiated via reflection */ 
    private FileDatabase(String databaseName) { 
     // init db. 
    } 
} 
+0

好的,但我仍然不明白你將如何得到一個數據庫的實例? (我已經有一個接口,實際上是一個抽象類)。 –

+1

你可以使用反射。 – asgoth

+0

我已經添加了一個使用反射的例子。請注意,這是未經測試的代碼。 – asgoth

3

你可以把工廠放在enum本身。

public enum DatabaseType { 
    TXT { 
     @Override 
     public Database createDatabase(String databaseName) { 
      return new FileDatabase(databaseName); 
     } 
    }, 
    SQL { 
     @Override 
     public Database createDatabase(String databaseName) { 
      return new SQLDatabase(databaseName); 
     } 
    }, 
    XML { 
     @Override 
     public Database createDatabase(String databaseName) { 
      return new XMLDatabase(databaseName); 
     } 
    }; 

    public abstract Database createDatabase(String databaseName); 
} 

在Java中,enum s爲不是整數值只是漂亮的名稱(如C語言)。考慮enum的更好方法是將一個具有固定數量實例的類作爲一個類。與匿名類的概念一起,您可以爲枚舉中的每個值賦予該值特定的不同屬性和方法。

+0

+1不能說更好自己:)。 –