正确的代码注释礼仪?



所以在代码中注释函数似乎是语言中的常见内容,但是,注释代码的正确方法是什么?我有一些示例代码,充斥着静态滥用和设计不佳的机制(对于 Java 来说仍然是新的),还有一些评论。注意:这是我上交的一个黑杰克项目,所以它最初是一个学校项目。

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class Main extends Application {
//Screen dimensions
private static int width;
private static int height;
private static int value;
//Make new card regions
private static Region userZERO;
private static Region userONE;
private static Region userTWO;
private static Region userTHREE;
private static Region userFOUR;
private static Region dealerZERO;
private static Region dealerONE;
private static Region dealerTWO;
private static Region dealerTHREE;
private static Region dealerFOUR;
//Scene components
private static Button hitButton;
private static Button endButton;
private static Button resetButton;
private static VBox root;
private static HBox userCardHolder;
private static HBox buttonContainer;
private static HBox dealerCardHolder;
private static Label text;
private static Scene scene;
//Card values
private static ArrayList<Card> user = new ArrayList<>();
private static ArrayList<Card> dealer = new ArrayList<>();
private static ArrayList<Card> cards = new ArrayList<>();
private static boolean dealerBusted = false;
//Miscellaneous variable assignments
/* Constant random variables using
* ThreadLocalRandom, speeds up to x3
* faster than Java.util.Random, and is
* unique to this thread.
*/
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
/* Main is first method called upon
* start, which uses the singular
* method, launch, to use the Start
* method which passes a Stage reference
* to begin building the Window.
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
width = ((int) Toolkit.getDefaultToolkit().getScreenSize().getWidth());
height = ((int) Toolkit.getDefaultToolkit().getScreenSize().getHeight());
cards = new ArrayList<>(Arrays.asList(Card.values()));
/* Creates rectangular regions for each card
* that will be represented in the GUI. Size
* is dictated by screen width and height,
* and in the shape of a rectangle to adapt
* to the shape of a playing card. Will set
* the preferential size, however has
* possibility of error if application is
* minimized.
*/
userZERO    = new Region(); userZERO.setPrefSize(width / 12, height / 4.5);
userONE     = new Region(); userONE.setPrefSize(width / 12, height / 4.5);
userTWO     = new Region(); userTWO.setPrefSize(width / 12, height / 4.5);
userTHREE   = new Region(); userTHREE.setPrefSize(width / 12, height / 4.5);
userFOUR    = new Region(); userFOUR.setPrefSize(width / 12, height / 4.5);
dealerZERO  = new Region(); dealerZERO.setPrefSize(width / 12, height / 4.5);
dealerONE   = new Region(); dealerONE.setPrefSize(width / 12, height / 4.5);
dealerTWO   = new Region(); dealerTWO.setPrefSize(width / 12, height / 4.5);
dealerTHREE = new Region(); dealerTHREE.setPrefSize(width / 12, height / 4.5);
dealerFOUR  = new Region(); dealerFOUR.setPrefSize(width / 12, height / 4.5);
/* Sets the .css limitations of the regions.
* First, sets up image as the BACK.png image
* in the resources folder. Then edits
* background size to auto cover the entire
* region to prevent inappropriately sized
* images per region.
*/
userZERO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userONE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userTWO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userTHREE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userFOUR.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerZERO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerONE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerTWO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerTHREE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerFOUR.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");

/* Setting up scene / Window information,
* and root information. Adding sub-roots
* to main-root for customized grid-pattern
* to contain cards on two rows, and a row
* of buttons in the middle independent
* of the card rows.
*/
root = new VBox(height / 25);
root.setPrefSize(width, height);
root.setMaxSize(width, height);
root.setMinSize(width, height);
root.alignmentProperty().setValue(Pos.CENTER);
root.setStyle(" -fx-background-image: url("images/BACKGROUND.png"); -fx-background-size: cover, auto;");
text = new Label();
text.setPrefSize(width / 2, height / 20);
text.setStyle(" -fx-text-alignment: center; -fx-font: 48 arial;");
text.alignmentProperty().setValue(Pos.CENTER);
text.setTextFill(Color.RED.darker());
hitButton = new Button("HIT");
endButton = new Button("END");
resetButton = new Button("RESET");
userCardHolder = new HBox(width / 12);
userCardHolder.getChildren().addAll(userZERO, userONE, userTWO, userTHREE, userFOUR);
userCardHolder.alignmentProperty().setValue(Pos.CENTER);
buttonContainer = new HBox(width / 10);
buttonContainer.getChildren().addAll(hitButton, resetButton, endButton);
buttonContainer.alignmentProperty().setValue(Pos.CENTER);
dealerCardHolder = new HBox(width / 20);
dealerCardHolder.getChildren().addAll(dealerZERO, dealerONE, dealerTWO, dealerTHREE, dealerFOUR);
dealerCardHolder.alignmentProperty().setValue(Pos.CENTER);
root.getChildren().add(userCardHolder);
root.getChildren().add(text);
root.getChildren().add(buttonContainer);
root.getChildren().add(dealerCardHolder);
scene = new Scene(root);
stage = new Stage();
stage.setScene(scene);
stage.show();
hitButton.setPrefSize(width / 4.5, height / 12);
endButton.setPrefSize(width / 4.5, height / 12);
resetButton.setPrefSize(width / 4.5, height / 12);
user.clear();
dealer.clear();
buttonHandlers();
begin();
}
public static void buttonHandlers() {
/* Stop!
* Lambda Time!
*/
hitButton.setOnAction(e -> {
if (user.size() < 5) {
Card card = cards.get(RANDOM.nextInt(cards.size()));
user.add(card);
cards.remove(card);
switch (user.size()) {
case 3:
userTWO.setStyle(" -fx-background-image: url("images/" + user.get(user.size() - 1).toString() + ".png"); -fx-background-size: cover, auto;");
break;
case 4:
userTHREE.setStyle(" -fx-background-image: url("images/" + user.get(user.size() - 1).toString() + ".png"); -fx-background-size: cover, auto;");
break;
case 5:
userFOUR.setStyle(" -fx-background-image: url("images/" + user.get(user.size() - 1).toString() + ".png"); -fx-background-size: cover, auto;");
break;
}
}
});
endButton.setOnAction(e -> {
for (Card c : dealer) {
switch (dealer.indexOf(c)) {
case 0:
dealerZERO.setStyle(" -fx-background-image: url("images/" + c.toString() + ".png"); -fx-background-size: cover, auto;");
break;
case 1:
dealerONE.setStyle(" -fx-background-image: url("images/" + c.toString() + ".png"); -fx-background-size: cover, auto;");
break;
case 2:
dealerTWO.setStyle(" -fx-background-image: url("images/" + c.toString() + ".png"); -fx-background-size: cover, auto;");
break;
case 3:
dealerTHREE.setStyle(" -fx-background-image: url("images/" + c.toString() + ".png"); -fx-background-size: cover, auto;");
break;
case 4:
dealerFOUR.setStyle(" -fx-background-image: url("images/" + c.toString() + ".png"); -fx-background-size: cover, auto;");
break;
}
}
/* Checking scenarios for valid ending:
*
* Checks if one or both entites busted, and decided winner based
* on card amount and card value. House wins by default if same
* card values and card amount.
*/
if (checkForBust(user) && checkForBust(dealer)) {
System.out.println("BOTH BUSTED!");
text.setText("BOTH BUSTED!");
}
else if (checkForBust(user) && !checkForBust(dealer)) {
System.out.println("YOU BUSTED!");
text.setText("DEALER WON!");
}
else if (!checkForBust(user) && checkForBust(dealer)) {
System.out.println("DEALER BUSTED!");
text.setText("YOU WON!");
}
else if (getValue(user) > getValue(dealer)) {
System.out.println("USER WINS");
text.setText("YOU WON!");
}
else if ((getValue(user) == getValue(dealer)) && (user.size() >= dealer.size())) {
System.out.println("DEALER WINS");
text.setText("DEALER WON!");
}
else if ((getValue(user) == getValue(dealer)) && (user.size() <= dealer.size())) {
System.out.println("USER WINS");
text.setText("USER WON!");
}
else if ((getValue(user) == getValue(dealer)) && (user.size() == dealer.size())) {
System.out.println("DEALER WINS");
text.setText("DEALER WON!");
}
else if (getValue(dealer) > getValue(user)) {
System.out.println("DEALER WINS");
text.setText("DEALER WON!");
}
else {
System.out.println("ERROR!");
text.setText("ERROR GETTING WINNER!");
}
});
resetButton.setOnAction(e ->{
begin();
});
}
public static boolean checkForBust(List<Card> lc) {
value = 0;
for (Card c : lc) {
value += c.getValue();
}
if (lc.contains(Card.ACE_OF_CLUBS) && value > 21) { value -= 10; }
if (lc.contains(Card.ACE_OF_DIAMONDS) && value > 21) { value -= 10; }
if (lc.contains(Card.ACE_OF_HEARTS) && value > 21) { value -= 10; }
if (lc.contains(Card.ACE_OF_SPADES) && value > 21) { value -= 10; }
return value > 21;
}
public static int getValue(List<Card> lc) {
value = 0;
for (Card c : lc) {
value += c.getValue();
}
if (lc.contains(Card.ACE_OF_CLUBS) && value > 21) { value -= 10; }
if (lc.contains(Card.ACE_OF_DIAMONDS) && value > 21) { value -= 10; }
if (lc.contains(Card.ACE_OF_HEARTS) && value > 21) { value -= 10; }
if (lc.contains(Card.ACE_OF_SPADES) && value > 21) { value -= 10; }
return value;
}
public static void begin() {
text.setText("");
cards.clear();
user.clear();
dealer.clear();
cards = new ArrayList<>(Arrays.asList(Card.values()));
userZERO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userONE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userTWO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userTHREE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
userFOUR.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerZERO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerONE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerTWO.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerTHREE.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
dealerFOUR.setStyle(" -fx-background-image: url("images/BACK.png"); -fx-background-size: cover, auto;");
Card card = cards.get(RANDOM.nextInt(cards.size()));
user.add(card);
cards.remove(card);
card = cards.get(RANDOM.nextInt(cards.size()));
user.add(card);
cards.remove(card);
userZERO.setStyle(" -fx-background-image: url("images/" + user.get(0) + ".png"); -fx-background-size: cover, auto;");
userONE.setStyle(" -fx-background-image: url("images/" + user.get(1) + ".png"); -fx-background-size: cover, auto;");
card = cards.get(RANDOM.nextInt(cards.size()));
dealer.add(card);
cards.remove(card);
card = cards.get(RANDOM.nextInt(cards.size()));
dealer.add(card);
cards.remove(card);
dealerZERO.setStyle(" -fx-background-image: url("images/" + dealer.get(0) + ".png"); -fx-background-size: cover, auto;");
while(getValue(dealer) < 16 && dealer.size() < 5) {
card = cards.get(RANDOM.nextInt(cards.size()));
dealer.add(card);
cards.remove(card);
}
}

/* Switch to enum values:
* Card values and suits. Nested enum classes in a main class.
*/
public enum Card {
ACE_OF_SPADES(11, Suit.SPADES),
ACE_OF_HEARTS(11, Suit.HEARTS),
ACE_OF_DIAMONDS(11, Suit.DIAMONDS),
ACE_OF_CLUBS(11, Suit.CLUBS),
TWO_OF_SPADES(2, Suit.SPADES),
TWO_OF_HEARTS(2, Suit.HEARTS),
TWO_OF_DIAMONDS(2, Suit.DIAMONDS),
TWO_OF_CLUBS(2, Suit.CLUBS),
THREE_OF_SPADES(3, Suit.SPADES),
THREE_OF_HEARTS(3, Suit.HEARTS),
THREE_OF_DIAMONDS(3, Suit.DIAMONDS),
THREE_OF_CLUBS(3, Suit.CLUBS),
FOUR_OF_SPADES(4, Suit.SPADES),
FOUR_OF_HEARTS(4, Suit.HEARTS),
FOUR_OF_DIAMONDS(4, Suit.DIAMONDS),
FOUR_OF_CLUBS(4, Suit.CLUBS),
FIVE_OF_SPADES(5, Suit.SPADES),
FIVE_OF_HEARTS(5, Suit.HEARTS),
FIVE_OF_DIAMONDS(5, Suit.DIAMONDS),
FIVE_OF_CLUBS(5, Suit.CLUBS),
SIX_OF_SPADES(6, Suit.SPADES),
SIX_OF_HEARTS(6, Suit.HEARTS),
SIX_OF_DIAMONDS(6, Suit.DIAMONDS),
SIX_OF_CLUBS(6, Suit.CLUBS),
SEVEN_OF_SPADES(7, Suit.SPADES),
SEVEN_OF_HEARTS(7, Suit.HEARTS),
SEVEN_OF_DIAMONDS(7, Suit.DIAMONDS),
SEVEN_OF_CLUBS(7, Suit.CLUBS),
EIGHT_OF_SPADES(8, Suit.SPADES),
EIGHT_OF_HEARTS(8, Suit.HEARTS),
EIGHT_OF_DIAMONDS(8, Suit.DIAMONDS),
EIGHT_OF_CLUBS(8, Suit.CLUBS),
NINE_OF_SPADES(9, Suit.SPADES),
NINE_OF_HEARTS(9, Suit.HEARTS),
NINE_OF_DIAMONDS(9, Suit.DIAMONDS),
NINE_OF_CLUBS(9, Suit.CLUBS),
TEN_OF_SPADES(10, Suit.SPADES),
TEN_OF_HEARTS(10, Suit.HEARTS),
TEN_OF_DIAMONDS(10, Suit.DIAMONDS),
TEN_OF_CLUBS(10, Suit.CLUBS),
JACK_OF_SPADES(10, Suit.SPADES),
JACK_OF_HEARTS(10, Suit.HEARTS),
JACK_OF_DIAMONDS(10, Suit.DIAMONDS),
JACK_OF_CLUBS(10, Suit.CLUBS),
QUEEN_OF_SPADES(10, Suit.SPADES),
QUEEN_OF_HEARTS(10, Suit.HEARTS),
QUEEN_OF_DIAMONDS(10, Suit.DIAMONDS),
QUEEN_OF_CLUBS(10, Suit.CLUBS),
KING_OF_SPADES(10, Suit.SPADES),
KING_OF_HEARTS(10, Suit.HEARTS),
KING_OF_DIAMONDS(10, Suit.DIAMONDS),
KING_OF_CLUBS(10, Suit.CLUBS);
private int value;
private Suit suit;
Card(int value, Suit suit) {
this.value = value;
this.suit = suit;
}
public int getValue() { return value; }
}
public enum Suit {
HEARTS(),
DIAMONDS(),
CLUBS(),
SPADES();
Suit(){}
}
}

在提交要观察的代码时,我应该没有评论,我应该有评论,我应该使用 JavaDocs 功能等。然后是我应该如何评论,如果我做 2 行或 3 行,我应该使用多重方法吗?

/* store some comments
* around here
*/

或者干脆//comment here几次

回到JavaDocs,这对于一个学校项目来说是理想的吗,它是否让它在某种意义上看起来很"专业"?用Java和英语编写的代码是使其专业还是损害了专业性。还有,我应该描述它们是什么吗?他们做什么,两者兼而有之,等等?我显然不希望我的代码中有 99% 是注释,但我确实想要一些注释,没有你在书中看到的填充类型内容。什么因素允许在评论中写下理想和广泛接受的信息?

关于评论有几种不同的思想流派。一些开发人员认为注释是对编写不佳的代码的道歉,但我不同意这个想法,并发现它们很有用。阅读文章的替代方法是分析用Java编写的流行开源项目的源代码,并尝试模仿它们的风格。流行的Java IDE,如NetBeans,Eclipse和IntelliJ是用Java编写的开源项目,因此它们是很好的起点。

  • Netbeans: https://github.com/apache/incubator-netbeans
  • 日食:https://github.com/eclipse
  • IntelliJ: https://github.com/JetBrains/intellij-community

您不必理解逻辑,只需记下作者如何注释他们的代码即可。一段时间后,您应该开始看到一些很棒的相似之处,请继续将它们吸收到您的编码库中。

当我们被迫使用评论时,有一种强烈的气味,表明有什么不对劲。除了在javadocs中,当我们真的需要注释代码时,它可能写得不是那么好,甚至不能正确代表业务规则。

例如:您那里有注释"//屏幕尺寸"。为什么不使用这些属性创建和反对呢?

我喜欢Refactor.Guru,因为它解释了很多难闻的气味,代码模式,重构策略等等。此外,它还提供了一些关于何时以及如何评论的提示。

最新更新