面向对象的设计 - 我的值对象应该只包含getter吗?

时间:2014-01-08 13:35:29

标签: java oop

在我的项目的业务逻辑中,我主要有“价值对象”“经理”

值对象无处不在。它们可以是用户,汽车,照片,专辑等。

存在

管理员来控制其价值对象。它可以是UserManager,CarManager,PhotoManager,AlbumManager等。他们使用值对象创建/删除/ getList和其他操作。

现在我遇到了一个问题:我的价值对象是否应包含 setters 我的第一个观点是,因为我觉得价值对象状态只会由他的经理控制得更好。

但是有一个不好的副本 - 代码重复和明显的双重工作。

如果没有setter,我的经理将拥有像userManager.addPhoto(userToAddTo, photoToBeAdded)这样的方法,内部调用user.addPhoto(photo)(方法addPhoto存在于实现中,但不存在于接口中)。没关系,如果只有这样的方法,但是当它获得了很多这样的“setter”方法时,经理似乎有点丑陋而且显然是双重工作。

那么,我应该在我的值对象中使用setter吗?

4 个答案:

答案 0 :(得分:1)

您的值对象是数据访问层的一部分,管理器是业务逻辑的一部分。因此,setter和getter绝对是数据访问层的一部分,而不是业务逻辑的一部分。当您不确定应该在哪个层中执行特定操作时,还必须考虑实体或业务逻辑的可重用性。

http://en.wikipedia.org/wiki/Multilayered_architecture

但要小心。您的实体应该只有以下设置者:

    /**
     * @param Name
     */
    public void setName(sName) {
        m_sName = sName;
    }

如果由于可重用性,您会对某些值执行某些特定的操作,这是业务逻辑的一部分。

答案 1 :(得分:0)

我会说“是”,我也会避免像userManager.addPhoto(userToAddTo,photoToBeAdded)这样的东西,转移到更丰富的域模型,如user.addPhoto(照片)。

我认为大多数OOD设计社区已经放下了“继续为房地产添加二传手和吸气剂”。当然,有些纯粹主义者认为你应该只管理完整的状态,但这是不切实际的。

如果你看看像C#或Groovy这样的语言,他们已经让getter和setter的想法有点过时了,依靠各种机制简单地处理直接可分配/可读的属性,并允许一些'under-the-的方法引擎盖'添加/设置逻辑:

class Person {
  String name
  String lastname

  // for some dumb reason, always 'get' upper-cased last names
  String getLastname() {
    return this.lastname.toUpperCase()
  }
}

总而言之,我赞成OO设计,其中对象代表状态业务逻辑,而不是像数据库表中的行那样简单状态的贫血反映。

我也会考虑问自己为什么要使用简单/哑元值对象。是否需要它们,例如通过电线跨越系统边界?

答案 2 :(得分:0)

事先我会说我不明白你必须在价值对象和经理对象之间分割你的设计的原因,你也可以有充分的理由这样做。在我的例子中,我总是使用自己的getter和setter方法实现数据传输对象,如果我认为我必须保护自己免受API用户的攻击;),我会尝试遵循Josh Bloch在Effective Java中建议的防御方法。

这意味着,如果我不希望API用户修改我返回的DTO,我将使用final修饰符使这些对象不可变,并在必要时返回其属性的防御性副本...必要的。与Java对字符串或整数的处理方式相同。

当然,如果你的经理做了别的事情而不是写属性,那么他们就是业务逻辑的一部分,无论你做什么都是完全合理的

答案 3 :(得分:0)

不,你的财产必须有一个设定者来设置它。当属性由其他属性组成时,将使用无setter属性。