3

有很多关于 getter 和 setter 是“邪恶”的讨论。

我的问题是:下面的二传手是邪恶的吗?(为简洁起见,其余课程省略)

int balance

public void deposit(int amount)  
{  
    this.balance += amount;  
}

此类正在模拟 ATM。在英国,有一些 ATM 可以让您存款和取款,因此该对象需要一种更改其状态(余额)的方法。这个二传手是“邪恶的”吗?

4

12 回答 12

8

除了没有处理异常情况这一事实之外,它看起来是一个非常好的 OO 方法——它被称为它所做的,它做你所期望的。

于 2009-02-25T20:28:14.027 回答
8

我不认为这是人们谈论 getter 和 setter 的意思,因为这不仅仅是将成员设置为给定值。

我不关心 setter 和 getter,但主要是因为我认为我的“对象”是代码库中更高级别的实体。例如(IMO)在课堂外进行操作会“更错误”:

account.SetBalance(account.GetBalance() + depositAmount)

相反,您已经在对象中实现了更高级别的功能;你存了一笔钱,然后让对象找出处理它的正确方法。与我上面给出的 getter/setter 示例相比,这允许对异常条件进行更集中的处理。

于 2009-02-25T20:32:23.797 回答
4

这是一个技巧问题吗?我问是因为提供的方法甚至不是“setter”方法。这是一个操作,而不是一个属性。Setter 和 Getter 通常是私有变量(属性)的访问器方法。所以我想你的问题的答案是:

这不是 setter,但作为对对象执行操作的通用方法,它一点也不邪恶。

于 2009-02-25T20:46:27.897 回答
3

对于一个类来说,通过 setter 设置值并没有什么坏处,但这更像是一个函数而不是直接的 setter。是的,它设置属性的值,但它通过添加而不是替换先前的值来实现,并且名称不对齐。

真正的“二传手”看起来更像这样:

int balance

private void setBalance(int amount)
{
    this.balance = amount;
}

public void deposit(int amount)  
{  
    setBalance(this.balance + amount);  
}

但是,对于您的特定 ATM 问题,我非常怀疑 ATM 是否会立即为您的余额添加存款。它可能需要通过单独的机制收集和发布。

于 2009-02-25T20:28:39.657 回答
2

就个人而言,我将其称为方法,而不是设置器。刻板的二传手将是

public void deposit(int new_balance)
{
    this.balance = new_balance;
}

它所做的只是让您直接访问类的内部,从而破坏通过封装它们和限制访问而获得的任何价值。这就是人们不喜欢它们的原因。

于 2009-02-25T20:36:53.257 回答
1

好吧,您可能想检查负数、零数等……但给出要求就可以了。

遵循这个经验法则,你创建的每个变量都应该是最终的,除非它必须更改,并且永远不要为实例变量设置方法,除非你真的希望它们在类之外进行更改。

于 2009-02-25T20:29:37.470 回答
0

那不是二传手,它是一种正常的方法

即使是二传手,也不是邪恶的

这是一个邪恶的二传手

int _balance = 0;  
public int Balance()  
{  
    get { return _balance; }  
    set { }    //now that's evil!  
}
于 2009-02-25T21:19:51.093 回答
0

IMO,ATM不应将“余额”作为字段。

(此外,您的“存款”方法不是二传手)

您可能应该有一个带有“余额”字段的 Account 对象,并且可能有一个方便的方法“modifyBalance”,它采用正值来增加余额或负值来减少余额。

然后,当执行这些类型的交易时,您的 ATM 方法将在 Account 对象上调用“modifyBalance”。

于 2009-02-25T20:40:53.403 回答
0

您无法判断单个方法是否邪恶,这取决于上下文以及谁可以访问该对象。

如果您对所有字段都有 getter 和 setter,并且每个人和他的狗都可以访问该对象,那么这是非常糟糕的,因为基本上没有数据封装。

另一方面,如果您只为需要它的字段设置了设置器,并且该对象只为少数需要与之通信的其他对象所知,那么这将是完全可以的。

于 2009-02-25T20:46:15.417 回答
0

那不是二传手。这是一个普通的方法(或成员函数,或其他)。

setter 是将给定变量设置为给定值的函数,通常是一个坏主意。方法是执行给定类操作的函数。就班级而言,这是有意义的。

如果你有一个奇怪的数据结构,你可能实际上没有一个“平衡”变量。无论你的数据结构是什么,你都必须有一个“存款”功能。有一部分的不同。

于 2009-02-25T20:49:44.643 回答
0

不必要; 您提到您想模仿 ATM(自动取款机)的行为。而且您担心自动取款机可以让您存款和取款。但是这些操作,存款和取款,必须是序列化的。你需要你的所有动作都是原子的,所以这种方法比你尝试做更多事情的方法要好。

于 2009-02-25T20:30:19.700 回答
0

我看到的一个问题是您在处理金钱时使用的是整数类型。如果这是一个定点数,则不是问题,但没有迹象表明确实如此。

于 2009-02-25T20:35:47.783 回答