Proper Code Commenting Etiquette?

时间:2018-04-20 00:51:13

标签: java comments

So commenting functions in code seems to be a common staple amongst the languages, however, what is the proper way to comment on code? I have some example code, riddled with static abuse and poorly designed mechanics (still new to Java), with some comments. Note: This is for a Black Jack project I turned in so it was a school project originally.

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(){}
    }
}

When submitting code to be observed, should I not have comments, should I have comments, should I utilize the JavaDocs feature, etc. Then there is how should I comment, if I do 2 or 3 lines, should I use the multiple method?

/* store some comments
 * around here
 */

or simply //comment here a few times

Moving back to the JavaDocs, would that be ideal for a school project, does it make it seem 'professional' in a sense? Is having the code written in Java and English make it professional or is that hurting the professionalism. There is also, should I describe WHAT they are? What they DO, both, etc? I obviously don't want 99% of my code to be comments, but I do want some comments, without a filler-type content you'd see in books. What factor allows information to be ideally and widely accepted to be written down in comments?

2 个答案:

答案 0 :(得分:1)

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

您不必理解逻辑,只需记录作者如何评论他们的代码。过了一段时间,你应该开始看到一些很好的相似之处,继续并将它们融入你的编码曲目中。

答案 1 :(得分:0)

When we are forced to use comments it is a strong smell that something is wrong. Except in javadocs, when we really need to comment a code, probably it is not so well writen or even doesn't represent properly the business rules.

For example: you have the comment "//Screen dimensions" there. Why not create and object with those properties?

I love Refactor.Guru because it explains a lot of bad smells, code patterns, refactoring strategies and so on. Also, it has some tips about when and how comment.