You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构造函数中调用传入对象的Getter初始化类属性是否符合最佳实践?

类A两种设计方案的最佳实践分析

问题背景

我有一个类A,其属性是类B和类C的属性子集:C的少量属性在构造函数中直接赋值,而B的属性较多,因此我在A的构造函数中传入B对象,调用其Getter方法为A的x、y、list属性赋值,代码如下:

public class A {

    private int x;
    private int y;
    private List<> list;

    public A(B b) {
        this.x = b.getX();
        this.y = b.getY();
        this.list = b.getList();
    }
}

public class B {

    private int x;
    private int y;
    private int z;
    private String string;
    private Set<> set;
    private List<> list;

//constructor, setters and getters
}

同事建议改为让A直接持有B对象,代码如下:

public class A {
  
    private B b;

    public A(B b) {
        this.b=b;
    }

}

但这种方案需要将现有代码中的a.getX()重构为a.getB().getX()、a.getList()重构为a.getB().getList(),改动量很大。

我想了解这两种方案哪种符合最佳实践及原因:我认为自己的做法可避免使用A的对象与B的类结构耦合;同事则担忧构造函数传入B仅调用其Getter的做法存在问题。

补充场景:B和C是对应两张关联表的Entity类,A用于其他业务逻辑,且A是在HQL查询中构造的,使用工厂模式将B转为A不可行。


方案分析与结论

核心差异

两种方案的本质区别是:数据复制(你的方案) vs 依赖持有(同事的方案)

你的方案:数据复制,解耦结构

优势

  • 完全解耦A与B:A只暴露自身业务需要的属性,外部调用者无需知晓B的存在。后续B的属性名称、Getter方法变更时,只需调整A的构造函数,不会影响大量调用A的业务代码。
  • 符合单一职责:A作为特定业务的载体,仅保留必要属性,避免外部通过A访问B中无关的属性(如z、string、set),职责清晰。
  • 适配HQL场景:HQL中可直接通过构造函数传入B对象或其属性实例化A,无需额外转换逻辑,契合当前技术限制。

潜在问题与优化

  • 手动赋值代码冗余:若后续B需要传递给A的属性增多,构造函数会变长。可通过Bean映射工具(如Spring BeanUtils.copyProperties(b, this))简化,减少手动代码的出错概率。
  • 数据同步问题:如果B的属性后续更新,A中的复制值不会自动同步,但结合场景(A是HQL查询结果),这反而能保证数据快照的一致性,是合理的。

同事的方案:持有B对象,复用属性

优势

  • 代码简洁:无需重复定义属性和赋值逻辑,直接复用B的Getter方法。
  • 自动同步数据:若B的属性值更新,A通过getB()获取的属性会同步变化,但这在查询快照场景下是缺点,会导致数据不一致。

严重问题

  • 强耦合违反迪米特法则:A的调用者必须依赖B的类结构,后续B的任何变更都会直接影响所有调用a.getB().xxx()的代码,维护成本极高。
  • 职责模糊:A沦为B的包装器,失去了作为特定业务载体的意义,外部可通过A访问B的所有属性,增加业务逻辑混乱的风险。
  • 改动成本过高:现有大量a.getX()等调用需改为a.getB().getX(),改动量巨大且无对应收益。

最终结论

你的方案更符合最佳实践,原因如下:

  1. 适配当前HQL构造的技术限制,工厂模式不可行时,直接复制属性是最合理的实现方式。
  2. 遵循单一职责与迪米特法则,降低A与B的耦合,后续维护成本更低。
  3. 保证业务代码的稳定性,外部调用A的代码无需关注B的内部结构。

针对同事的担忧,可通过引入Bean映射工具优化构造函数的手动赋值逻辑,同时在A的类注释中明确其业务载体的定位,避免后续维护误解。


内容的提问来源于stack exchange,提问作者pillow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:15:40