首页
学习
活动
专区
圈层
工具
发布

使用setter上的Action管理getter/setter的更好方法

在面向对象编程中,通过 setter 上的 Action 管理 getter/setter 是一种提升代码可维护性和灵活性的设计模式。以下是完整的解析:

基础概念

  1. Getter/Setter 用于封装属性访问,通过方法控制读写逻辑(如验证、计算、副作用等)。
  2. Getter/Setter 用于封装属性访问,通过方法控制读写逻辑(如验证、计算、副作用等)。
  3. Action 模式setter 的逻辑委托给独立的 Action 类/函数,实现解耦和复用。

优势

  • 单一职责setter 仅负责赋值,逻辑由 Action 处理。
  • 可扩展性:动态替换或组合 Action(如验证、日志、通知)。
  • 测试友好Action 可独立单元测试。
  • 复用性:同一 Action 可用于多个属性的 setter

实现方法

1. 函数式 Action(推荐)

代码语言:txt
复制
type SetterAction<T> = (value: T) => T | void;

class Product {
  private _price: number = 0;

  set price(value: number) {
    this._price = applyPriceActions(value, [validatePrice, logPriceChange]);
  }

  get price(): number { return this._price; }
}

// 定义 Action
const validatePrice: SetterAction<number> = (value) => {
  if (value < 0) throw new Error("Price cannot be negative");
  return value;
};

const logPriceChange: SetterAction<number> = (value) => {
  console.log(`Price updated to ${value}`);
};

// 执行 Action 链
function applyPriceActions(value: number, actions: SetterAction<number>[]): number {
  return actions.reduce((val, action) => action(val) ?? val, value);
}

2. 面向对象 Action

代码语言:txt
复制
interface SetterAction<T> {
  execute(value: T): T;
}

class DiscountAction implements SetterAction<number> {
  execute(price: number): number {
    return price * 0.9; // 10% 折扣
  }
}

class Product {
  private _price: number = 0;
  private actions: SetterAction<number>[] = [new DiscountAction()];

  set price(value: number) {
    this._price = this.actions.reduce((val, action) => action.execute(val), value);
  }
}

应用场景

  1. 复杂验证(如跨字段校验、异步验证)。
  2. 副作用管理(如数据库同步、消息通知)。
  3. 动态行为(运行时切换 Action 逻辑)。
  4. AOP 编程(如日志、性能监控)。

常见问题与解决

问题1:Action 执行顺序冲突

  • 原因:多个 Action 依赖特定顺序(如先验证后计算)。
  • 解决:显式定义优先级或使用中间件链(如 Redux 中间件模式)。

问题2:性能开销

  • 原因:频繁创建 Action 实例或复杂逻辑。
  • 解决:缓存 Action 实例或用纯函数替代类。

问题3:循环依赖

  • 原因Action 内部调用 setter 导致栈溢出。
  • 解决:通过标志位避免递归,或拆分逻辑到 getter

总结

通过 Action 管理 setter 将业务逻辑与数据操作分离,适合中大型项目。优先选择函数式实现以减少样板代码,结合装饰器(如 TypeScript/Java)可进一步简化:

代码语言:txt
复制
@action([validatePrice, logPriceChange])
set price(value: number) { ... }
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

没有搜到相关的视频

领券