ios - 将数据库连接用作静态是一种好习惯吗?
问题描述
我正在为我的 iOS 应用程序使用SQLite.swift框架。我有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)")
}
}
解决方案
我想真正的答案是:如果你知道自己在做什么,并且对如何安全地做这件事有很好的把握,那么当然可以。
但既然你问:我的答案是否定的。
您在此处显示的静态变量是单例模式,如果您在任何地方都使用它的话。单例模式通常感觉是正确的做法,但是当您开始添加线程并想要使用不同的数据提供者时,事情开始变得有问题、更复杂和难看。你最好使用工厂模式的依赖注入,使用你只实例化一次的对象。
这样做真的不需要更多的代码。当您想要注入它时(编译时或运行时),选择就变成了,而 Swift 使这一切变得非常容易。如果您想通过示例进行编辑,请告诉我。预先以这种方式执行此操作需要更多代码,但从长远来看,对于大多数情况,它会为您节省很多心痛。做一些关于单例的利弊的研究。大多数人都同意在大多数情况下这是一个坏主意。
我将添加我强烈推荐的书中的一段:
主要问题可能是由全局状态引起的,例如,在您的被测单元中使用单例或静态成员。Singleton 不仅增加了软件单元之间的耦合。他们还经常拥有一个绕过单元测试独立性的全局状态。例如,如果某个全局状态是成功测试的先决条件,但之前的测试已经改变了该全局状态,那么它可能会导致严重的问题。尤其是在遗留系统中,这些系统经常充斥着单例,这就引出了一个问题:我如何才能摆脱对这些单例的所有讨厌的依赖,并使我的代码更好地可测试?嗯,这是我讨论的一个重要问题......
这本书还继续引用了对标志性书籍设计模式作者的采访,作者基本上说他们不介意放弃单例模式,因为它从未被正确使用。
一本关于抽象设计模式的标志性和有影响力的书的作者开玩笑(我认为这是一个笑话)关于从他们的书的新修订版本中删除单例设计模式......
也许真正的答案真的永远是否定的。
推荐阅读
- css - CSS 选择器
- trigonometry - 根据直线相交的 3 个点制作贝塞尔曲线
- python-3.x - 填充熊猫的条件日期时间列
- javascript - 将 React 网站拆分为单独的模块并作为 npm 依赖项加载到一个包中
- python - 如何使用 Selenium 和 Python 在 chrome 中单击弹出元素
- python - 使用 fgets 导致缓冲区溢出
- python - AttributeError:模块“cv2.cv2”在 OpenCV 中没有属性“freetype”
- python - 在 Tensorflow 2.0 上使用带有 Keras 输入层的 tf.data.Dataset
- javascript - 删除 JavaScript 数组中特定字符的最佳方法是什么?
- javascript - 变量在函数之外不起作用