您可於此 design_pattern repo 下載 Design Pattern 系列程式碼。
需求
我們收到了一個需求:開發一個應用程式,該應用程式需要與資料庫進行頻繁的交互。為了確保資料庫連接的效率和資源的合理使用,我們需要設計一個系統來管理資料庫連接。
物件導向分析 (OOA)
理解需求後,讓我們來快速實作物件導向分析吧!
我們有 CRUD 四個 function 以及 constructor 用來建立 DatabaseClient
察覺 Forces
來看看上面這樣的設計會有哪些問題
- 資源管理:多個資料庫連接會消耗大量資源,導致性能下降。
- 一致性:需要確保所有資料庫操作使用相同的連接,以避免數據不一致。
- 效率:頻繁創建和銷毀資料庫連接會降低系統效率。
套用 Singleton Pattern ( Solution ) 得到新的 Context ( Resulting Context )
做完 OOA,察覺 Forces,看清楚整個 Context 後,就可以來套用 Singleton Pattern 解決這個問題
先來看一下 Singleton Pattern 的 UML
我們可以發現,單例模式其實就是透過 getInstance() 方法去取得實體,而每次取的時都會去判斷內部 property instance 是否為 null,如果是 null 就創建一個新的,如果不是就回傳 instance property 的值,如此就能保證此 class 的實體只會有一個。
我們來將 DatabaseClient 套用 Singleton Pattern
如此我們就得到了一個全新的 Resulting Context
物件導向程式設計 (OOP)
再來我們就可以開始進行物件導向程式開發
[DatabaseClient]
class DatabaseClient {
fun create(tableName:String, data: Map<String, Any>): Int {
return 0
}
fun read(tableName:String, conditions: Map<String, Any>): Int {
return 0
}
fun update(tableName:String, data: Map<String, Any>, conditions: Map<String, Any>): Int {
return 0
}
fun delete(tableName:String, conditions: Map<String, Any>): Int {
return 0
}
companion object {
var mInstance: DatabaseClient? = null
fun getInstance(): DatabaseClient {
if (mInstance == null) {
mInstance = DatabaseClient()
}
return mInstance!!
}
}
}
[Client]
fun main() {
val db = DatabaseClient.getInstance()
db.create("test", mapOf(Pair("test", "123")))
}
這樣就完成了,這邊稍微提一下,其實 kotlin 語言有提供 object
來讓我們輕鬆實作 Singleton Pattern,如下
[DatabaseClient]
object DatabaseClient {
fun create(tableName:String, data: Map<String, Any>): Int {
return 0
}
fun read(tableName:String, conditions: Map<String, Any>): Int {
return 0
}
fun update(tableName:String, data: Map<String, Any>, conditions: Map<String, Any>): Int {
return 0
}
fun delete(tableName:String, conditions: Map<String, Any>): Int {
return 0
}
}
[Client]
fun main() {
val db = DatabaseClient
db.create("test", mapOf(Pair("test", "123")))
}
如此就能更簡單的操作 Singleton 的單例類別了!
Leave a comment