我目前正在为学校做一个小项目。在我的Java应用程序中,我需要一个数据库,并且我希望能够使我的应用程序能够使用不同类型的数据库。所以我目前实现了一个文本数据库和一个PostgreSQL。将来,应该可以添加其他数据库类型。如XML或MySQL,…
为了创建一个数据库实例,我设计了一个使用枚举的工厂。它工作得很好,但在我看来它不是很灵活。所以,我做了一些研究,但没有找到一个真正好的例子,对我来说很清楚。
这是我的enum:
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);
}
}
}
我的目标是将来只编辑enum,而不触及工厂本身。这应该给我足够的灵活性,但我不知道我该怎么做。
你可以把工厂放在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
不仅仅是整数值的好名字(就像在C中一样)。更好的方法是将enum
视为具有固定数量实例的类。结合匿名类的概念,您可以为枚举中的每个值赋予特定于该值的不同属性和方法。
使用反射:
enum:
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.
}
}