零基础鸿蒙应用开发学习计划表
【学习目标】
- 掌握策略模式核心思想,基于
IGoodsComparator接口封装排序规则,实现排序逻辑的灵活扩展与解耦; - 理解工厂模式的应用场景,开发排序工厂类统一管理比较器实例,屏蔽底层实现细节;
- 整合单例管控+策略模式+工厂模式,构建“数据统一、规则可扩展、调用低耦合”的商品排序体系;
- 实战验证多场景排序能力,实现商品列表页“一键切换排序规则”,完成从功能实现到工程化设计的进阶。
【学习重点】
- 策略核心:以接口为契约,将库存、价格(升/降序)等排序规则封装为独立策略类,遵循“开闭原则”;
- 工厂实现:通过排序工厂类统一创建比较器实例,页面仅需传入排序类型即可调用,降低耦合;
- 架构整合:将策略模式、工厂模式融入上一节的单例体系,保证全局数据一致性的同时提升扩展性;
- 实战验证:在商品列表页新增下拉选择器,支持多规则切换,验证工程化重构的优势。
一、工程结构
复制上一节的ClassObjectDemo_6工程,重命名为ClassObjectDemo_7,新增排序策略与工厂相关文件:
ClassObjectDemo_7/
├── entry/ # 应用主模块
│ ├── src/main/ets/
│ │ ├── pages/ # 视图层
│ │ │ └── Index.ets # 核心演示页(排序规则切换实战)
│ │ ├── model/ # 核心模型层
│ │ │ ├── entity/ # 实体层(复用原有)
│ │ │ ├── interface/ # 契约层(复用IGoodsComparator接口)
│ │ │ ├── comparator/ # 排序策略实现(新增价格降序比较器)
│ │ │ └── utils/ # 工具层:新增排序工厂类
│ │ │ ├── GoodsList.ets # 复用:泛型商品容器
│ │ │ ├── GoodsTool.ets # 复用:泛型商品工具类
│ │ │ ├── GoodsManager.ets # 复用:单例商品管理中枢
│ │ │ └── SortFactory.ets # 新增:排序比较器工厂类
│ ├── resources/ # 资源目录
│ └── module.json5 # 模块配置
└── hvigorfile.ts # 构建脚本
二、核心痛点回顾与技术选型
2.1 第十六节排序体系的核心问题
在第十六节的实现中,页面调用排序逻辑需要直接依赖具体比较器类:
// 原页面调用方式:强耦合具体实现
this.goodsList = GoodsTool.sortByComparator(this.goodsList, new StockAscComparator());
存在两个核心问题:
- 耦合度高:页面需导入所有用到的比较器,若比较器类名/路径变更,所有调用处都需修改;
- 扩展繁琐:例如新增价格降序排序时,需创建
PriceDescComparator,再在页面导入并实例化,规则越多越混乱。
2.2 技术选型:策略模式+工厂模式
| 技术特性 | 解决的核心问题 | 适用场景 |
|---|---|---|
| 策略模式 | 排序规则与页面解耦,新增规则无需修改页面 | 多规则灵活切换的场景 |
| 工厂模式 | 统一管理比较器实例,屏蔽创建细节 | 实例化逻辑复杂、规则较多 |
| 单例模式 | 保证商品数据全局唯一,排序后数据同步 | 全应用商品数据统一管控 |
三、策略模式:排序规则的解耦与扩展
3.1 策略模式核心逻辑
策略模式的核心是接口定义契约,类实现具体策略,核心优势:
- 新增策略无需修改原有代码,符合开闭原则(对扩展开放、对修改关闭);
- 策略类专注单一排序规则,职责清晰,便于维护;
- 页面仅依赖接口,不依赖具体实现,降低耦合。
3.2 新增价格降序排序策略
基于IGoodsComparator接口,新增价格降序比较器,与原有库存、价格升序比较器共同构成策略族:
// model/comparator/PriceDescComparator.ets(价格降序)
import { AbstractGoods } from '../entity/AbstractGoods';
import { IGoodsComparator } from '../interface/behavior/IGoodsComparator';/*** 价格降序比较器*/
export class PriceDescComparator implements IGoodsComparator<AbstractGoods> {compare(a: AbstractGoods, b: AbstractGoods): number {return b.price - a.price;}
}
原有
StockAscComparator/StockDescComparator/PriceAscComparator保持不变,共同构成排序策略库。
四、工厂模式:排序比较器的统一管理
4.1 工厂模式核心逻辑
排序工厂类的核心是封装比较器的实例化逻辑,对外提供统一的获取接口,页面只需传入排序类型,无需关注具体实现类;同时通过缓存复用无状态的比较器实例,减少内存开销。
4.2 实现SortFactory排序工厂
// model/utils/SortFactory.ets
import { IGoodsComparator } from '../interface/behavior/IGoodsComparator';
import { AbstractGoods } from '../entity/AbstractGoods';
import { StockAscComparator } from '../comparator/StockAscComparator';
import { StockDescComparator } from '../comparator/StockDescComparator';
import { PriceAscComparator } from '../comparator/PriceAscComparator';
import { PriceDescComparator } from '../comparator/PriceDescComparator'; // 新增价格降序导入// 定义排序类型枚举
export enum SortType {STOCK_ASC = "stockAsc", // 库存升序STOCK_DESC = "stockDesc", // 库存降序PRICE_ASC = "priceAsc", // 价格升序PRICE_DESC = "priceDesc" // 新增:价格降序
}/*** 排序比较器工厂类* 核心:根据排序类型返回对应比较器实例,屏蔽创建细节;缓存实例减少重复创建*/
export class SortFactory {// 缓存比较器实例(无状态策略类复用,提升性能)private static comparatorCache: Map<SortType, IGoodsComparator<AbstractGoods>> = new Map();/*** 获取比较器实例* @param sortType 排序类型* @returns 对应的比较器实例*/public static getComparator(sortType: SortType): IGoodsComparator<AbstractGoods> {// 从缓存中读取,减少每次创建新的排序比较器,如果不存在则创建新的拍下比较器并存到Map中if (!SortFactory.comparatorCache.has(sortType)) {switch (sortType) {case SortType.STOCK_ASC:SortFactory.comparatorCache.set(sortType, new StockAscComparator());break;case SortType.STOCK_DESC:SortFactory.comparatorCache.set(sortType, new StockDescComparator());break;case SortType.PRICE_ASC:SortFactory.comparatorCache.set(sortType, new PriceAscComparator());break;case SortType.PRICE_DESC:SortFactory.comparatorCache.set(sortType, new PriceDescComparator());break;default:SortFactory.comparatorCache.set(sortType, new StockAscComparator());}}return SortFactory.comparatorCache.get(sortType)!;}
}
五、工程实战:排序规则的灵活切换
5.1 页面核心逻辑
// pages/Index.ets
import { AbstractGoods } from '../model/entity/AbstractGoods';
import { DigitalGoods } from '../model/entity/DigitalGoods';
import { BookGoods } from '../model/entity/BookGoods';
import { GoodsStatus } from '../model/entity/GoodsStatus';
import { GoodsManager } from '../model/utils/GoodsManager';
import { GoodsTool } from '../model/utils/GoodsTool';
import { SortFactory, SortType } from '../model/utils/SortFactory';
import { IBookGoods } from '../model/interface/attribute/IBookGoods';
import { IDigitalGoods } from '../model/interface/attribute/IDigitalGoods';@Entry
@Component
struct Index {@State goodsList: AbstractGoods[] = [];@State currentSortKey: SortType = SortType.STOCK_ASC;@State currentSortValue: string = "库存升序";@State selectMenus: SelectOption[] = [{value:"库存升序"},{value:"库存降序"},{value:"价格升序"},{value:"价格降序"}];private goodsManager = GoodsManager.getInstance();// 排序规则配置表(Map数组方式,适配Select索引联动)private sortMapList: Map<string,SortType>[] = [new Map([["库存升序",SortType.STOCK_ASC]]),new Map([[ "库存降序",SortType.STOCK_DESC]]),new Map([["价格升序",SortType.PRICE_ASC]]),new Map([["价格降序",SortType.PRICE_DESC]])];aboutToAppear() {this.initData();this.sortGoods();}// 初始化商品数据private initData(): void {const digitalProps: IDigitalGoods = {name: "鸿蒙Mate70手机",price: 5999,stock: 100,costPrice: 4000,category: "数码产品",status: GoodsStatus.ON_SHELF,brand: "华为",warranty: 2};const tabletProps: IDigitalGoods = {name: "鸿蒙平板Pro",price: 3999,stock: 80,costPrice: 2500,category: "数码产品",status: GoodsStatus.ON_SHELF,brand: "华为",warranty: 2};const bookProps: IBookGoods = {name: "鸿蒙开发实战",price: 69,stock: 500,costPrice: 30,category: "图书",status: GoodsStatus.ON_SHELF,author: "散修",publishDate: "2025-01"};const goodsList = [new DigitalGoods(digitalProps),new DigitalGoods(tabletProps),new BookGoods(bookProps)];this.goodsManager.addGoodsBatch(goodsList);this.goodsList = this.goodsManager.getGoodsList();}// 排序商品列表(基于工厂获取比较器,解耦具体实现)private sortGoods(): void {// 共排序工厂中获取对应的排序比较实例const comparator = SortFactory.getComparator(this.currentSortKey);this.goodsList = GoodsTool.sortByComparator(this.goodsList, comparator);// 控制台日志(输出排序规则+结果,便于调试)console.log(`[排序切换] 当前规则:${this.currentSortValue}`);console.log(`[排序结果]`, this.goodsList.map(g => `${g.name}(价格:¥${g.price} | 库存:${g.stock})`));}build() {Column() {Text("工厂+策略模式 排序演示").fontSize(20).fontWeight(FontWeight.Bold).margin(20);// 排序选择器Row({ space: 10 }) {Text("排序规则:").fontSize(16);Select(this.selectMenus).value(this.currentSortValue).onSelect((index: number, key: string) => {this.currentSortValue = key;const sortType = this.sortMapList[index].get(key);this.currentSortKey = sortType as SortType;this.sortGoods();}).width(200);}.margin({ bottom: 15 });// 商品列表(空状态兜底,提升用户体验)Scroll() {Column({ space: 10 }) {if (this.goodsList.length === 0) {Text("暂无商品数据").fontSize(16).fontColor('#999').margin(20);} else {ForEach(this.goodsList, (goods: AbstractGoods) => {Column({ space: 5 }) {Text(goods.name).fontSize(18).fontWeight(FontWeight.Medium);Text(`分类:${goods.category} | 价格:¥${goods.price.toFixed(2)} | 库存:${goods.stock}件`).fontSize(14).fontColor('#666');if (goods instanceof DigitalGoods) {Text(`品牌:${goods.brand} | 质保:${goods.warranty}年`).fontSize(12).fontColor('#999');}if (goods instanceof BookGoods) {Text(`作者:${goods.author} | 出版日期:${goods.publishDate}`).fontSize(12).fontColor('#999');}}.width('90%').padding(15).backgroundColor(Color.White).borderRadius(8);})}}.padding(10).width('100%');}.layoutWeight(1).width('100%');}.width('100%').height('100%').backgroundColor('#f5f5f5').padding(10);}
}
5.2 演示效果

六、架构整合与工程化最佳实践
6.1 三层架构整合逻辑
本次重构后,商品管理体系形成“数据层-规则层-调用层”的三层架构,各层职责清晰、解耦:
graph LRA[单例GoodsManager:全局数据层<br/>- 统一管控商品数据<br/>- 保证数据唯一性] --> B[GoodsTool:工具层<br/>- 排序/筛选等通用能力<br/>- 依赖策略接口]C[SortFactory:工厂层<br/>- 封装比较器实例化<br/>- 屏蔽底层实现细节<br/>- 缓存策略实例] --> BD[排序策略族:规则层<br/>- IGoodsComparator定契约<br/>- 各类实现具体排序规则<br/>- 无状态可复用] --> CB --> E[页面:调用层<br/>- 仅依赖工厂/枚举<br/>- 无需关注规则实现<br/>- 一键切换排序规则]
6.2 工程化最佳实践
- 策略模式应用原则:
- 当同一类业务有多种实现方案时,优先用接口定义契约,避免if-else分支判断;
- 新增策略只需实现接口,无需修改原有代码,符合开闭原则;
- 策略类设计为无状态,便于缓存复用(如比较器类无属性,仅含compare方法)。
- 工厂模式应用原则:
- 当实例化逻辑复杂或需要统一管理时,使用工厂类封装;
- 通过枚举限定入参类型,避免字符串硬编码导致的错误;
- 无状态策略类通过缓存复用,减少内存开销和实例化耗时。
- 与单例模式的配合:
- 单例负责数据的全局唯一性,策略和工厂负责业务逻辑的扩展,各司其职;
- 排序操作基于单例数据,保证多页面/多组件排序后数据同步;
- 单例类仅存储核心数据,页面临时状态(如当前排序值)保留在页面内部,避免内存泄漏。
七、内容总结
- 策略模式核心:以
IGoodsComparator接口为契约,将排序规则封装为独立策略类(如PriceDescComparator),实现规则与页面解耦,新增规则仅需新增策略类,无需修改原有代码; - 工厂模式核心:通过
SortFactory统一管理比较器实例化逻辑,页面仅需传入SortType枚举即可调用,屏蔽底层实现细节;同时缓存无状态策略实例,提升性能; - 架构整合价值:单例(数据统一)+策略(规则扩展)+工厂(实例管理)的整合,既保证商品数据全局唯一,又让排序体系具备“低耦合、高扩展”的工程化特性;
- 实战优化:补充商品列表空状态兜底、排序日志增强、策略实例缓存,提升代码健壮性和运行性能。
八、代码仓库
- 工程名称:
ClassObjectDemo_7 - 代码地址:https://gitee.com/juhetianxia321/harmony-os-code-base.git
下节预告
本节课我们通过工厂+策略模式完成了商品排序体系的重构,也掌握了“类实现接口”的核心用法,但当业务场景升级,需要为商品实现多种促销规则(折扣、多档位满减、赠品、满折、会员专属优惠等)时,单纯依赖“一个类实现多个接口”的基础用法,会暴露出致命问题:
- 商品类职责爆炸:商品类会充斥大量促销计算逻辑,违背“单一职责原则”,代码臃肿且难以维护;
- 规则叠加混乱:多种促销规则的叠加顺序(如先满减后折扣/先折扣后满减)、优先级(如400-40优先于200-20)无法统一管控,易出现计算错误;
- 扩展成本指数级增加:新增第三种促销规则时,需让商品类实现新接口,所有调用处都要同步调整,完全违背“开闭原则”;
- 代码复用性差:不同商品的同类促销规则(如数码/图书都支持满200减20),无法复用同一套实现逻辑,重复代码大量滋生。
下一节,我们将跳出“单纯用类实现接口”的思维局限,通过进阶版策略模式破解多促销规则的扩展难题