首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据库管理器类的设计模式

数据库管理器类的设计模式
EN

Stack Overflow用户
提问于 2016-06-02 16:20:09
回答 5查看 3.3K关注 0票数 1

我实现了一个类Database Manager,它管理两个数据库引擎上的操作。类有一个私有变量databaseEngine,它在使用类方法之前设置(删除数据库、创建数据库、运行脚本、比较、断开等等)。基于这个变量,类识别如何行为。

然而,我知道这是错误的,Database Manager的方法充满了这样的情况:

代码语言:javascript
复制
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脚本保存在一个资源文件中,并将任何其他数据保存到一个配置文件中。,请给我推荐适合这种情况的任何设计模式.

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-06-02 16:29:43

每当您需要基于switch语句调用不同的操作时,请考虑使用一个定义操作接口的抽象类和实现操作的实现类。

在您的示例中,databaseEngine是一个命名数据库的字符串。相反,创建一个抽象类DatabaseEngine并定义像createDatabase这样的操作

代码语言:javascript
复制
 public abstract class DatabaseEngine {
      public abstract void createDatabase(String databaseName);
      public abstract void dropDatabase(String databaseName);
 }

并添加实现:

代码语言:javascript
复制
public class PostgresEngine extends DatabaseEngine {
     public void createDatabase(String databaseName) { 
         ... // do it the postgres way
     }   
}

然后在你的经理类中使用它

代码语言:javascript
复制
public void createNewDatabase(String databaseName) {
     engine_.createDatabase(databaseName);
}
票数 3
EN

Stack Overflow用户

发布于 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类型”设计感兴趣.然后,您必须咬紧牙关,要么定义一个接口,要么定义一个抽象基类;然后对每个具体的数据库进行不同的实现/扩展。

或者你更喜欢“把所有东西都塞进一个班级”.那就保留你所拥有的吧,因为如果你用金或钢做的门把手并不重要.因为一栋建在糟糕的地下室上的房子。

意思:你的开关语句只是一个不太理想的设计的结果.现在决定是否要治愈问题的症状或根本原因。

票数 1
EN

Stack Overflow用户

发布于 2016-06-03 07:53:25

我实现了一个类数据库管理器,它管理两个数据库引擎上的操作。

如果您有三个或四个或五个不同的数据库/存储库呢?例如,甲骨文、MongoDB、Redis等等,你还会把它们的实现都放到Database Manager中吗?

数据库管理器的方法充满了开关箱.

不出所料,因为你把所有的东西都放到了一个类中。

请给我建议一下适合这个情况的设计模式。

简化解决方案的最严格的方法是将MySQLPostgree实现相互分离。您需要使用工厂和策略设计模式。如果你看到一个开关,你应该考虑使用它们,但不要沉迷于模式。它们不是您的目标,也就是说,不要仅仅因为您可以,就将它们放在代码中的任何地方。

因此,您应该从定义抽象开始。如果有所有数据库子类共有的功能,则创建接口或抽象类。

代码语言:javascript
复制
// 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();
}

然后,您需要实现您的数据库,这实际上是策略。

代码语言:javascript
复制
public final class MySqlDatabase implements MyDatabase {
    @Override
    public void drop() {}
    ...
}

public final class PostgreDatabase implements MyDatabase {
    @Override
    public void drop() {}
    ...
}

最后,您需要创建一个工厂。如果你愿意的话,你可以把它变成静态的或者实现一个接口。

代码语言:javascript
复制
public class MyDatabaseFactory {
    public MyDatabase create(String type) {
        switch (type) {
        case "mysql":
            return new MySqlDatabase();
        case "postgress":
            return new PostgreDatabase();
        default:
            throw new IllegalArgumentException();
        }
    } 
}

你不一定要传递字符串。它可以是一个选项/设置类,但是它们有增长的趋势,这可能会导致类的膨胀。但不要太担心,这不是你目前最大的问题。

最后但并非最不重要。如果你不介意的话,修改你的命名规则。拜托,不要将您的类命名为经理或助手

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37597207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档