代码之家  ›  专栏  ›  技术社区  ›  Maihan Nijat

将数据库连接用作静态连接是一个好的实践吗?

  •  1
  • Maihan Nijat  · 技术社区  · 7 年前

    我在用 斯威夫特 我的ios应用程序的框架。我有 DatabaseService 类中创建数据库连接并执行所有 CURD 操作。我正在实例化这个类并在每个控制器上创建一个连接,但最近我将数据库变量更改为 static 为所有控制器创建一次连接。我不确定这是否是一个好的做法。以下是我执行此操作的方式:

    static var db: Connection?
    
    init() {
        if DatabaseService.db != nil {
            return
        }
        let path = NSSearchPathForDirectoriesInDomains(
            .documentDirectory, .userDomainMask, true
            ).first!
        do {
            let fileManager = FileManager()
            try fileManager.copyfileToUserDocumentDirectory(forResource: "db", ofType: "sqlite3")
    
            // Empty database will be created if file does not exist
            DatabaseService.db = try? Connection("\(path)/db.sqlite3")
    
            print("Connection successful")
        } catch let error {
            print("Unable to connect with the database. \(error)")
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Benjamin    7 年前

    我想真正的答案是:如果你知道你在做什么,而且你对如何安全地做有很好的把握,那当然。

    但既然你问: 我的回答是不。

    这里显示的静态变量是singleton模式(如果您在任何地方都使用它)。这个 singleton pattern 通常感觉这样做是正确的,但是当您开始添加线程并希望使用不同的数据提供程序时,事情开始变得有缺陷、更复杂和丑陋。 你最好用 dependency injection factory pattern 使用对象 你实例化了 就一次。

    这样做的代码实在不多。当您想要注入它(编译时或运行时)时,选择就变成了,swift使这一切变得非常容易。如果你想用一个例子来编辑,请告诉我。这样做的代码要多一些,但从长远来看,对于大多数情况,这会让你省去很多心痛。做一些关于单身汉利弊的研究。大多数人都认为在大多数情况下这是个坏主意。

    我要加一段 a book 我强烈建议:

    主要问题可能是由全局状态引起的,例如,使用singleton或静态成员 在你的测试单元里。不仅仅是单体增加了软件单元之间的耦合。它们还经常持有一个规避单元测试独立性的全局状态。例如,如果某个全局状态是成功测试的先决条件,但之前的测试已经改变了该全局状态,则可能会导致严重的问题。 尤其是在遗留系统中,这些系统常常充斥着单例,这就回避了一个问题:我如何才能摆脱对这些单例的所有那些讨厌的依赖,并使我的代码更易于测试?嗯,这是我讨论的一个重要问题…

    这本书还引用了对这本标志性著作作者的采访 Design Patterns 作者基本上说他们不介意放弃singleton模式,因为它从来没有被正确使用过。

    一本具有代表性和影响力的关于抽象设计模式的书的作者开玩笑说(我认为这是个玩笑)从他们的书的新修订版本中删除了单例设计模式…

    也许真正的答案总是否定的。