我实现了一个类Database Manager,它管理两个数据库引擎上的操作。类有一个私有变量databaseEngine,它在使用类方法之前设置(删除数据库、创建数据库、运行脚本、比较、断开等等)。基于这个变量,类识别如何行为。
然而,我知道这是错误的,Database Manager的方法充满了这样的情况:
public void CreateNewDatabase(String databaseName){
switch (databaseEngine){
case "mysql":
//Executes a prepared statement for dropping mysql database (databaseName
break;
case "postgres":
//Executes a prepared statement for dropping postgres database (databaseName
break;
...
}
}对此我需要一个很好的建议。我希望加载配置和资源文件夹中的所有内容,我的意思是,准备好的用于创建和删除的语句等等。如果需要支持一个新的数据库引擎,它不会很麻烦,因为它只需要将sql脚本保存在一个资源文件中,并将任何其他数据保存到一个配置文件中。,请给我推荐适合这种情况的任何设计模式.
发布于 2016-06-02 16:29:43
每当您需要基于switch语句调用不同的操作时,请考虑使用一个定义操作接口的抽象类和实现操作的实现类。
在您的示例中,databaseEngine是一个命名数据库的字符串。相反,创建一个抽象类DatabaseEngine并定义像createDatabase这样的操作
public abstract class DatabaseEngine {
public abstract void createDatabase(String databaseName);
public abstract void dropDatabase(String databaseName);
}并添加实现:
public class PostgresEngine extends DatabaseEngine {
public void createDatabase(String databaseName) {
... // do it the postgres way
}
}然后在你的经理类中使用它
public void createNewDatabase(String databaseName) {
engine_.createDatabase(databaseName);
}发布于 2016-06-03 07:22:05
第一件事:打开字符串太老套了;如果有的话;你会想要使用一个真正的枚举。当然,这并不是真正的问题;从"OO设计“的角度来看,转换枚举就像切换字符串一样糟糕(关于您所想到的事情)。
从面向对象的角度来看,wero的解决方案绝对是“正确的选择”。好的OO设计从SOLID开始(https://en.wikipedia.org/wiki/SOLID_(object-oriented_design%29);SOLID从SRP开始)。
在这种情况下,我要指出SRP的“只有一个改变的理由”。问题是:如果将2、3、n个不同数据库的所有数据库处理推到一个类中.这意味着,如果任何数据库需要更改,则必须更改该类。除了显而易见的事情:提供对一个数据库的“访问方式”(几乎更多)对于单个类来说是足够的“单一责任”。
另一种观点是:这是关于平衡的。要么你对一个好的,良好的结构,“真正的OO类型”设计感兴趣.然后,您必须咬紧牙关,要么定义一个接口,要么定义一个抽象基类;然后对每个具体的数据库进行不同的实现/扩展。
或者你更喜欢“把所有东西都塞进一个班级”.那就保留你所拥有的吧,因为如果你用金或钢做的门把手并不重要.因为一栋建在糟糕的地下室上的房子。
意思:你的开关语句只是一个不太理想的设计的结果.现在决定是否要治愈问题的症状或根本原因。
发布于 2016-06-03 07:53:25
我实现了一个类数据库管理器,它管理两个数据库引擎上的操作。
如果您有三个或四个或五个不同的数据库/存储库呢?例如,甲骨文、MongoDB、Redis等等,你还会把它们的实现都放到Database Manager中吗?
数据库管理器的方法充满了开关箱.
不出所料,因为你把所有的东西都放到了一个类中。
请给我建议一下适合这个情况的设计模式。
简化解决方案的最严格的方法是将MySQL和Postgree实现相互分离。您需要使用工厂和策略设计模式。如果你看到一个开关,你应该考虑使用它们,但不要沉迷于模式。它们不是您的目标,也就是说,不要仅仅因为您可以,就将它们放在代码中的任何地方。
因此,您应该从定义抽象开始。如果有所有数据库子类共有的功能,则创建接口或抽象类。
// I'm not sure what methods you need, so I just added methods you mentioned.
public interface MyDatabase {
void drop();
void create();
void runScript();
void compare();
void disconnect();
}然后,您需要实现您的数据库,这实际上是策略。
public final class MySqlDatabase implements MyDatabase {
@Override
public void drop() {}
...
}
public final class PostgreDatabase implements MyDatabase {
@Override
public void drop() {}
...
}最后,您需要创建一个工厂。如果你愿意的话,你可以把它变成静态的或者实现一个接口。
public class MyDatabaseFactory {
public MyDatabase create(String type) {
switch (type) {
case "mysql":
return new MySqlDatabase();
case "postgress":
return new PostgreDatabase();
default:
throw new IllegalArgumentException();
}
}
}你不一定要传递字符串。它可以是一个选项/设置类,但是它们有增长的趋势,这可能会导致类的膨胀。但不要太担心,这不是你目前最大的问题。
最后但并非最不重要。如果你不介意的话,修改你的命名规则。拜托,不要将您的类命名为经理或助手。
https://stackoverflow.com/questions/37597207
复制相似问题