我正在寻找改进我为此编写的代码的方法。
考虑一个简单的自动售货机类。该机器接受代币和分发罐的提神饮料。编写完整的类(在下一页)如下所述:
public class Vendingmachine
{
private int tokens;
private int cans;
public Vendingmachine()
{
tokens=0;
cans=50;
}
public Vendingmachine( int ca)
{
tokens=0;
cans=ca;
System.out.printf(" The constructor for this %s\n", this);
}
public void setTokens( int coins)
{
tokens = coins;
}
public void setCans ( int ca)
{
cans = ca;
}
public void purchase( int coins)
{
tokens = coins;
if (tokens >=1)
cans = cans-tokens;
if (cans == 0)
addCans();
}
public int getTokens()
{
return tokens;
}
public int getCans()
{
cans = cans- tokens;
return cans;
}
public void addCans()
{
cans =50;
}
public String toString()
{
String str = "You have purchased "+ cans + " cans and have entered the following amount of coins: " + tokens;
return str;
}
}发布于 2016-12-08 05:02:54
我注意到了一些你可以考虑的事情:
VendingMachine,注意大写M。const。coins和tokens的使用令人困惑,因为它们似乎指的是同一件事。选一个词,在任何地方都用。getCans()更改cans的值。这是一个副作用,这通常被认为是不-不,特别是在一个吸气剂.-=,所以我会将cans = cans - tokens;改为cans -= tokens;发布于 2016-12-08 04:37:37
有几件事我个人会改变的。
首先,间距似乎不一致。在您的构造器中,您有以下内容:
public Vendingmachine()
{
tokens=0;
cans=50;
} 但后来,你有了这个:
public void setTokens( int coins)
{
tokens = coins;
}
public void setCans ( int ca)
{
cans = ca;
}它不会对你的表现产生任何影响,但是保持它的一致性会增加你自己和其他人的可读性。我也很好奇为什么您的setTokens和addCans函数在两次中被标签化,大多数是一次被标签化,而您的toString却根本没有被标签。
这一点没有多大区别,但您可以使用println,而不是使用printf (我假设您来自C背景)。无论是对你在做什么,还是你使用哪一个,都是非常好的,通常都取决于你的喜好。对我来说,这几乎完全是为了清晰。所以你可以这么做:
public Vendingmachine( int ca)
{
tokens=0;
cans=ca;
System.out.printf(" The constructor for this %s\n", this);
}或者这个:
public Vendingmachine( int ca)
{
tokens=0;
cans=ca;
System.out.println("The constructor for this " + this);
}虽然我不太清楚您想要在其中添加什么,因为它只是在文本的基础上输出toString方法。
接下来,我认为购买功能有问题。从读取问题语句看,它似乎只使用一个令牌,但您的代码似乎使用多个标记。假设我们知道它只使用一个令牌,那么您所要做的就是检查是否还剩罐,如果没有,则添加一些罐,或者从罐中减去一个,然后向令牌中添加一个。看起来会是这样的:
public void purchase()
{
if(cans == 0)
addCans();
else
{
cans--;
tokens++;
}
}但除此之外,我唯一能挑出来的就是它的间距。
发布于 2016-12-09 11:49:18
该类有两个实例数据字段:一个用于跟踪机器中的罐头数量,另一个用于跟踪收集到的令牌(如硬币)的数量。
看起来不错,因为你实际上有这些字段。
应该有两个构造函数。一个人没有争论,开始于50个罐子和零代币。另一个论点是机器中罐头的初始数量。
满足了这一要求。然而,它是如何实现的,现在是一种代码味道。只有一个主构造函数执行字段赋值,另一个构造函数只使用其他参数调用主构造函数,这是一个良好做法:
public Vendingmachine() {
this(50);
}
public Vendingmachine(int cans) {
this.tokens = 0;
this.cans = cans;
}应该有一种购买饮料的方法,这种方法在机器上添加一个令牌,并减去一个可以减少的东西--假设机器中还有罐要购买。
当没有罐子的时候,这个要求并没有说明什么是行为,所以我认为它没有什么。如果你知道这个要求是什么,我会相应地更新我的答案。
看看您当前的purchase方法,我认为需求没有达到。首先你用tokens=coins;擦去旧的代币,然后在自动售货机空着的时候用50罐装满它,这看起来很奇怪,会产生意想不到的副作用(详见最小惊讶原则 )。该需求还指出,您应该能够在时间上只能检索一个(而不是很多)。下面是我如何实现purchase
public void purchase() {
if(cans > 0) {
cans--;
tokens++;
}
}应该有一种方法把罐头加到机器上。
目前有一个addCans方法。但是,既然您应该添加罐而不是设置罐,那么您应该将应该添加的罐数作为一个参数:
public void addCans(int cans) {
this.cans += cans;
}应该有不同的方法来返回剩余的罐数和收集到的令牌数。编写toString( )方法,以便方便地打印自动售货机对象
getCans在这里真的很恶心!人们期望只返回一个值,但在它执行一些意外的计算之前!您应该以简单吸气剂的形式编写它。
public int getCans() {
return cans;
}getTokens很好。
toString中的结果字符串具有误导性。cans是自动贩卖机目前装的罐的数量,tokens是插入的硬币的数量。您还应该直接返回字符串,而不是创建一个空变量。
public String toString() {
return cans + " cans left and " + tokens + " coins inside.";
}超越需求的
这两位策划者是多余的,可以被移除。
另外,Java类命名约定是CamelCase,所以您应该将Vendingmachine重命名为VendingMachine。
由于您的类不是要继承的,所以可以将其标记为final。
下面是完整的结果类
public class final VendingMachine {
private int tokens;
private int cans;
public VendingMachine() {
this(50);
}
public VendingMachine(int cans) {
this.tokens = 0;
this.cans = cans;
}
public void purchase() {
if (cans > 0) {
cans--;
tokens++;
}
}
public void addCans(int cans) {
this.cans += cans;
}
public String toString() {
return cans + " cans left and " + tokens + " coins inside.";
}
public int getTokens() {
return tokens;
}
public int getCans() {
return cans;
}
}https://codereview.stackexchange.com/questions/149254
复制相似问题