本文解析 ImportantDays 项目中的
Constants.ets常量文件,探讨枚举定义、接口设计、常量管理策略,以及如何通过集中的类型系统提升代码可维护性和类型安全性。
一、Constants 文件的定位
Constants.ets是项目的"类型字典",集中定义了所有枚举、接口和常量。它的价值在于:
- 统一引用:所有模块从同一处导入常量
- 类型安全:接口定义确保数据结构一致
- 易于维护:修改常量只需改一处
- 代码文档:通过命名和注释传达业务含义
二、枚举定义
ViewTypeEnum:日历视图类型
exportenumViewTypeEnum{YEAR,// 年视图MONTH,// 月视图WEEK,// 周视图DAY// 日视图}虽然目前只使用了YEAR和MONTH,但预留了WEEK和DAY,为未来扩展做准备。
SortTypeEnum:排序方式
exportenumSortTypeEnum{DATE_ASC,// 按日期升序DATE_DESC,// 按日期降序CREATE_TIME// 按创建时间}三种排序方式覆盖了常见需求:
DATE_ASC:即将到来的在前DATE_DESC:最远的在前CREATE_TIME:最近添加的在前
枚举的设计考量
使用enum而非常量字符串的优势:
// 使用 enum(项目采用)sortType===SortTypeEnum.DATE_ASC// 类型安全// 使用常量字符串sortType==='DATE_ASC'// 容易拼写错误三、常量定义
日历相关
exportconstWEEK_DAYS=7;exportconstMONTH_NAMES:string[]=['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'];exportconstWEEK_NAMES:string[]=['日','一','二','三','四','五','六'];exportconstCALENDAR_SWIPER_COUNT=3;| 常量 | 值 | 用途 |
|---|---|---|
WEEK_DAYS | 7 | 一周天数 |
MONTH_NAMES | 中文月份名 | 预留(目前用 dayjs 格式化) |
WEEK_NAMES | 中文星期名 | 星期标题行 |
CALENDAR_SWIPER_COUNT | 3 | Swiper 缓存页数 |
存储相关
exportconstSTORAGE_KEY_IMPORTANT_DAYS='important_days_list';exportconstNOTIFICATION_CHANNEL_ID='important_days_reminder';| 常量 | 值 | 用途 |
|---|---|---|
STORAGE_KEY_IMPORTANT_DAYS | 'important_days_list' | Preferences 存储键 |
NOTIFICATION_CHANNEL_ID | 'important_days_reminder' | 通知渠道 ID |
布局相关
exportconstCOMMON_PADDING=12;exportconstCOMMON_PADDING_SMALL=8;exportconstCOMMON_PADDING_LARGE=16;统一的间距常量,确保全应用布局一致。目前这些常量定义了但未广泛使用(各组件直接写了数值),是未来重构的方向。
颜色
exportconstDEFAULT_COLOR='#FF6B6B';默认颜色为红色,与主题色一致。
四、接口定义
TabItem
exportinterfaceTabItem{title:string;icon:Resource;activeIcon:Resource;}Tab 配置接口,预留了图标支持。目前MainEntry的tabBuilder只用了文字,但此接口为图标扩展做好准备。
ViewTypeItem
exportinterfaceViewTypeItem{type:ViewTypeEnum;name:string;}视图类型配置项,用于CalendarPage的视图切换按钮:
privategetViewTypes():ViewTypeItem[]{return[{type:ViewTypeEnum.YEAR,name:'年'},{type:ViewTypeEnum.MONTH,name:'月'}];}Stats
exportinterfaceStats{total:number;upcoming:number;past:number;today:number;}统计信息接口,定义了四种统计数据结构。
ImportantDayJSON
exportinterfaceImportantDayJSON{dayID:string;title:string;targetDate:number;// 时间戳isCountdown:boolean;color:string;reminderEnabled:boolean;reminderDaysBefore:number;note:string;isPinned:boolean;createTime:number;// 时间戳}序列化接口,定义了ImportantDay持久化时的 JSON 结构。
与 ImportantDay 类的区别:
| 特性 | ImportantDay | ImportantDayJSON |
|---|---|---|
targetDate | Date | number(时间戳) |
createTime | Date | number(时间戳) |
| 装饰器 | @ObservedV2+@Trace | 无 |
| 用途 | 运行时使用 | 持久化存储 |
五、类型系统在项目中的应用
枚举的使用
// 排序@LocalsortBy:SortTypeEnum=SortTypeEnum.DATE_ASC;// 视图类型@TraceviewType:ViewTypeEnum=ViewTypeEnum.MONTH;// switch 分支switch(sortType){caseSortTypeEnum.DATE_ASC:...caseSortTypeEnum.DATE_DESC:...caseSortTypeEnum.CREATE_TIME:...}接口的使用
// Stats 接口getStats():Stats{return{total:this.allDays.length,upcoming:this.getUpcomingDays().length,past:this.getPastDays().length,today:this.getTodayDays().length};}// ViewTypeItem 接口ForEach(this.getViewTypes(),(item:ViewTypeItem)=>{Text(item.name).fontColor(this.vm.viewType===item.type?'#FFFFFF':'#666666')})// ImportantDayJSON 接口toJSON():ImportantDayJSON{return{...};}六、常量管理的最佳实践
1. 命名规范
// 常量:全大写 + 下划线exportconstWEEK_DAYS=7;exportconstSTORAGE_KEY_IMPORTANT_DAYS='important_days_list';// 枚举:PascalCaseexportenumViewTypeEnum{...}exportenumSortTypeEnum{...}// 接口:PascalCaseexportinterfaceStats{...}exportinterfaceTabItem{...}2. 注释规范
/** 日历视图类型 */exportenumViewTypeEnum{/** 年视图 */YEAR,/** 月视图 */MONTH,...}每个枚举和枚举值都有注释,便于理解。
3. 分组组织
常量按功能分组:
- 视图相关:
ViewTypeEnum、ViewTypeItem - 日历相关:
WEEK_DAYS、MONTH_NAMES、WEEK_NAMES - 存储相关:
STORAGE_KEY_IMPORTANT_DAYS - 通知相关:
NOTIFICATION_CHANNEL_ID - 布局相关:
COMMON_PADDING系列 - 数据相关:
Stats、ImportantDayJSON
七、改进建议
1. 颜色常量集中管理
目前DEFAULT_COLOR在Constants.ets,而PRESET_COLORS在ImportantDay.ets。建议统一:
// Constants.etsexportconstDEFAULT_COLOR='#FF6B6B';exportconstPRESET_COLORS:string[]=[...];2. 布局常量推广使用
目前COMMON_PADDING等常量未被广泛使用,建议各组件统一引用:
// 替代直接写数字.padding({left:COMMON_PADDING_LARGE,right:COMMON_PADDING_LARGE})3. 颜色主题化
可以定义颜色主题:
exportinterfaceAppTheme{primary:string;secondary:string;background:string;textPrimary:string;textSecondary:string;textHint:string;}exportconstLIGHT_THEME:AppTheme={primary:'#FF6B6B',secondary:'#4ECDC4',background:'#FFFFFF',textPrimary:'#333333',textSecondary:'#666666',textHint:'#999999'};八、总结
Constants.ets的设计体现了以下原则:
- 集中管理:所有常量和类型定义在一处
- 类型安全:使用枚举和接口确保类型正确
- 语义清晰:命名和注释传达业务含义
- 预留扩展:枚举预留未来值,接口预留未来字段
- 分组有序:按功能分组,便于查找
常量文件是项目的"契约",定义了各模块之间共享的数据结构和约定,其设计质量直接影响项目的可维护性。