Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正在使用';数据类';在这种情况下是个坏主意吗?_Java_Design Patterns_Anti Patterns - Fatal编程技术网

Java 正在使用';数据类';在这种情况下是个坏主意吗?

Java 正在使用';数据类';在这种情况下是个坏主意吗?,java,design-patterns,anti-patterns,Java,Design Patterns,Anti Patterns,我目前正在使用你可以称之为遗留代码的东西。我基本上有一个处理工作流的类,每次机器启动时只实例化一次。每次新用户使用该计算机并登录到该计算机时,都会启动一个新的“会话”,但我们会保留该类的相同实例。为了简单起见,让我们假设这台机器是一台自助式机器 这基本上意味着每次新用户会话启动时,我们都需要将所有流变量重置回其默认值 所以通常我会有实例/成员变量,比如: boolean didUserPressYes; boolean didUserTakeHisReceipt; int numberOfIns

我目前正在使用你可以称之为遗留代码的东西。我基本上有一个处理工作流的类,每次机器启动时只实例化一次。每次新用户使用该计算机并登录到该计算机时,都会启动一个新的“会话”,但我们会保留该类的相同实例。为了简单起见,让我们假设这台机器是一台自助式机器

这基本上意味着每次新用户会话启动时,我们都需要将所有流变量重置回其默认值

所以通常我会有实例/成员变量,比如:

boolean didUserPressYes;
boolean didUserTakeHisReceipt;
int numberOfInsertedItems;
然后是在流/用户会话开始时调用的resetVars()方法:

public void resetVars() {
 didUserPressYes = false;
 didUserTakeHisReceipt = false;
 numberOfInsertedItems = 0;
}
通常我只是重新实例化这个类,并避免使用这个resetVars()方法。不幸的是,我们被绑定到一个不允许我们这样做的框架上,我们必须保持类的相同实例

在我们的实际代码中,我们有大约12个这样的变量,并且在将来几乎肯定会添加更多。我可以看到,当每个用户会话启动时,这些变量没有正确地重置为默认值,特别是当项目中有新成员忘记将新变量添加到此resetVars()方法中时,可能会出现错误

为了解决这个问题,我制作了一个WorkflowVariables类,它包含这些变量,并在适当的地方有getter和setter,以及一些小的实用方法。在每个用户会话开始时,我们只需重新实例化这个WorkflowVariables类,现在就可以知道所有变量都已恢复为默认值。无需担心某些实例变量不会被重置,因为我们只有一个:

private WorkFlowVariables workFlowVariables;

public void resetVars() {
    workFlowVariables = new WorkFlowVariables();
}
然而,在阅读了一些“代码气味”之后,似乎这就是所谓的“数据类”,实现起来很糟糕

在我的情况下,是否有人认为这是一个坏主意,或者这适合这种特定情况?也许有更好的办法来解决这个问题?如果我们保留多个实例变量,那么过于担心潜在的bug是不是错了


提前谢谢

您提到了程序运行时存在的一个类<代码>程序可能是这个类的好名字,但你可以想出更好的名字

---一个小插曲,但我们会回到你的主线问题---

您还提到了有效范围为一个“会话”的变量。我将创建第二个类,
Session
并重构,直到这些变量在该类中。然后在构造函数中初始化变量

在开始移动对象之前,请放入测试用例(尽可能地)以验证变量行为是否正确。移动后,清理这些测试用例并使其健壮。测试您通常不会做的事情,或者允许做的事情(如果您完全控制所有代码),比如传递空变量等等

通过这样做,您可以有效地取消遗留代码的一小部分。相信我,这是值得的

---好的,不是回到我们的常规问题---

您是对的,此路径设置了一个数据类;然而,数据在正确的位置,现在只有逻辑在错误的位置

查找访问集群中移动数据的代码块。如果直接访问数据,可以通过将成员设置为私有并监视整个产品的编译失败,或者使用IDE功能来实现这一点。跟踪每个访问,寻找读写行为的模式

一旦您确定了(比方说)读取行为的模式,然后在“数据类”中创建一个虚拟方法,其名称与您认为正在发生的事情近似。将该方法放在远程调用者中,然后他们将语句“移动”到该方法中。这有效地将它们移动到了过去仅用于数据的类中

现在您有了一个包含数据和一些行为的类。继续使用该模式,直到您确信所有“正确”的行为都是正确的。然后再次检查您公开的“getter和setter”方法是否真的需要公开

在整个过程中使您的测试保持最新,并验证它们是否也涵盖了新创建的方法。他们是你的安全网,你真的没有改变任何事情,除非你想改变代码

祝你好运

---为回答问题而编辑---

只有出于愚蠢的原因才是愚蠢的。您似乎认为移动代码的原因与避免气味有关。这根本不是移动代码的原因。移动代码的原因是因为它位于错误的位置

如果我有独立于数据的逻辑,那么我的数据必须在外部进行管理。也就是说,每当有人想对我的数据做一些事情时,就要由“某人”以一种不会使我的数据在内部不一致的方式来做。这可能包括在将数据类设置为包含变量值之前检查变量是否不为null、根据成员变量的组合更新公开值、在值更改时发送通知、标记项目以进行“进一步处理”、存储审核日志条目等

Won't it also tightly couple those classes? 
这在很大程度上取决于你在哪里进行拆分,以及如何进行拆分。重构并不意味着你可以一次性解决所有问题。这意味着您修改代码的方式不会改变其功能。在重构步骤之间,您最终将进行代码更改。如果没有先前的重构步骤,这些小的代码更改可能是不可能的(或者至少是困难的),并且它们可能会引入bug(就像任何非重构更改一样)

哦,松散耦合在您为可扩展性而设计的地方是很好的。松散耦合是一个典型的例子,它不会扩展任何内容,浪费资源来编写不需要的代码

一个很好的例子
Won't it also tightly couple those classes?