Oop OO封装-对象转换以获取;“内脏”;

Oop OO封装-对象转换以获取;“内脏”;,oop,language-agnostic,Oop,Language Agnostic,我有一个目标,在这个目标中,我试图遵循“告诉-不要问”的原则。因此,在不显示代码的情况下,我告诉对象做一些事情。这个物体是一个球,所以我有能力把球发向另一个物体。此方法将在内部调整球的速度,使其朝向发球对象 我的问题是当我希望在GUI上显示球时。为此,我需要x和y坐标,所以当我画图时,我想在球上添加一个方法来转换为DTO,这将允许我访问x和y位置 我的问题是,我可以忘记这个DTO,将属性添加到球上,然后使用它,但是这意味着球可以在不遵循我正在使用的核心逻辑的情况下进行调整 对于这种情况有什么建议

我有一个目标,在这个目标中,我试图遵循“告诉-不要问”的原则。因此,在不显示代码的情况下,我告诉对象做一些事情。这个物体是一个球,所以我有能力把球发向另一个物体。此方法将在内部调整球的速度,使其朝向发球对象

我的问题是当我希望在GUI上显示球时。为此,我需要x和y坐标,所以当我画图时,我想在球上添加一个方法来转换为DTO,这将允许我访问x和y位置

我的问题是,我可以忘记这个DTO,将属性添加到球上,然后使用它,但是这意味着球可以在不遵循我正在使用的核心逻辑的情况下进行调整

对于这种情况有什么建议吗

这里有一些伪代码来帮助可视化问题。球的DTO在球内用于管理球的内部状态,但在某些时候我需要知道球在哪里。我提出的每一种方法都违反了封装的全部要点

ball = new Ball();
ball.ServeTo(player)
// Logic, blah blah blah...
// Wish to draw now...
drawer.Draw(ball.ToDTO())
// Problem is I could easily do this
ball = ball.ToDTO()
ball.x = 100
// Just violated core logic, should not be able to move here etc...

我强烈建议读两篇文章,主题是“为什么能者和二传者邪恶”和“更多关于能者和二传者”。特别是后者提供了使用builder模式解决这个问题的方法


  • 您只能实现getter而不能实现setter来限制访问。或者,球可以通过调用某种抽签行为并进入“抽屉”使用来抽签。

    Nice。我本来打算否决这一点,因为第一个链接并不新鲜,而第二个链接有一个非常巧妙的技术(传入一个构建器),我将尝试一下。顺便说一句,我不得不修改答案来重新投票。干杯。