一週過去了。
作為一人公司的創辦人,每週日我會花時間回顧這週的決策、失敗和學習。這不是給投資人看的粉飾報告,而是對自己誠實的反思。
這週的主題很明確:我被自己的經驗困住了。
昨天提到,我一直用 Java/Spring 的思維寫 Kotlin。讓我們看看具體差異。
Spring 開發者的本能反應是什麼?當然要 Dependency Injection!要 @Component、@Autowired、@Transactional。30 行程式碼處理事務、例外、日誌。
// 我的第一反應
@Component
class ProjectService {
@Autowired
private lateinit var projectRepository: ProjectRepository
@Transactional
fun createProject(name: String): Project {
// 30 行程式碼處理事務、例外、日誌...
}
}
但 Kotlin 的方式呢?
簡單直接。
// Kotlin:簡單直接
class ProjectRepository(private val database: Database) {
fun createProject(name: String) = database.transaction {
// 5 行程式碼搞定
}
}
// 手動 DI,清晰可見
object AppModule {
val database = Database(...)
val projectRepository = ProjectRepository(database)
}
沒有註解魔法,沒有反射,沒有啟動時掃描。一切都是普通的 Kotlin 程式碼。
還記得學 Spring 的日子嗎?
買本《Spring 實戰》,600 頁。看官方文件,迷失在無盡的配置中。StackOverflow 搜尋,找到的答案都是 5 年前的。踩坑、除錯、懷疑人生。
這次學 Kotlin Multiplatform,我換了方法。
我直接問 Claude:「我有 Spring Boot 背景,如何用 Kotlin 思維重構這段程式碼?」Claude 馬上指出我用了 @Component 和 @Autowired,建議在 Kotlin 中用更明確的依賴管理。
接著問:「MVI 架構在 Compose Desktop 中的最佳實踐是什麼?」立刻得到可執行的範例程式碼。
關鍵差異在哪?即時回饋,不用等到編譯或運行才知道錯誤。個性化指導,基於你的背景給出建議。最新實踐,AI 的知識包含最新的社群共識。範例驅動,直接給出可運行的程式碼。
我以為 Kotlin 的 Repository 應該像 Spring 那樣寫。有 findById、save、deleteById、findAll,20 個方法。
錯了。
AI 建議用 SQLDelight 的 Kotlin 方式:
// Projects.sq
selectAll:
SELECT * FROM projects;
selectById:
SELECT * FROM projects WHERE id = ?;
insert:
INSERT INTO projects(name, description) VALUES (?, ?);
// Kotlin 程式碼自動生成,類型安全
val projects = database.projectsQueries.selectAll().executeAsList()
不是把 JPA 的模式搬過來,而是用 SQLDelight 的方式思考。
Spring 的哲學是什麼?Convention over Configuration,框架決定結構。Enterprise Ready,為大型團隊設計。Annotation Driven,用註解表達意圖。Runtime Magic,運行時解析依賴。
Kotlin/Compose 的哲學呢?
Explicit over Implicit,明確優於隱含。Compile-time Safety,編譯時期保證正確。Functional Thinking,函數式優先。Simplicity,能簡單就不要複雜。
理解這些差異後,我不再試圖把 Spring 的模式帶過來,而是擁抱 Kotlin 的方式。
拋棄單一 JVM 的「聰明」方案後,新架構反而更清晰。
// app-desktop/Main.kt
fun main() = application {
val appModule = AppModule() // 簡單的依賴注入
Window(
onCloseRequest = ::exitApplication,
state = rememberWindowState(width = 1200.dp, height = 800.dp),
title = "Grimo"
) {
App(appModule)
}
}
// shared/AppModule.kt
class AppModule {
val database = createDatabase()
val projectRepository = ProjectRepository(database)
val projectViewModel = ProjectViewModel(projectRepository)
// 清晰的依賴關係,沒有魔法
}
沒有 Spring Context,沒有 Bean Factory,沒有 AOP。
就是簡單的 Kotlin 程式碼。
學習新框架時,我有個提問模板。
「背景:我有 X 框架的經驗,現在學習 Y 框架。問題:X 框架中我們用某模式解決某問題,在 Y 框架中的慣用方式是什麼?」
程式碼審查也很有用。把程式碼貼給 AI,請它從 Kotlin 的最佳實踐角度給出改進建議。
架構決策更是如此。描述場景、限制、初步方案,讓 AI 評估並提供替代建議。
週一到週三,信心滿滿。選定技術棧、設計「完美」架構、開始實作。
週四到週五,挫敗困惑。Spring + Compose = 災難。依賴衝突。懷疑人生。
週六到週日,頓悟重生。
放下 Spring 包袱。擁抱 Kotlin 哲學。與 AI 深度對話。重構成功。
經驗是雙刃劍。豐富的經驗可能成為學習新事物的障礙。
AI 改變學習曲線。從陡峭到平緩,從獨自摸索到有導師相伴。
簡單是最高境界。不是無法複雜,而是選擇簡單。
框架哲學很重要。理解「為什麼」比知道「怎麼做」更重要。
如果你也是從其他語言/框架轉到 Kotlin 的開發者,我有幾個建議。
不要急著寫程式碼,先理解哲學差異。善用 AI,它是你的私人 Kotlin 導師。參考官方範例和社群最佳實踐,不要憑經驗推測。保持初學者心態,你的經驗可能是負資產。
記住:Kotlin 不是更好的 Java,它是不同的思維方式。
下週,我們要開始真正的 Kotlin Multiplatform 開發了。這次,我會放下包袱,用正確的方式。
「最難的不是學習新知識,而是放下舊習慣。」
關於作者:Sam,一人公司創辦人。正在打造 Grimo,一個智能任務管理和分配平台。
專案連結:GitHub - grimostudio