Oop OO编码-是否使用对象管理器?

Oop OO编码-是否使用对象管理器?,oop,domain-driven-design,Oop,Domain Driven Design,关于建筑风格,我想听听你的意见: 我的ORM给了我一个用户对象,它对应于我系统的一个用户。我想开发一系列处理用户的方法——GetByUsername()、Authenticate()、VerifyLoginPassword()等等。但我觉得其中一些方法并不真正属于用户类——例如GetByUsername()至少感觉像是用户的静态方法,但如果有另一个类,比如“UserManager”,会不会更“干净”哪些为我们提供了这些用户管理类型的任务?用户实例包含Authenticate()方法似乎有点奇怪,

关于建筑风格,我想听听你的意见:

我的ORM给了我一个用户对象,它对应于我系统的一个用户。我想开发一系列处理用户的方法——GetByUsername()、Authenticate()、VerifyLoginPassword()等等。但我觉得其中一些方法并不真正属于用户类——例如GetByUsername()至少感觉像是用户的静态方法,但如果有另一个类,比如“UserManager”,会不会更“干净”哪些为我们提供了这些用户管理类型的任务?用户实例包含Authenticate()方法似乎有点奇怪,例如,如果是安全系统进行身份验证

我担心的是,我最终遵循这个模型,用户类只不过是一个结构,而我的用户管理器和安全管理器类实际上完成了所有的方法工作。让所有这些管理器类操作轻量级对象感觉不是很“OO”


任何关于这一哲学问题的想法或与现有技术的链接都将不胜感激

您描述的情况与对象是否遵循自服务或适配器模式保存到存储库(即数据库)有关

自助服务将使对象将“自身”保存为
myObjectInstance.save()
,而适配器模式将为
myObjectAdapter.save(myObjectInstance)


适配器表单经常受到青睐,因为它可以从对象中删除任何存储库功能。

Martin Fowler有一些有用的方法

基本的选择是在服务定位器和依赖注入之间。第一点是,这两种实现都提供了原始示例中缺少的基本解耦——在这两种情况下,应用程序代码都独立于服务接口的具体实现。这两种模式之间的重要区别在于如何将实现提供给应用程序类。对于服务定位器,应用程序类通过给定位器的消息显式地请求它。使用注入时,没有显式的请求,服务出现在应用程序类中-因此控制反转

控制反转是框架的一个常见特性,但它是有代价的。当您尝试调试时,它往往很难理解并导致问题。所以总的来说,除非我需要它,否则我宁愿避免它。这并不是说这是一件坏事,只是我认为它需要证明自己,而不是更直接的选择


听起来你已经超越了将对象定义为“狗就是动物”的定义,转而将对象定义为角色、责任和行为

我推荐这本书,以帮助您实现这一转变,并真正“实现它”:


我对你的特定问题没有答案,因为这是一个基本的设计决定,你真的应该了解“更大的图景”。这本书将给你在责任驱动设计的原理和技术方面打下良好的基础。

你可以继续重构你的用户类中的所有功能。但正如你所说的,你可能会一无所有。此时,您可以选择评估您创建的所有其他类,然后对这些类中的每一个做出单独的判断,根据具体情况决定这些类是否包含足够的功能来保证一个全新的类

如果您确定其中一些类太小,那么可以将它们的功能放回用户类中。例如,我认为在用户上有一个Validate函数,而不是一个只有一个方法的UserValidation类没有什么错

让所有这些管理器类操作轻量级对象感觉不是很“OO”


我不知道这是否是非常“OO”,但对我来说,这感觉非常MVC和关注点分离。拥有非常轻量级的业务类(在这一点上,它们只是数据容器)和移动它们的存储库对象是一种常见的模式。

如果你说这些方法可能不属于用户对象,我认为你是在赚钱。Get/Search/Save方法可以讨论,但我认为它们不应该在业务对象本身上,应该使用存储库(存储库模式)来完成,或者如果您不希望在存储库中抽象出ORM,可以通过


就身份验证而言,最好有一组类,由用户负责身份验证,而不让用户对象进行身份验证。这组类可以知道用户对象,或者更好的是,它们应该知道诸如凭证之类的契约

我喜欢用另一种方式来表达。这些方法并不真正属于这个领域,因为不涉及业务逻辑。我想使用命令和查询分离原则

GetByUsername()--这是一个真正不需要任何业务逻辑的查询


Authenticate()、VerifyLoginPassword()--这些是不应该在域中执行的验证逻辑。请参阅此文档

为什么称之为适配器?它与这个适配器模式有什么共同之处吗?