gpt4 book ai didi

java - 测试驱动开发中如何避免访问器?

转载 作者:太空狗 更新时间:2023-10-29 22:56:59 25 4
gpt4 key购买 nike

我正在学习测试驱动开发,我注意到它强制松耦合对象,这基本上是一件好事。然而,这有时也迫使我为我通常不需要的属性提供访问器,而且我认为 SO 上的大多数人都同意访问器通常是糟糕设计的标志。在进行 TDD 时这是不可避免的吗?

下面是一个例子,没有TDD的实体的简化绘图代码:

class Entity {
private int x;
private int y;
private int width;
private int height;

void draw(Graphics g) {
g.drawRect(x, y, width, height);
}
}

实体知道如何绘制自己,这很好。都在一个地方。然而,我正在做 TDD,所以我想检查我的实体是否被我即将实现的“fall()”方法正确移动。下面是测试用例的样子:

@Test
public void entityFalls() {
Entity e = new Entity();
int previousY = e.getY();
e.fall();
assertTrue(previousY < e.getY());
}

我必须查看对象的内部(嗯,至少在逻辑上)状态并查看位置是否已正确更新。因为它实际上是在路上(我不希望我的测试用例依赖于我的图形库),我将绘图代码移动到类“Renderer”:

class Renderer {
void drawEntity(Graphics g, Entity e) {
g.drawRect(e.getX(), e.getY(), e.getWidth(), e.getHeight());
}
}

松散耦合,很好。我什至可以将渲染器替换为以完全不同的方式显示实体的渲染器。但是,我必须公开实体的内部状态,即所有属性的访问器,以便渲染器可以读取它。

我觉得这是 TDD 特意强制的。我该怎么办?我的设计可以接受吗? Java 是否需要 C++ 中的“friend”关键字?

更新:

感谢您迄今为止提供的宝贵意见!但是,我担心我选择了一个不好的例子来说明我的问题。这是完全编造的,我现在将演示一个更接近我的实际代码的代码:

@Test
public void entityFalls() {
game.tick();
Entity initialEntity = mockRenderer.currentEntity;
int numTicks = mockRenderer.gameArea.height
- mockRenderer.currentEntity.getHeight();
for (int i = 0; i < numTicks; i++)
game.tick();
assertSame(initialEntity, mockRenderer.currentEntity);
game.tick();
assertNotSame(initialEntity, mockRenderer.currentEntity);
assertEquals(initialEntity.getY() + initialEntity.getHeight(),
mockRenderer.gameArea.height);
}

这是一个基于游戏循环的游戏实现,其中实体可能会掉落等。如果它落地,就会创建一个新实体。

“mockRenderer”是接口(interface)“Renderer”的模拟实现。这种设计部分是被 TDD 强制的,但也因为我将在 GWT 中编写用户界面,并且浏览器中没有显式绘图(目前),所以我认为这是不可能的实体类来承担这个责任。此外,我想保留将来将游戏移植到原生 Java/Swing 的可能性。

更新 2:

再想一想,也许这样就好了。也许实体和绘图是分开的并且实体告诉其他对象足够多的关于它自己的信息是可以被绘制的。我的意思是,我还能如何实现这种分离?我真的不知道没有它该如何生活。即使是伟大的面向对象的程序员有时也会使用带有 getter/setter 的对象,尤其是对于实体对象之类的东西。也许 getter/setter 并不都是邪恶的。你怎么看?

最佳答案

实用程序员讨论 tell, don't ask .您不想了解实体,而是希望绘制它。告诉它在给定的图形上绘制自己。

您可以重构上面的代码,以便实体进行绘图,这在实体不是矩形而是圆形的情况下很有用。

void Entity::draw(Graphics g) {
g.drawRect(x,y, width, height);
}

然后您将检查 g 在您的测试中调用了正确的方法。

关于java - 测试驱动开发中如何避免访问器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3808075/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com