该文章称,数据类是一个“代码味道”。原因:
当新创建的类仅包含几个公共字段(甚至可能有少数getter / setter)时,这是很正常的事情。但是对象的真正威力在于它们可以包含行为类型或对其数据的操作。
为什么对象仅包含数据是错误的?如果该类的核心职责是代表数据,那么添加对数据进行操作的方法是否会违反“ 单一职责原则”?
该文章称,数据类是一个“代码味道”。原因:
当新创建的类仅包含几个公共字段(甚至可能有少数getter / setter)时,这是很正常的事情。但是对象的真正威力在于它们可以包含行为类型或对其数据的操作。
为什么对象仅包含数据是错误的?如果该类的核心职责是代表数据,那么添加对数据进行操作的方法是否会违反“ 单一职责原则”?
Answers:
拥有纯数据对象绝对没有错。坦率地说,这本书的作者不知道他在说什么。
这种想法源于一个古老的,失败的想法,即“真正的OO”是最好的编程方式,而“真正的OO”则是关于“丰富的数据模型”的,其中混合了数据和功能。
事实表明,事实恰恰相反,尤其是在这个多线程解决方案领域。纯函数与不可变的数据对象相结合,是一种更好的编码方式。
拥有纯数据对象绝对没有错。作者的观点未与我认识的软件开发人员共享。
特别是对于数据库映射,您通常具有实体类,这些实体类仅包含存储在数据库中的字段以及getter和setter。维基百科休眠(框架)
许多工具/框架使用的Java bean漏洞概念都是基于称为bean的数据类,这些数据类仅包含字段以及相关的getter和setters。Wikipdia JavaBeans
Fazit:
如果有人声称某些东西“不好”或“有代码气味”,则应始终查找给出的原因。如果原因不能说服您,请向其他人询问更好的原因或其他意见。(就像您在此论坛中所做的一样)
马丁·福勒(Martin Fowler)的一个很好的论点为何:
“不要问这个原则,可以帮助人们记住面向对象是将数据与对该数据进行操作的功能绑定在一起。它提醒我们,我们不向对象索要数据并对该数据进行操作,而是而是应该告诉对象该怎么做。这鼓励将行为转移到对象中以与数据一起使用。”
baz
参数作为参数传递给静态方法,但是要做到这一点,您首先需要向对象询问。也许在方法是主要方法的编程范例中(例如函数式编程),这是有道理的,但是在OO环境中,绝对没有意义,因为对象是主要方法,并且应同时包含数据和作用于其上的功能。据我所知,您声称从对象中删除方法会增加封装,这也恰恰是倒退,因为这意味着您现在已经baz
出现在对象外部。
您需要了解的是,有两种对象:
有行为的对象。这些应避免公开访问其大多数/任何数据成员。我希望只为这些定义的访问器方法很少。
一个示例就是一个已编译的正则表达式:创建该对象是为了提供某种行为(将字符串与特定的正则表达式进行匹配,并报告(部分)匹配项),但是编译后的正则表达式如何执行其工作与用户无关商业。
我写的大多数类都属于此类。
对象实际上只是数据。这些应仅将其所有成员声明为公共(或为他们提供完整的访问器集)。
一个例子是一个类Point2D
。绝对不需要为此类的成员确保不变,并且用户应该能够仅通过myPoint.x
和访问数据。myPoint.y
。
就我个人而言,我并没有太多使用此类,但我想我没有编写更大的代码来在某个地方不使用此类。
精通面向对象包括意识到存在这种区别,并学习将类的功能归为这两类之一。
如果使用C ++编写代码,则可以通过class
对第一类对象和struct
第二类对象使用来明确区分。当然,两者是等效的,除了那class
意味着默认情况下所有成员都是私有的,而默认情况下则将struct
所有成员声明为公共。这正是您想要传达的信息。