OOP背后的基本思想是数据和行为(基于数据)是不可分割的,并且它们与类对象的思想联系在一起。对象具有与之配合使用的数据和方法(以及其他数据)。显然,根据OOP的原理,仅仅是数据的对象(如C结构)被视为反模式。
到现在为止还挺好。
问题是我注意到我的代码最近朝着这种反模式的方向发展。在我看来,我越努力实现隐藏在类与松散耦合设计之间的信息,我的类就越成为纯数据无行为类和所有行为无数据类的混合。
我通常以一种使类对其他类的存在的意识最小化并且对其他类的接口的知识最小化的方式设计类。我特别以自上而下的方式执行此操作,较低级别的类不了解较高级别的类。例如:
假设您有一个通用的纸牌游戏API。你上课了Card
。现在,该Card
课程需要确定玩家的可见度。
一种方法是有boolean isVisible(Player p)
对Card
类。
另一种是有boolean isVisible(Card c)
对Player
类。
我特别不喜欢第一种方法,因为它将有关较高级别的知识授予Player
较低级别的知识Card
。
取而代之的是,我选择了第三个选项,在该选项中,我们有一个Viewport
类,给定一个,Player
并且卡片列表确定了哪些卡片是可见的。
然而这种做法剥夺了两个Card
和Player
一个可能的成员函数的类。一旦完成了除卡片可见性之外的其他工作,就剩下了Card
和Player
类,它们仅包含数据,因为所有功能都是在其他类中实现的,这些类大多是没有数据的类,只是Viewport
上面的方法。
这显然与OOP的主要思想背道而驰。
哪种方法正确?我应该如何进行最小化类相互依赖性和最小化假定的知识和耦合的任务,而又不会陷入怪异的设计中,其中所有低层类仅包含数据,而高层类包含所有方法?是否有人对类设计有任何第三种解决方案或观点可以避免整个问题?
PS这是另一个例子:
假设您的类DocumentId
是不可变的,只有一个BigDecimal id
成员和该成员的吸气剂。现在,您需要在某处有一个方法,该方法会从数据库中获得该ID 的DocumentId
返回值Document
。
你呢:
Document getDocument(SqlSession)
在DocumentId
类中添加方法,突然介绍有关您的persistence("we're using a database and this query is used to retrieve document by id"
),用于访问数据库的API等知识。现在,此类也需要持久性JAR文件才能进行编译。- 使用method添加其他类
Document getDocument(DocumentId id)
,将DocumentId
类保持为无效,无行为,类似于结构的类。