引言

在之前的课程中,我们已经系统学习了 ArkTS 面向对象编程的核心知识。本节课将通过一个完整的智能家居遥控案例,将接口、抽象类、继承、多态等知识串联起来,展示如何在实际开发中运用面向对象的分层架构设计,解决多设备系统中的规范、复用与扩展问题。

核心内容

需求分析:智能家居遥控系统核心需求

本案例要实现的智能家居遥控系统包含三种核心设备:灯、空调、门锁,功能支持按位置筛选展示对应设备。

设备共性:所有设备都包含名称、类型、位置、状态四种共有属性,都需要"打开"和"关闭"两种通用操作。

设备差异:灯支持设置亮度,空调支持设置温度,门锁仅需要开关锁,没有额外个性化参数。

核心业务需求

需求类型 具体要求
兼容多设备 系统需稳定接入灯光、空调、智能锁等多种设备,并支持后续新增设备
统一操作规范 所有设备遵循一致操作逻辑,降低开发协作成本与用户学习成本
功能完整性 既要覆盖所有设备的共性基础功能,也要支持各设备的个性化专属功能
灵活扩展 新增设备或修改功能时,最小化对现有系统的影响,提升迭代开发效率

系统整体分层架构设计

如果不做分层设计,直接针对每个设备写代码,会出现命名混乱、共性逻辑重复编写、特殊功能与共性逻辑耦合等问题,后续修改维护难度大、容易出错。为解决这些问题,系统整体分为四个核心层级:

设备接口 → 实现 → 设备抽象类 → 继承 → 设备子类 → 被调用 → 设备UI组件
层级 核心职责
设备接口 定义统一规范:设备唯一标识、名称、类型、安装位置属性,以及开机、关机通用方法
设备抽象类 实现接口,补充所有设备通用的状态属性和获取状态、设备信息的方法,封装共性逻辑
设备子类 针对灯、空调、智能锁分别创建子类,继承抽象类,仅实现自身专属的个性化功能
设备UI组件 提供可视化交互界面,接收用户操作并调用对应设备的方法,同步状态展示

第一层:设备接口设计

核心价值:解决规范混乱问题,定规则立标准,不负责具体逻辑实现,仅强制所有设备遵守统一规范。

设计要点

  1. 明确核心属性:要求所有设备必须包含唯一标识、名称、安装位置、设备类型等基础属性,保证设备可区分可定位。

  2. 明确核心方法:强制统一方法命名(如统一用 turnOn 表示开机),避免 open/start 等多种命名混乱。

  3. 约束开发边界:从源头避免混乱,降低团队协作和后续维护成本。

代码定义

export interface IDevice {
    id: string;
    name: string;
    type: DeviceType;
    location: Location;

    turnOn(): Promise<void>;
    turnOff(): Promise<void>;
}

第二层:设备抽象类设计

核心价值:解决共性冗余问题,抽共性做复用,实现接口的共性逻辑让子类继承复用,避免重复编码。

设计要点

  1. 必须完整实现设备接口定义的所有核心属性和共性方法,符合统一规范。

  2. 封装所有设备通用逻辑:如开机更新状态、关机记录日志、获取设备信息等,统一写在抽象类中。

  3. 提供复用基础:子类无需重复编写共性代码,修改共性逻辑仅需修改抽象类一处即可全局生效。

代码定义

export abstract class Device implements IDevice {
    id: string = '';
    name: string = '';
    type: DeviceType = DeviceType.Light;
    location: Location = Location.Default;
    protected status: 'on' | 'off' = 'off';

    constructor(id: string, name: string, type: DeviceType, location: Location) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.location = location;
    }

    getStatus(): 'on' | 'off' {
        return this.status;
    }

    // 抽象方法:子类必须实现
    abstract turnOn(): Promise<void>;
    abstract turnOff(): Promise<void>;

    // 通用方法
    getInfo(): string {
        return `${this.name} (${Location[this.location]} 位置的 ${DeviceType[this.type]} 设备)`;
    }
}

第三层:设备子类设计

核心价值:解决差异冲突问题,继承复用共性代码,专注实现自身专属功能,隔离差异避免冲突。

设计要点

  1. 每个具体设备对应一个子类,全部继承自设备抽象类,直接拥有所有共性属性和方法。

  2. 子类无需关注共性逻辑,仅需专注实现自身特殊功能:如灯光调亮度、空调调温度、智能锁密码验证。

  3. 差异逻辑完全隔离,修改某类设备的特殊功能不会影响其他设备和共性逻辑。

代码示例:智能锁子类

import { DeviceType, Location } from '../common/types';
import { Device } from './Device';
import { delay, logAction } from '../utils/DeviceUtils';

export class SmartLock extends Device {
    constructor(id: string, name: string, location: Location) {
        super(id, name, DeviceType.Lock, location);
    }

    async turnOn(): Promise<void> {
        try {
            await delay(300); // 模拟设备响应延迟(如蓝牙连接、云端校验)
            this.status = 'on';
            logAction(`${this.getInfo()} 已开锁`);
        } catch (error) {
            console.error(`error: ${(error as Error).message}`);
        }
    }

    // turnOff 方法实现省略
}

第四层:UI 界面实现

核心逻辑:使用 ArkTS 声明式 UI 框架,UI 组件接收设备对象,实现 UI 状态与设备状态的联动,用户操作直接调用设备对应方法。

代码示例:智能锁卡片

@Component
export struct LockView {
    @ObjectLink device: Device; // 接收父类对象
    @State lock: SmartLock = this.device as SmartLock;

    build() {
        Column() {
            // 状态显示区域
            Text(this.lock.name)
            // ...

            Toggle({ type: ToggleType.Switch, isOn: this.lock.status === 'on' ? true : false })
                .onChange((isOn: boolean) => {
                    if (isOn) {
                        this.lock.turnOn();
                    } else {
                        this.lock.turnOff();
                    }
                })
            // ...
        }
    }
}

总结

本智能家居开发案例的核心是,使用面向对象的接口、抽象类、继承知识,分别解决规范、复用和差异问题:

  1. 接口负责定规范:让所有模块按规则协作,降低耦合,从源头解决命名和方法混乱问题。

  2. 抽象类负责抽共性:封装所有设备的通用逻辑,减少重复代码,便于统一修改,修改一处即可全局生效。

  3. 子类通过继承实现扩展:专注实现自身差异逻辑,差异逻辑完全隔离,修改某类设备不影响其他模块。

这套设计思路不局限于智能家居开发,任何包含多种相似模块的系统开发,都可以复用这套"定规范、抽共性、兼容差异"的设计思路。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐