|
|
|
|
@ -0,0 +1,677 @@
|
|
|
|
|
# 小米便签应用 - UML 类图
|
|
|
|
|
|
|
|
|
|
## 一、类图概述
|
|
|
|
|
|
|
|
|
|
类图(Class Diagram)是软件工程中用于描述系统结构的静态图。它展示了系统中的类、接口以及它们之间的关系。类图是面向对象建模的核心工具。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 二、系统架构分层
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
┌────────────────────────────────────────┐
|
|
|
|
|
│ Presentation Layer │
|
|
|
|
|
│ ┌────────────┐ ┌──────────────┐ │
|
|
|
|
|
│ │NoteList │ │NoteEditor │ │
|
|
|
|
|
│ │Screen │ │Screen │ │
|
|
|
|
|
│ └────────────┘ └──────────────┘ │
|
|
|
|
|
│ ┌────────────┐ │
|
|
|
|
|
│ │NoteItem │ │
|
|
|
|
|
│ └────────────┘ │
|
|
|
|
|
└──────────────┬─────────────────────────┘
|
|
|
|
|
│
|
|
|
|
|
┌──────────────▼─────────────────────────┐
|
|
|
|
|
│ ViewModel Layer │
|
|
|
|
|
│ ┌──────────────────────────┐ │
|
|
|
|
|
│ │ NoteViewModel │ │
|
|
|
|
|
│ └──────────────────────────┘ │
|
|
|
|
|
└──────────────┬─────────────────────────┘
|
|
|
|
|
│
|
|
|
|
|
┌──────────────▼─────────────────────────┐
|
|
|
|
|
│ Data Layer │
|
|
|
|
|
│ ┌────────┐ ┌───────┐ ┌──────────┐ │
|
|
|
|
|
│ │ Note │ │NoteDao│ │NoteDatabase│ │
|
|
|
|
|
│ └────────┘ └───────┘ └──────────┘ │
|
|
|
|
|
│ ┌──────────────────────────┐ │
|
|
|
|
|
│ │ NoteRepository │ │
|
|
|
|
|
│ └──────────────────────────┘ │
|
|
|
|
|
└──────────────────────────────────────┘
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 三、类详细说明
|
|
|
|
|
|
|
|
|
|
### 3.1 实体类
|
|
|
|
|
|
|
|
|
|
#### Note
|
|
|
|
|
|
|
|
|
|
**职责**: 便签数据模型,映射数据库表
|
|
|
|
|
|
|
|
|
|
**属性**:
|
|
|
|
|
```
|
|
|
|
|
- id: Int (主键,自增)
|
|
|
|
|
- title: String (便签标题)
|
|
|
|
|
- content: String (便签内容)
|
|
|
|
|
- createTime: Long (创建时间戳)
|
|
|
|
|
- updateTime: Long (更新时间戳)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**方法**:
|
|
|
|
|
```
|
|
|
|
|
+ Note(id, title, content, createTime, updateTime)
|
|
|
|
|
+ componentN(): 数据类自动生成
|
|
|
|
|
+ copy(): 数据类自动生成
|
|
|
|
|
+ equals(): 数据类自动生成
|
|
|
|
|
+ hashCode(): 数据类自动生成
|
|
|
|
|
+ toString(): 数据类自动生成
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**注解**:
|
|
|
|
|
- `@Entity(tableName = "notes")`
|
|
|
|
|
- `@PrimaryKey(autoGenerate = true)`
|
|
|
|
|
|
|
|
|
|
**设计模式**: 数据类(Data Class)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 3.2 数据访问层
|
|
|
|
|
|
|
|
|
|
#### NoteDao
|
|
|
|
|
|
|
|
|
|
**职责**: 定义数据库操作的接口
|
|
|
|
|
|
|
|
|
|
**方法**:
|
|
|
|
|
```
|
|
|
|
|
+ getAllNotes(): Flow<List<Note>>
|
|
|
|
|
+ getNoteById(noteId: Int): Flow<Note?>
|
|
|
|
|
+ insertNote(note: Note): Long
|
|
|
|
|
+ updateNote(note: Note): Unit
|
|
|
|
|
+ deleteNote(note: Note): Unit
|
|
|
|
|
+ deleteNoteById(noteId: Int): Unit
|
|
|
|
|
+ deleteAllNotes(): Unit
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**注解**:
|
|
|
|
|
- `@Dao`
|
|
|
|
|
- `@Query`
|
|
|
|
|
- `@Insert`
|
|
|
|
|
- `@Update`
|
|
|
|
|
- `@Delete`
|
|
|
|
|
|
|
|
|
|
**设计模式**: 数据访问对象模式(DAO Pattern)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 3.3 数据库层
|
|
|
|
|
|
|
|
|
|
#### NoteDatabase
|
|
|
|
|
|
|
|
|
|
**职责**: 管理 SQLite 数据库实例
|
|
|
|
|
|
|
|
|
|
**属性**:
|
|
|
|
|
```
|
|
|
|
|
# INSTANCE: NoteDatabase? (单例实例)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**方法**:
|
|
|
|
|
```
|
|
|
|
|
+ abstract noteDao(): NoteDao
|
|
|
|
|
+ static getDatabase(context: Context): NoteDatabase
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**注解**:
|
|
|
|
|
- `@Database(entities = [Note::class], version = 1)`
|
|
|
|
|
|
|
|
|
|
**设计模式**:
|
|
|
|
|
- 单例模式(Singleton)
|
|
|
|
|
- 抽象工厂模式(Abstract Factory)
|
|
|
|
|
|
|
|
|
|
**线程安全**:
|
|
|
|
|
- `@Volatile` 保证可见性
|
|
|
|
|
- `synchronized` 保证原子性
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 3.4 仓库层
|
|
|
|
|
|
|
|
|
|
#### NoteRepository
|
|
|
|
|
|
|
|
|
|
**职责**: 封装数据操作,提供统一的数据访问接口
|
|
|
|
|
|
|
|
|
|
**属性**:
|
|
|
|
|
```
|
|
|
|
|
- noteDao: NoteDao (数据访问对象)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**方法**:
|
|
|
|
|
```
|
|
|
|
|
+ getAllNotes(): Flow<List<Note>>
|
|
|
|
|
+ getNoteById(noteId: Int): Flow<Note?>
|
|
|
|
|
+ createNote(note: Note): Long
|
|
|
|
|
+ updateNote(note: Note): Unit
|
|
|
|
|
+ deleteNote(note: Note): Unit
|
|
|
|
|
+ deleteNoteById(noteId: Int): Unit
|
|
|
|
|
+ deleteAllNotes(): Unit
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**设计模式**: 仓库模式(Repository Pattern)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 3.5 ViewModel 层
|
|
|
|
|
|
|
|
|
|
#### NoteViewModel
|
|
|
|
|
|
|
|
|
|
**职责**: 管理 UI 状态和业务逻辑
|
|
|
|
|
|
|
|
|
|
**属性**:
|
|
|
|
|
```
|
|
|
|
|
- repository: NoteRepository (数据仓库)
|
|
|
|
|
- _allNotes: MutableStateFlow<List<Note>> (便签列表)
|
|
|
|
|
- allNotes: StateFlow<List<Note>> (公开只读)
|
|
|
|
|
- _currentNote: MutableStateFlow<Note?> (当前便签)
|
|
|
|
|
- currentNote: StateFlow<Note?> (公开只读)
|
|
|
|
|
- _isLoading: MutableStateFlow<Boolean> (加载状态)
|
|
|
|
|
- isLoading: StateFlow<Boolean> (公开只读)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**方法**:
|
|
|
|
|
```
|
|
|
|
|
+ NoteViewModel(application: Application)
|
|
|
|
|
- observeNotes(): Unit
|
|
|
|
|
+ loadNote(noteId: Int): Unit
|
|
|
|
|
+ createNote(title: String, content: String): Unit
|
|
|
|
|
+ updateNote(note: Note): Unit
|
|
|
|
|
+ saveNote(title: String, content: String, noteId: Int?): Unit
|
|
|
|
|
+ deleteNote(note: Note): Unit
|
|
|
|
|
+ deleteNoteById(noteId: Int): Unit
|
|
|
|
|
+ clearCurrentNote(): Unit
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**继承**:
|
|
|
|
|
- 继承自 `AndroidViewModel`
|
|
|
|
|
|
|
|
|
|
**设计模式**:
|
|
|
|
|
- MVVM 模式
|
|
|
|
|
- 观察者模式(通过 Flow)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 3.6 UI 层
|
|
|
|
|
|
|
|
|
|
#### MainActivity
|
|
|
|
|
|
|
|
|
|
**职责**: 应用入口,初始化 Compose UI 和导航
|
|
|
|
|
|
|
|
|
|
**属性**:
|
|
|
|
|
```
|
|
|
|
|
- viewModel: NoteViewModel (by viewModels)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**方法**:
|
|
|
|
|
```
|
|
|
|
|
+ onCreate(savedInstanceState: Bundle?): Unit
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**继承**:
|
|
|
|
|
- 继承自 `ComponentActivity`
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
#### NoteListScreen (Composable)
|
|
|
|
|
|
|
|
|
|
**职责**: 显示便签列表
|
|
|
|
|
|
|
|
|
|
**参数**:
|
|
|
|
|
```
|
|
|
|
|
- navController: NavController
|
|
|
|
|
- viewModel: NoteViewModel
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**内部组件**:
|
|
|
|
|
- TopAppBar
|
|
|
|
|
- LazyColumn
|
|
|
|
|
- FloatingActionButton
|
|
|
|
|
- EmptyState
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
#### NoteEditorScreen (Composable)
|
|
|
|
|
|
|
|
|
|
**职责**: 编辑或创建便签
|
|
|
|
|
|
|
|
|
|
**参数**:
|
|
|
|
|
```
|
|
|
|
|
- navController: NavController
|
|
|
|
|
- viewModel: NoteViewModel
|
|
|
|
|
- noteId: Int
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**内部状态**:
|
|
|
|
|
- title: String (remember)
|
|
|
|
|
- content: String (remember)
|
|
|
|
|
|
|
|
|
|
**内部组件**:
|
|
|
|
|
- TopAppBar
|
|
|
|
|
- OutlinedTextField (标题)
|
|
|
|
|
- OutlinedTextField (内容)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
#### NoteItem (Composable)
|
|
|
|
|
|
|
|
|
|
**职责**: 显示单个便签卡片
|
|
|
|
|
|
|
|
|
|
**参数**:
|
|
|
|
|
```
|
|
|
|
|
- note: Note
|
|
|
|
|
- onClick: () -> Unit
|
|
|
|
|
- onDelete: () -> Unit
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**内部组件**:
|
|
|
|
|
- Card
|
|
|
|
|
- Text (标题)
|
|
|
|
|
- Text (内容)
|
|
|
|
|
- Text (时间)
|
|
|
|
|
- IconButton (删除)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 3.7 主题配置
|
|
|
|
|
|
|
|
|
|
#### Color
|
|
|
|
|
|
|
|
|
|
**定义的颜色常量**:
|
|
|
|
|
```
|
|
|
|
|
+ XiaomiOrange: Color
|
|
|
|
|
+ XiaomiOrangeDark: Color
|
|
|
|
|
+ BackgroundLight: Color
|
|
|
|
|
+ BackgroundDark: Color
|
|
|
|
|
+ CardBackgroundLight: Color
|
|
|
|
|
+ CardBackgroundDark: Color
|
|
|
|
|
+ TextPrimaryLight: Color
|
|
|
|
|
+ TextPrimaryDark: Color
|
|
|
|
|
+ TextSecondaryLight: Color
|
|
|
|
|
+ TextSecondaryDark: Color
|
|
|
|
|
+ DividerLight: Color
|
|
|
|
|
+ DividerDark: Color
|
|
|
|
|
+ DeleteRed: Color
|
|
|
|
|
+ DeleteRedDark: Color
|
|
|
|
|
+ NoteColors: List<Color>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
#### Theme
|
|
|
|
|
|
|
|
|
|
**方法**:
|
|
|
|
|
```
|
|
|
|
|
+ XiaomiNoteTheme(
|
|
|
|
|
darkTheme: Boolean,
|
|
|
|
|
dynamicColor: Boolean,
|
|
|
|
|
content: @Composable () -> Unit
|
|
|
|
|
): Unit
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**内部配置**:
|
|
|
|
|
- LightColorScheme
|
|
|
|
|
- DarkColorScheme
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
#### Type
|
|
|
|
|
|
|
|
|
|
**定义的排版样式**:
|
|
|
|
|
```
|
|
|
|
|
+ Typography: Typography
|
|
|
|
|
- headlineLarge
|
|
|
|
|
- headlineMedium
|
|
|
|
|
- titleLarge
|
|
|
|
|
- bodyLarge
|
|
|
|
|
- bodyMedium
|
|
|
|
|
- bodySmall
|
|
|
|
|
- labelLarge
|
|
|
|
|
- labelSmall
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 四、类关系
|
|
|
|
|
|
|
|
|
|
### 4.1 关联关系(Association)
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
MainActivity "1" --> "1" NoteViewModel : 拥有
|
|
|
|
|
NoteViewModel "1" --> "1" NoteRepository : 使用
|
|
|
|
|
NoteRepository "1" --> "1" NoteDao : 使用
|
|
|
|
|
NoteDatabase "1" --> "*" NoteDao : 创建
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4.2 依赖关系(Dependency)
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
NoteListScreen ..> NoteViewModel : 观察状态
|
|
|
|
|
NoteListScreen ..> NoteItem : 使用
|
|
|
|
|
NoteEditorScreen ..> NoteViewModel : 调用方法
|
|
|
|
|
NoteDao ..> Note : 操作
|
|
|
|
|
NoteRepository ..> Note : 操作
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4.3 继承关系(Inheritance)
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
NoteViewModel --|> AndroidViewModel
|
|
|
|
|
MainActivity --|> ComponentActivity
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4.4 实现关系(Realization)
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
NoteDao ..|> DAO接口
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 五、UML 类图(Mermaid 格式)
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
classDiagram
|
|
|
|
|
%% 实体类
|
|
|
|
|
class Note {
|
|
|
|
|
<<Entity>>
|
|
|
|
|
-id: Int
|
|
|
|
|
-title: String
|
|
|
|
|
-content: String
|
|
|
|
|
-createTime: Long
|
|
|
|
|
-updateTime: Long
|
|
|
|
|
+Note()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%% 数据访问层
|
|
|
|
|
class NoteDao {
|
|
|
|
|
<<DAO>>
|
|
|
|
|
+getAllNotes() Flow~List~Note~~
|
|
|
|
|
+getNoteById(noteId: Int) Flow~Note?~
|
|
|
|
|
+insertNote(note: Note) Long
|
|
|
|
|
+updateNote(note: Note) void
|
|
|
|
|
+deleteNote(note: Note) void
|
|
|
|
|
+deleteNoteById(noteId: Int) void
|
|
|
|
|
+deleteAllNotes() void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%% 数据库层
|
|
|
|
|
class NoteDatabase {
|
|
|
|
|
<<Database>>
|
|
|
|
|
-INSTANCE: NoteDatabase?
|
|
|
|
|
+noteDao() NoteDao
|
|
|
|
|
+getDatabase(context: Context) NoteDatabase
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%% 仓库层
|
|
|
|
|
class NoteRepository {
|
|
|
|
|
-noteDao: NoteDao
|
|
|
|
|
+getAllNotes() Flow~List~Note~~
|
|
|
|
|
+getNoteById(noteId: Int) Flow~Note?~
|
|
|
|
|
+createNote(note: Note) Long
|
|
|
|
|
+updateNote(note: Note) void
|
|
|
|
|
+deleteNote(note: Note) void
|
|
|
|
|
+deleteNoteById(noteId: Int) void
|
|
|
|
|
+deleteAllNotes() void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%% ViewModel层
|
|
|
|
|
class NoteViewModel {
|
|
|
|
|
-repository: NoteRepository
|
|
|
|
|
-_allNotes: MutableStateFlow~List~Note~~
|
|
|
|
|
+allNotes: StateFlow~List~Note~~
|
|
|
|
|
-_currentNote: MutableStateFlow~Note?~
|
|
|
|
|
+currentNote: StateFlow~Note?~
|
|
|
|
|
+NoteViewModel(application: Application)
|
|
|
|
|
-observeNotes() void
|
|
|
|
|
+loadNote(noteId: Int) void
|
|
|
|
|
+saveNote(title: String, content: String, noteId: Int?) void
|
|
|
|
|
+deleteNote(note: Note) void
|
|
|
|
|
+deleteNoteById(noteId: Int) void
|
|
|
|
|
+clearCurrentNote() void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%% UI层
|
|
|
|
|
class MainActivity {
|
|
|
|
|
-viewModel: NoteViewModel
|
|
|
|
|
+onCreate(savedInstanceState: Bundle?) void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class NoteListScreen {
|
|
|
|
|
<<Composable>>
|
|
|
|
|
+NoteListScreen(navController, viewModel) void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class NoteEditorScreen {
|
|
|
|
|
<<Composable>>
|
|
|
|
|
+NoteEditorScreen(navController, viewModel, noteId) void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class NoteItem {
|
|
|
|
|
<<Composable>>
|
|
|
|
|
+NoteItem(note, onClick, onDelete) void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%% 关系
|
|
|
|
|
NoteViewModel --|> AndroidViewModel
|
|
|
|
|
MainActivity --|> ComponentActivity
|
|
|
|
|
|
|
|
|
|
MainActivity "1" --> "1" NoteViewModel : 拥有
|
|
|
|
|
NoteViewModel "1" --> "1" NoteRepository : 使用
|
|
|
|
|
NoteRepository "1" --> "1" NoteDao : 使用
|
|
|
|
|
NoteDatabase "1" --> "1" NoteDao : 创建
|
|
|
|
|
NoteDao ..> Note : 操作
|
|
|
|
|
NoteRepository ..> Note : 操作
|
|
|
|
|
|
|
|
|
|
NoteListScreen ..> NoteViewModel : 观察
|
|
|
|
|
NoteListScreen ..> NoteItem : 使用
|
|
|
|
|
NoteEditorScreen ..> NoteViewModel : 调用
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 六、设计模式应用
|
|
|
|
|
|
|
|
|
|
### 6.1 MVVM 模式
|
|
|
|
|
|
|
|
|
|
**实现**:
|
|
|
|
|
- **Model**: Note, NoteDao, NoteDatabase, NoteRepository
|
|
|
|
|
- **View**: MainActivity, NoteListScreen, NoteEditorScreen, NoteItem
|
|
|
|
|
- **ViewModel**: NoteViewModel
|
|
|
|
|
|
|
|
|
|
**优势**:
|
|
|
|
|
- 关注点分离
|
|
|
|
|
- 可测试性强
|
|
|
|
|
- 生命周期感知
|
|
|
|
|
|
|
|
|
|
### 6.2 Repository 模式
|
|
|
|
|
|
|
|
|
|
**实现**: NoteRepository 封装所有数据操作
|
|
|
|
|
|
|
|
|
|
**优势**:
|
|
|
|
|
- 统一数据访问接口
|
|
|
|
|
- 便于切换数据源
|
|
|
|
|
- 业务逻辑与数据访问分离
|
|
|
|
|
|
|
|
|
|
### 6.3 单例模式
|
|
|
|
|
|
|
|
|
|
**实现**: NoteDatabase 使用双重检查锁定
|
|
|
|
|
|
|
|
|
|
**优势**:
|
|
|
|
|
- 全局唯一数据库实例
|
|
|
|
|
- 线程安全
|
|
|
|
|
- 延迟初始化
|
|
|
|
|
|
|
|
|
|
### 6.4 观察者模式
|
|
|
|
|
|
|
|
|
|
**实现**: Flow 响应式数据流
|
|
|
|
|
|
|
|
|
|
**优势**:
|
|
|
|
|
- 自动更新 UI
|
|
|
|
|
- 解耦数据源和观察者
|
|
|
|
|
- 支持背压
|
|
|
|
|
|
|
|
|
|
### 6.5 工厂模式
|
|
|
|
|
|
|
|
|
|
**实现**: NoteDatabase.getDatabase() 创建数据库实例
|
|
|
|
|
|
|
|
|
|
**优势**:
|
|
|
|
|
- 封装创建逻辑
|
|
|
|
|
- 控制实例化过程
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 七、数据流分析
|
|
|
|
|
|
|
|
|
|
### 7.1 数据读取流程
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
用户打开应用
|
|
|
|
|
↓
|
|
|
|
|
MainActivity 初始化
|
|
|
|
|
↓
|
|
|
|
|
创建 NoteViewModel
|
|
|
|
|
↓
|
|
|
|
|
初始化 NoteRepository
|
|
|
|
|
↓
|
|
|
|
|
获取 NoteDao
|
|
|
|
|
↓
|
|
|
|
|
查询数据库 (Flow)
|
|
|
|
|
↓
|
|
|
|
|
更新 StateFlow
|
|
|
|
|
↓
|
|
|
|
|
UI 自动刷新 (collectAsState)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 7.2 数据写入流程
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
用户点击保存
|
|
|
|
|
↓
|
|
|
|
|
NoteEditorScreen 调用 ViewModel
|
|
|
|
|
↓
|
|
|
|
|
NoteViewModel.saveNote()
|
|
|
|
|
↓
|
|
|
|
|
NoteRepository.createNote() / updateNote()
|
|
|
|
|
↓
|
|
|
|
|
NoteDao.insertNote() / updateNote()
|
|
|
|
|
↓
|
|
|
|
|
写入 SQLite 数据库
|
|
|
|
|
↓
|
|
|
|
|
Flow 自动发射新数据
|
|
|
|
|
↓
|
|
|
|
|
StateFlow 更新
|
|
|
|
|
↓
|
|
|
|
|
UI 自动刷新
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 八、关键设计决策
|
|
|
|
|
|
|
|
|
|
### 8.1 为什么使用 Flow 而不是 LiveData?
|
|
|
|
|
|
|
|
|
|
**选择 Flow 的原因**:
|
|
|
|
|
1. 更强大的操作符
|
|
|
|
|
2. 更好的协程集成
|
|
|
|
|
3. 支持冷流和热流
|
|
|
|
|
4. 更灵活的线程控制
|
|
|
|
|
|
|
|
|
|
### 8.2 为什么使用 StateFlow 而不是 MutableStateFlow 公开?
|
|
|
|
|
|
|
|
|
|
**封装原则**:
|
|
|
|
|
- 内部使用 MutableStateFlow 可变
|
|
|
|
|
- 外部暴露 StateFlow 只读
|
|
|
|
|
- 防止外部意外修改状态
|
|
|
|
|
|
|
|
|
|
### 8.3 为什么使用 Repository 模式?
|
|
|
|
|
|
|
|
|
|
**优势**:
|
|
|
|
|
- 单一职责原则
|
|
|
|
|
- 便于添加缓存层
|
|
|
|
|
- 易于单元测试
|
|
|
|
|
- 支持多数据源扩展
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 九、扩展性设计
|
|
|
|
|
|
|
|
|
|
### 9.1 添加搜索功能
|
|
|
|
|
|
|
|
|
|
**扩展点**:
|
|
|
|
|
```kotlin
|
|
|
|
|
// 在 NoteDao 中添加
|
|
|
|
|
@Query("SELECT * FROM notes WHERE title LIKE :query OR content LIKE :query")
|
|
|
|
|
fun searchNotes(query: String): Flow<List<Note>>
|
|
|
|
|
|
|
|
|
|
// 在 NoteRepository 中添加
|
|
|
|
|
fun searchNotes(query: String): Flow<List<Note>>
|
|
|
|
|
|
|
|
|
|
// 在 NoteViewModel 中添加
|
|
|
|
|
fun searchNotes(query: String)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 9.2 添加分类功能
|
|
|
|
|
|
|
|
|
|
**扩展点**:
|
|
|
|
|
```kotlin
|
|
|
|
|
// 扩展 Note 实体
|
|
|
|
|
data class Note(
|
|
|
|
|
val id: Int = 0,
|
|
|
|
|
val title: String = "",
|
|
|
|
|
val content: String = "",
|
|
|
|
|
val categoryId: Int? = null, // 新增
|
|
|
|
|
val createTime: Long = System.currentTimeMillis(),
|
|
|
|
|
val updateTime: Long = System.currentTimeMillis()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 创建 Category 实体
|
|
|
|
|
@Entity(tableName = "categories")
|
|
|
|
|
data class Category(
|
|
|
|
|
@PrimaryKey(autoGenerate = true)
|
|
|
|
|
val id: Int = 0,
|
|
|
|
|
val name: String
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 9.3 添加云同步
|
|
|
|
|
|
|
|
|
|
**扩展点**:
|
|
|
|
|
```kotlin
|
|
|
|
|
// 创建远程数据源
|
|
|
|
|
class RemoteNoteDataSource {
|
|
|
|
|
suspend fun syncNotes(notes: List<Note>)
|
|
|
|
|
suspend fun fetchNotes(): List<Note>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 扩展 Repository
|
|
|
|
|
class NoteRepository(
|
|
|
|
|
private val localDao: NoteDao,
|
|
|
|
|
private val remoteDataSource: RemoteNoteDataSource
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 十、总结
|
|
|
|
|
|
|
|
|
|
本类图展示了小米便签应用的完整架构设计:
|
|
|
|
|
|
|
|
|
|
✅ **清晰的分层**: Presentation、ViewModel、Data 三层
|
|
|
|
|
✅ **合理的职责划分**: 每个类都有明确的职责
|
|
|
|
|
✅ **优秀的设计模式**: MVVM、Repository、Singleton、Observer
|
|
|
|
|
✅ **高内聚低耦合**: 类之间关系清晰,依赖合理
|
|
|
|
|
✅ **良好的扩展性**: 易于添加新功能
|
|
|
|
|
|
|
|
|
|
**架构评级**: ⭐⭐⭐⭐⭐ 优秀
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
**文档版本**: v1.0
|
|
|
|
|
**创建日期**: 2026年4月24日
|