# 零基础鸿蒙应用开发第二十八节:商品排序体系之工厂与策略模式 - 鸿蒙

news/2026/1/25 11:06:51/文章来源:https://www.cnblogs.com/san-xiu/p/19528913

零基础鸿蒙应用开发学习计划表

【学习目标】

  1. 掌握策略模式核心思想,基于IGoodsComparator接口封装排序规则,实现排序逻辑的灵活扩展与解耦;
  2. 理解工厂模式的应用场景,开发排序工厂类统一管理比较器实例,屏蔽底层实现细节;
  3. 整合单例管控+策略模式+工厂模式,构建“数据统一、规则可扩展、调用低耦合”的商品排序体系;
  4. 实战验证多场景排序能力,实现商品列表页“一键切换排序规则”,完成从功能实现到工程化设计的进阶。

【学习重点】

  • 策略核心:以接口为契约,将库存、价格(升/降序)等排序规则封装为独立策略类,遵循“开闭原则”;
  • 工厂实现:通过排序工厂类统一创建比较器实例,页面仅需传入排序类型即可调用,降低耦合;
  • 架构整合:将策略模式、工厂模式融入上一节的单例体系,保证全局数据一致性的同时提升扩展性;
  • 实战验证:在商品列表页新增下拉选择器,支持多规则切换,验证工程化重构的优势。

一、工程结构

复制上一节的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());

存在两个核心问题:

  1. 耦合度高:页面需导入所有用到的比较器,若比较器类名/路径变更,所有调用处都需修改;
  2. 扩展繁琐:例如新增价格降序排序时,需创建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 演示效果

排序工程策略_20260108143734_616_125

六、架构整合与工程化最佳实践

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 工程化最佳实践

  1. 策略模式应用原则
    • 当同一类业务有多种实现方案时,优先用接口定义契约,避免if-else分支判断;
    • 新增策略只需实现接口,无需修改原有代码,符合开闭原则;
    • 策略类设计为无状态,便于缓存复用(如比较器类无属性,仅含compare方法)。
  2. 工厂模式应用原则
    • 当实例化逻辑复杂或需要统一管理时,使用工厂类封装;
    • 通过枚举限定入参类型,避免字符串硬编码导致的错误;
    • 无状态策略类通过缓存复用,减少内存开销和实例化耗时。
  3. 与单例模式的配合
    • 单例负责数据的全局唯一性,策略和工厂负责业务逻辑的扩展,各司其职;
    • 排序操作基于单例数据,保证多页面/多组件排序后数据同步;
    • 单例类仅存储核心数据,页面临时状态(如当前排序值)保留在页面内部,避免内存泄漏。

七、内容总结

  1. 策略模式核心:以IGoodsComparator接口为契约,将排序规则封装为独立策略类(如PriceDescComparator),实现规则与页面解耦,新增规则仅需新增策略类,无需修改原有代码;
  2. 工厂模式核心:通过SortFactory统一管理比较器实例化逻辑,页面仅需传入SortType枚举即可调用,屏蔽底层实现细节;同时缓存无状态策略实例,提升性能;
  3. 架构整合价值:单例(数据统一)+策略(规则扩展)+工厂(实例管理)的整合,既保证商品数据全局唯一,又让排序体系具备“低耦合、高扩展”的工程化特性;
  4. 实战优化:补充商品列表空状态兜底、排序日志增强、策略实例缓存,提升代码健壮性和运行性能。

八、代码仓库

  • 工程名称:ClassObjectDemo_7
  • 代码地址:https://gitee.com/juhetianxia321/harmony-os-code-base.git

下节预告

本节课我们通过工厂+策略模式完成了商品排序体系的重构,也掌握了“类实现接口”的核心用法,但当业务场景升级,需要为商品实现多种促销规则(折扣、多档位满减、赠品、满折、会员专属优惠等)时,单纯依赖“一个类实现多个接口”的基础用法,会暴露出致命问题:

  1. 商品类职责爆炸:商品类会充斥大量促销计算逻辑,违背“单一职责原则”,代码臃肿且难以维护;
  2. 规则叠加混乱:多种促销规则的叠加顺序(如先满减后折扣/先折扣后满减)、优先级(如400-40优先于200-20)无法统一管控,易出现计算错误;
  3. 扩展成本指数级增加:新增第三种促销规则时,需让商品类实现新接口,所有调用处都要同步调整,完全违背“开闭原则”;
  4. 代码复用性差:不同商品的同类促销规则(如数码/图书都支持满200减20),无法复用同一套实现逻辑,重复代码大量滋生。

下一节,我们将跳出“单纯用类实现接口”的思维局限,通过进阶版策略模式破解多促销规则的扩展难题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1214064.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026年国内靠谱的控制台生产厂家哪家靠谱,成品操作台/化验室操作台/多联控制台/室外监控杆,控制台供应厂家哪家强

行业背景与市场趋势分析 随着智能化、数字化转型加速,控制台作为指挥中心、监控中心的核心设备,其市场需求持续攀升。从公共安全到能源管理,从交通调度到金融监控,控制台的应用场景不断拓展,对产品的稳定性、定制…

TurboDiffusion开源镜像发布:开机即用的AI视频生成解决方案

TurboDiffusion开源镜像发布&#xff1a;开机即用的AI视频生成解决方案 1. 这不是又一个“跑不起来”的视频模型&#xff0c;而是真正能用的工具 你是不是也试过下载一堆AI视频项目&#xff0c;结果卡在环境配置、依赖冲突、显存报错上&#xff1f;折腾三天&#xff0c;连第一…

Qwen vs Stable Diffusion:儿童风格图片生成部署对比评测

Qwen vs Stable Diffusion&#xff1a;儿童风格图片生成部署对比评测 1. 为什么儿童向图片生成需要专门优化&#xff1f; 给小朋友看的图片&#xff0c;不是随便画得可爱就行。它得安全、温和、色彩明亮、造型圆润&#xff0c;不能有尖锐线条、复杂背景或任何可能引发不安的元…

CosyVoice2-0.5B速度调节功能,0.5x到2.0x自由控制

CosyVoice2-0.5B速度调节功能&#xff0c;0.5x到2.0x自由控制 1. 为什么语音速度调节不是“锦上添花”&#xff0c;而是真实刚需&#xff1f; 你有没有遇到过这些场景&#xff1f; 听一段产品介绍音频&#xff0c;语速太慢&#xff0c;等得心焦&#xff1b; 做外语学习材料&a…

跨平台兼容性如何?CosyVoice2-0.5B浏览器适配实测

跨平台兼容性如何&#xff1f;CosyVoice2-0.5B浏览器适配实测 你是不是也遇到过这样的情况&#xff1a;在公司用Chrome调试得好好的语音合成效果&#xff0c;回家换台Mac打开Safari&#xff0c;界面错位、按钮点不动、录音功能直接灰掉&#xff1f;或者用Edge访问时&#xff0…

Llama3-8B语音合成联动:TTS端到端系统搭建教程

Llama3-8B语音合成联动&#xff1a;TTS端到端系统搭建教程 1. 为什么需要语音合成与大模型联动 你有没有遇到过这样的场景&#xff1a;用大模型写好了产品介绍文案&#xff0c;却还要手动复制粘贴到另一个语音工具里生成配音&#xff1f;或者在做AI教学助手时&#xff0c;模型…

教育插图神器!Z-Image-Turbo教学场景实测

教育插图神器&#xff01;Z-Image-Turbo教学场景实测 老师备课到凌晨&#xff0c;只为找一张贴切的“细胞有丝分裂动态示意图”&#xff1b;历史课需要“北宋汴京虹桥市井全景”&#xff0c;搜图结果全是现代仿建照片&#xff1b;美术老师想生成“敦煌飞天线描稿水墨渲染”风格…

小白指南:分清 USB 3.0 3.1 3.2 的命名规则

以下是对您提供的博文内容进行 深度润色与结构重构后的专业级技术博客文稿 。我以一位深耕USB协议栈多年、常驻一线做高速接口调试的嵌入式系统工程师视角,彻底摒弃AI腔调和教科书式罗列,用真实工程语言重写全文——既有“踩坑现场”的痛感,也有“拨云见日”的顿悟;既讲清…

Z-Image-Turbo行业落地挑战:大规模应用中的性能瓶颈分析

Z-Image-Turbo行业落地挑战&#xff1a;大规模应用中的性能瓶颈分析 1. UI界面初体验&#xff1a;直观、简洁、开箱即用 Z-Image-Turbo的UI界面设计走的是极简实用路线——没有花哨的动效&#xff0c;也没有层层嵌套的菜单&#xff0c;打开就是核心功能区。整个界面分为三大区…

Qwen3-Embedding-0.6B使用全攻略:图文并茂易理解

Qwen3-Embedding-0.6B使用全攻略&#xff1a;图文并茂易理解 1. 这个模型到底能帮你做什么&#xff1f; 你可能已经听说过“嵌入”这个词&#xff0c;但具体是什么&#xff1f;简单说&#xff0c;它就像给每段文字发一张独一无二的“身份证”&#xff0c;把一整段话压缩成一串…

从0开始学YOLOv10:官方镜像助你快速入门AI视觉

从0开始学YOLOv10&#xff1a;官方镜像助你快速入门AI视觉 你是否曾为部署一个目标检测模型耗费半天时间——反复安装CUDA版本、调试PyTorch兼容性、下载权重失败、环境冲突报错&#xff1f;你是否在项目截止前夜&#xff0c;还在用pip install和conda install轮番尝试&#x…

Xilinx FPGA SRIO接口Verilog源码揭秘与应用

xilinx FPGA srio 接口verilog源码程序&#xff0c;顶层接口封装为fifo&#xff0c;使用简单方便&#xff0c;已运用在实际项目上。 本源码支持srio NWRITE、NWRITE_R、SWRITE、MAINTENCE、DOORBELL等事务。 1、提供srio源码 2、提供srio license文件 3、提供操作文档 最近在项…

告别高显存!Unsloth让大模型训练更省资源

告别高显存&#xff01;Unsloth让大模型训练更省资源 你是否曾盯着GPU显存监控界面&#xff0c;看着OOM错误反复弹出&#xff0c;而训练任务才刚跑完第一个epoch&#xff1f;是否在4090上连7B模型的QLoRA微调都得小心翼翼调batch size&#xff0c;生怕一不小心就爆显存&#x…

YOLO26训练超参调优:SGD优化器实战配置

YOLO26训练超参调优&#xff1a;SGD优化器实战配置 YOLO系列模型持续进化&#xff0c;最新发布的YOLO26在精度、速度与泛化能力上实现了显著突破。但再强的模型架构&#xff0c;也离不开科学合理的训练配置——尤其是优化器这一核心组件。很多用户反馈&#xff1a;明明用了官方…

2026年边缘AI趋势分析:Qwen轻量模型部署实战

2026年边缘AI趋势分析&#xff1a;Qwen轻量模型部署实战 1. 为什么“单模型干多活”正在成为边缘AI新标配 你有没有遇到过这样的场景&#xff1a;在一台没有GPU的工控机上&#xff0c;想同时跑一个情感分析服务和一个客服对话模块&#xff0c;结果发现光是加载两个模型就占满…

Qwen3-1.7B部署难题全解,小白少走弯路

Qwen3-1.7B部署难题全解&#xff0c;小白少走弯路 你是不是也遇到过这些情况&#xff1a; 下载好了Qwen3-1.7B镜像&#xff0c;点开Jupyter却卡在“连接失败”&#xff1b; 复制了官方调用代码&#xff0c;运行报错ConnectionRefusedError或Invalid URL&#xff1b; 明明GPU显…

用GPEN给爷爷奶奶的老照片做AI修复,家人惊呆了

用GPEN给爷爷奶奶的老照片做AI修复&#xff0c;家人惊呆了 你有没有翻过家里的老相册&#xff1f;泛黄的纸页、模糊的轮廓、褪色的衣裳&#xff0c;还有那张笑得腼腆却看不清眉眼的爷爷——照片里的人还在&#xff0c;可时光的褶皱早已悄悄盖住了他们的样子。直到我试了GPEN人…

从零实现工业网关USB-serial controller驱动修复

以下是对您提供的技术博文进行 深度润色与结构重构后的专业级技术文章 。全文已彻底去除AI生成痕迹,强化工程语境、实战节奏与人类专家口吻;摒弃模板化章节标题,代之以自然递进的逻辑流;所有技术点均融入真实开发场景,并补充了大量一线调试经验、内核机制洞察与工业部署…

UNet人脸融合怎么用?科哥版WebUI详细使用手册

UNet人脸融合怎么用&#xff1f;科哥版WebUI详细使用手册 在AI图像处理领域&#xff0c;人脸融合早已不是实验室里的概念验证&#xff0c;而是真正走进内容创作、数字人制作和个性化服务的实用工具。当“换脸”不再只是娱乐噱头&#xff0c;而成为设计师快速出图、创作者批量生…

商用密码应用安全性评估备案信息表:从合规底线到安全上限的全面指南

摘要 商用密码应用安全性评估&#xff08;简称“密评”&#xff09;备案是网络安全合规的核心环节&#xff0c;而备案信息表则是这一过程的法定载体。本文深度解析密评备案信息表的法律内涵、实操要点与技术背景&#xff0c;涵盖“三同步一评估”机制、AI赋能备案、量化评估规则…