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

使用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) { ... }
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • 【Groovy】Groovy 方法调用 ( Java 类成员及 setter 和 getter 方法设置 | Groovy 类自动生成成员的 getter 和 setter 方法 )

    文章目录 一、Java 类成员及 setter 和 getter 方法设置 二、Groovy 类自动生成成员的 getter 和 setter 方法 一、Java 类成员及 setter 和 getter...方法设置 ---- 创建标准的 Java 类 , 需要将成员变量设置为私有成员 , 并且为其定义 getter 和 setter 方法 ; class Student { private String...class Student { def name def age } 在 Groovy 中的类中 , 不需要定义成员变量的 setter 和 getter 方法 , Groovy 会自动生成相关的...(18) // 使用 getter 方法获取成员值 println student.getName() println student.getAge() 执行结果 : Tom 18 查看编译后的 Student.class...字节码文件 , 可以看到系统为 Student 类自动生成了 getter 和 setter 方法 ; 完整的字节码类如下 : // // Source code recreated from

    1.7K30

    盘点JavaScript中getter()和setter()函数的使用

    它们本质上是用于获取和设置值的函数,但从外部代码来看就像常规属性。 二、Getter 和 setter 访问器属性由 “getter” 和 “setter” 方法表示。...四、更聪明的 getter/setter Getter/setter 可以用作“真实”属性值的包装器,以便对它们进行更多的控制。...五、兼容性 访问器的一大用途是,它们允许随时通过使用 getter 和 setter 替换“正常的”数据属性,来控制和调整这些属性的行为。...六、总结 本文基于JavaScript基础,介绍了getter 和 setter函数的使用。对于其中的属性,通过案例的样式,运行效果图的展示,进行详细的讲解。...同时拓展相对于的内容,希望能够帮助你更好的理解。 欢迎大家积极尝试,有时候看到别人实现起来很简单,但是到自己动手实现的时候,总会有各种各样的问题,切勿眼高手低,勤动手,才可以理解的更加深刻。

    2.1K11

    TW洞见〡getter和setter的那些事

    这些以get和set开头的方法,被称为getter和setter。时间久了,这种做法似乎成了一种神圣的约定,每个人都记得应该这么写,而忘记了为什么这么写。...但是,当你写了很多程序,写过很多getter和setter,尤其是有些类方法,只有getter和setter时,总会有一天,你会疑惑,我到底为什么要这么干? Why private field?...要解释为什么需要getter和setter,先要知道为什么字段应该是private的。 在汇编语言时,数据都是公开的。所谓公开,是指几乎任何指令,都可以作用在任意的数据块上。...如果采用文章开始时的代码,即添加getter和setter,有新需求出现时,只需修改getName方法,不需要修改调用处的代码,即可实现。...不过,因为这只是通过注解做的一种Hack,加了@Data注解,相当于编译器自动生成getter和setter,所以调用代码还是要用getId和getName这样的方法名来访问变量。

    1.1K60

    寻找性能更优秀的动态 Getter 和 Setter 方案

    方案说明 就是用表达式编译一个 Action 作为 Setter,编译一个 Func 作为 Getter。...然后把这些编译好的委托放在一个泛型类的静态字段中保存起来,需要使用的时候从这里面查找就可以了。...知识要点 使用表达式创建委托 泛型类的静态字段是每个闭合类型独立的,因此用于存储和类型相关的内容非常方便 实现代码 由于代码中混合的使用 Switch 作为字典的阴招,所以代码很长,此处不再罗列,仅给出链接...如果属性是明确的,建议把字典中取出来的委托保存在自己的上下文,这可以明显的省去查找的消耗。 图表 从左往右分别是:直接读取属性、缓存委托、不缓存委托和使用 PropertyInfo。...0.1.4 发布,初始版本 使用样例 Newbe.ObjectVisitor 样例 1 番外分享 寻找性能更优秀的动态 Getter 和 Setter 方案 寻找性能更优秀的不可变小字典 GitHub

    69100

    【Kotlin】类的初始化 ① ( 成员属性 | Kotlin 自动为成员字段生成 getter 和 setter 方法 | 手动设置成员的 getter 和 setter 方法 | 计算属性 )

    文章目录 一、Kotlin 自动为成员字段生成 getter 和 setter 方法 二、手动设置成员的 getter 和 setter 方法 三、计算属性 一、Kotlin 自动为成员字段生成 getter...Java 代码中 , 存在 name 和 age 成员的 getter 和 setter 函数 ; 调用 hello.name 方法 , 实际上调用的是 hello.setName 方法 ; class...结果 如下 : 二、手动设置成员的 getter 和 setter 方法 ---- Kotlin 会为 类中的每个 成员属性 生成一个 field , getter , setter ; field...用于存储 属性数据 , 是由 Kotlin 自动进行定义封装的 , 只有在 getter 和 setter 函数中才能调用 field ; 手动定义 getter 和 setter 方法示例 : class...某个属性 是 通过计算得到的 , 可以 在该属性的 getter 和 setter 方法中进行计算设置或获取结果 , 不使用 field 属性 ; 下面的 age 属性就是通过计算得到的属性值 , 每次获取都是

    3K20

    别再写getter,setter方法了,用Lombok来简化你的代码吧

    ,ide会识别不到,会提示你getter,setter等方法没有定义。...Lombok常用注解 1.Data注解 该注解作用在类上,默认为类生成get 、 set、equals、hashCode、toString 等方法。...Data注解标识在类上,我们可以通过ide的自动补全功能查看Data注解为我们实现了哪些方法: 可以看到,get 、 set、equals、hashCode、toString 这些pojo必备的方法都已经实现了...2.Setter注解 有些类不需要getter方法,那么我们可以单独使用setter注解来标识。...通过ide的自动补全功能,可以看到为我们实现了getter方法 3.Getter注解 有些类只提供getter返回,不允许外部设置属性值,这时候可以使用getter注解。

    23210

    java里getter和setter的作用和区别是什么?

    java是典型的面向对象的编程语言,面向对象三个特性,继承性,多态性,封装性,主要和封装性考虑,类里面的变量不想设置成公共的类型,但是还要给外部使用在这种实用场景下,从编程技巧上加上方法来获取或者设置参数值...,于是getter和setter就使用上了。...增加两个方法保证了类结构的完整性以及安全性还是非常合算的做法,其实从框架上考虑增加这两个方法还能在实际编程过程中增加额外的功能作用,现在就根据实际编程中的经验做一些总结归纳: 1.可以通过setter方法检查下数据的准确性...,比如是否越界之类的异常等等 2.可以在setter方法里面加上一些功能函数,主要在限定一些条件如果数值达到一定范围之后就开始做某些动作,选择的时机点正好在这个方法里面。...3.加入涉及到多线程的操作,在setter方法里面正好做加锁的操作,正好是一个恰当的时机 4.由于是关键数值的变化,在这两个方法中加上打印非常适合追踪数据的变化,方便程序的判断。

    2.1K30

    fastjson:JavaBeanInfo无法正确解析setter方法的问题分析

    https://blog.csdn.net/10km/article/details/88941314 最近在使用fastjson做Java bean的序列化和反序列化时遇到一个小问题:.../getter方法,B为A的子类,重写了setValue方法。...从上面的setValue的返回值不是void可知这个写法不是标准java bean的setter方法(标准java bean要求setter方法返回为void)。...fastjson是支持这种非标准的setter方法的。 实际测试过程中A的实例可以正确序列化和返回序列化,但B的实例在反序列化过程中没有对value字段进行解析,也就是说把value字段给丢了!...所以对于B而言父类中的setValue方法以及自己类中重写的setValue方法因为返回类型问题在这里都被fastjson判断为非setter方法给跳过了,所以后续的反序列化过程中自然就没有value字段

    1.3K30

    构造函数和使用一个个 setter 的效率哪个好??

    ,使用 JProfiler 看代码的时间占比,然后,看看哪些部分是可以优化的,减少运行时间的。...1,能使用构造函数一步到位的,就尽量使用构造函数,而不是使用一个个 setter 函数 2,能使用数组的,就使用数组。替代 list,数组是真的快。...3,for 循环的时候,使用 for i 循环针对lsit接口的集合,不使用 for each 循环。for i 循环的时候,把 length 的值提到 for 循环之外。...4,有些变量能提出来的,取一次,多次使用。不要频繁的 get 。即使是一个简单的 int 值。 5,要是能使用内部类的话,可以使用内部类,这样可以省去 getter,setter 方法的使用。...6,json 的序列化和反序列化,不要说理论上是 fastjson 快,就使用 fastjson ,因为针对数据结构的简单复杂程度,来选择使用什么去序列化和反序列化,要实际测试之后,再说话。

    1.1K20

    Java代码优化:使用构造函数和使用一个个setter的效率差别

    能使用构造函数一步到位的,就尽量使用构造函数,而不是使用一个个setter函数 2. 能使用数组的,就使用数组。替代list,数组是真的快。...3. for循环的时候,使用for i循环针对list接口的集合,不使用for each 循环。for i循环的时候,把length的值提到for循环之外。 4....有些变量能提出来的,取一次,多次使用。不要频繁的get。即使是一个简单的int值。 5. 要是能使用内部类的话,可以使用内部类,这样可以省去getter,setter方法的使用。...6. json的序列化和反序列化,不要说理论上是fastjson快,就使用fastjson,因为针对数据结构的简单复杂程度,来选择使用什么去序列化和反序列化,要实际测试之后,再说话。...使用的Lombok的注解。 然后是JProfiler监测结果 ?

    1.2K20

    JMX in action第二篇

    一,DynamicMBean 其实一看到Dynamic这个词就基本上确定了,就是反射那一套,不外乎属性获取,设定,方法调用等等,但是这个在使用中是至关重要的,因为现有系统如果都想把接口改造成符合...Standard MBean方式的,不太现实,而利用DynamicMBean,通过反射将需要管理的Bean动态生成,对现有系统减少侵入性,也减少了问题产生的可能。...,是的Server可以不用去区分我们的实现而用统一的方式去管理MBean 来看看MBeanInfo拥有的属性: private transient Descriptor descriptor;...DynamicMBean并没有什么神秘的,关键还是使用这个接口的方式,如果对于每一个类都实现这个接口,然后构造一大堆类的元数据,也是挺痛苦的一件事,JIA提供了一个DynamicMBeanSupport...,因为暴露的方法其实还是硬编码在了子类中 tomcat提供了一种配置方式来暴露,使用一个mb ean-descriptor,将需要暴露的方法属性写到里面,用xml digest解析出来,比较直观,在我看来是一种更好的办法

    40330

    重回iOS应用开发

    在重新熟悉ObjectC语法的过程中,有几个点之前关注的不多,记录下: 一、Protocol可以用@property形式声明属性,只不过在Protocol中声明的属性,只有对应的setter/getter...@synthesize 的作用:是为属性添加一个实例变量名,或者说别名。同时会为该属性生成 setter/getter 方法。...2.禁止@synthesize:如果某属性已经在某处实现了自己的 setter/getter ,可以使用 @dynamic 来阻止 @synthesize 自动生成新的 setter/getter 覆盖...3.内存管理:@synthesize 和 ARC 无关。 4.使用:一般情况下无需对属性添加 @synthesize ,但一些特殊情形仍然需要,例如protocol中声明的属性。...二、如何进行UI模块跳转与管理 1、直接跳转: #模态跳转:一个普通的视图控制器一般只有模态跳转的功能,这个方法是所有视图控制器对象都可以用的。

    55020
    领券