如何在Java中缩短我的长方法?

时间:2019-03-11 14:48:22

标签: java methods

我是Java的初学者,我的问题是我的方法经常变得很长。有人告诉我方法应该尽可能简短,而一种方法只能做一件事情。例如,我制作了一个程序,可以在这里拍卖狗。我需要一些技巧,说明如何从这种较长的方法中分解出较小的方法,但仍然可以使其以相同的方式工作。这是我的代码:

private void makeNewBid() {

System.out.println("Enter the name of the user>");
String userName = input.nextLine().toLowerCase();
User u = getUser(userName);
if (userName == null || !userRegister.contains(u)) {
    System.out.println("error. no such user");
    return;


}else {


Auction bidAuction = null;
String name = dogLowerCaseTrim();
Dog d = getDog(name);
for(Auction a: auctionRegister ) {
    if(auctionRegister.equals(name.toLowerCase())) {
        bidAuction = a;
        break;
    }
}
Auction a = getAuctionedDog(d);
if(bidAuction != null) {
    System.out.println("error. this dog is not up for auction.");

    return;
}

System.out.print("Amount to bid: min " + (getAuctionedDog(d).getTopBid()+ 1 )+ "> ");
int amount = input.nextInt();   
while(amount <= a.getTopBid()) {
    System.out.println("error. too low bid");
    System.out.println("Amount to bid: min " + (getAuctionedDog(d).getTopBid() + 1));
    amount = input.nextInt();


}
Bid b = new Bid(u, amount);
getAuctionedDog(d).addBid(b);
System.out.println("Bid made");
input.nextLine();

}    

}

2 个答案:

答案 0 :(得分:1)

您的方法违反了single responsibility设计原则的一部分SOLID

来自“清除代码”

大小

  

函数的第一个规则是它们应该很小。第二   功能规则是它们应该小于该值。

块和缩进

  

[...]函数的大小应不足以容纳嵌套结构。

做一件事

  

功能应该做一件事。他们应该做得很好。他们应该做   只能。

本书进一步介绍了一些保持功能清洁的内容,但我认为仅在示例中实现这些功能已经有些工作了。

  • 创建一种获取用户的方法。
  • 创建一种方法来进行大拍卖。
  • 创建一种获取金额的方法。

最好创建一个服务来容纳所有这些方法。

不要那样停止您的方法流,而是创建您的异常并抛出该异常。

System.out.println("error. no such user");
return;

不要这样命名您的变量。取而代之的是使用有意义的变量名,这不仅可以提高代码的可读性,还可以为将来的自己,也可以为其他人提供。

Dog d = getDog(name);

答案 1 :(得分:0)

关于“有人告诉我方法应该尽可能短,而一种方法只能做一件事情”的问题。 这实际上是两个不同的语句:

  1. 方法应尽可能短
  2. 方法只能做一件事。

对于第一句话:

通常,我会拒绝第一句话。编写方法的最短方法往往是一些难以理解的混淆代码垃圾。 但是,使代码更易于理解通常会导致更少的代码行。同样,如果您遵循第二条语句,您将得到较少的提示。 因此,尽管我认为尝试创建最少的代码行根本没有任何好处,但是如果可以改进代码,很多行会指示对代码进行复审(但复查本身不应该专注于代码行。有关代码的质量)。

第二句话:

此说法正确!一种方法应该专注于一项任务并正确地做到这一点。它应该具有尽可能小的副作用。

您称其为做某事。如果它还有其他功能,则很可能早晚为原始用途调用该问题。否则,您将无法在其他情况下调用它,因为它会执行您不想做的事情。

为清楚起见,具有明确目的的方法也易于理解和检查:它是否应做的事?还是做错了什么?如果您想确定的话,可以轻松地创建一个检查方法的测试。

现在为您提供代码: 首先,作为借口,您的示例“按原样”并不是显示方法的理想选择。此外,缺少某些部件,这些部件可能无法或不能提供进一步改进的空间。因此,不要单枪匹马,而要专注于底层思想,将您的代码分解为一些逻辑单元(按您的要求)。

a)您具有一些用户标识:

System.out.println("Enter the name of the user>");
String userName = input.nextLine().toLowerCase();
User u = getUser(userName);
if (userName == null || !userRegister.contains(u)) {
    System.out.println("error. no such user");
    return;

}

该标识似乎是可以用其自己的方法放置的逻辑单元。它标识一个用户。

b)您从其他地方定义的容器中获取了一些bidAuction:

for(Auction a: auctionRegister ) {
    if(auctionRegister.equals(name.toLowerCase())) {
        bidAuction = a;
        break;
    }
}

和平可以是一个单独的方法,该方法可以通过名称“ getBidAuction(String name)”来获取项目。

c)接下来,您要出价:

System.out.print("Amount to bid: min " + (getAuctionedDog(d).getTopBid()+ 1 )+ "> ");
int amount = input.nextInt();   
while(amount <= a.getTopBid()) {
    System.out.println("error. too low bid");
    System.out.println("Amount to bid: min " + (getAuctionedDog(d).getTopBid() + 1));
    amount = input.nextInt();
}
Bid b = new Bid(u, amount);

再次类似于可以放入返回出价的方法中的代码:“ Bid getBid(User user,Auction auction){”。

这样,您最终会得到结果-仍然不是最佳选择(缺少有关逻辑以及其他方法正在执行的操作的一些提示),但会分崩离析

public class NewClass {

    User identifyUser() {
        System.out.println("Enter the name of the user>");
        String userName = input.nextLine().toLowerCase();
        User user = getUser(userName);
        if (userName == null || !userRegister.contains(user)) {
            System.out.println("error. no such user");
            return null;
        }
        return user;
    }

    Auction findAuction(String name) {
        Auction bidAuction = null;
        for (Auction a : auctionRegister) {
            if (auctionRegister.equals(name.toLowerCase())) {
                return a;
            }
        }
        return null;
    }

    Bid getBid(User user, Auction auction) {
        System.out.print("Amount to bid: min " + (auction.getTopBid() + 1) + "> ");
        int amount = input.nextInt();
        while (amount <= auction.getTopBid()) {
            System.out.println("error. too low bid");
            System.out.println("Amount to bid: min " + (auction.getTopBid() + 1));
            amount = input.nextInt();

        }
        return new Bid(user, amount);
    }

    void makeNewBid() {
        User user = identifyUser();
        if (null == user) {
            return; //use an exception instead.
        }
        String name = dogLowerCaseTrim();
        Auction bidAuction = findAuction(name);
        //is this realy what you intended?!
        if (bidAuction != null) {
            System.out.println("error. this dog is not up for auction.");
            return; //use an exception instead?
        }
        Dog dog = getDog(name);
        //might this be the same as bidAuction?!
        Auction auction = getAuctionedDog(dog);
        Bid bid = getBid(user, auction);
        auction.addBid(bid);
        System.out.println("Bid made");
        input.nextLine();

    }
}

接下来出现的问题是,为什么用户再次为每个出价进行注册?那不应该在别的地方做吗?未注册用户甚至可能竞标吗?很可能应该在方法之外进行检查。

“拍卖”项目可能也是如此。取决于。

getAuctionedDog()有什么作用?是多余的吗?它类似于findAuction吗?那么“ bidAuction”和“ auction”是同一个对象吗? -无法从代码中说出来。如果没有:也许应该!如果是这样:使用您拥有的一个并删除第二个(在这种情况下,将其与多余的狗对象一起使用)。

逻辑上您想要的是比较“ if(bidAuction!= null){”吗? -我无法从您的代码中说出来,但很有可能您希望以另一种方式使用它“ if(bidAuction == null){”。