Estilo de Código

Nós seguimos as diretrizes do Google Java Style <https://google.github.io/styleguide/javaguide.html> com algumas adições e alterações que são descritas abaixo.

Dica

Você pode utilizar os nossos estilos de código para Eclipse ou IntelliJ IDEA para que a IDE formate o código corretamente para você. Visite Sponge Code Styles.

  • Finais de linha

    • Usa os finais de linha do Unix quando fizeres commit (\n)

      • Os utilizadores de Git no windows podem usar git config --global core.autocrlf true para deixar o Git converter-los automaticamente

  • Comprimento da coluna

    • 80 para Javadocs

    • 150 para o código

    • Pode fazer wrap quando achar que ajuda na leitura

  • Indentação

    • Use 4 espaços para indentar, não use 2

  • Parágrafos em branco

    • Utilize uma linha em branco antes do primeiro membro de uma classe, interface, enum, etc. (ex: depois de “class Example {”) e depois do ultimo membro

  • Cabeçalhos de ficheiros

    • Os cabeçalhos dos ficheiros têm de conter os cabeçalhos da licença para o projeto. Usa a função updateLicenses do Gradle para adicionar-los automaticamente

  • Imports

    • As Imports devem ser agrupadas pela seguinte ordem, e os grupos devem ser separados por uma linha em branco

      • Imports Estáticos

      • Todos os outros Imports

      • Imports do Java

      • Imports do Javax

    • Isto difere do estilo do Google na medida em que os imports não estão agrupados por packages de top-level, mas estão todas num só grupo.

  • Exceções

    • Para exceções que devem ser ignoradas, nomeia a variável da exceção “ignored”

  • Field accesses

    • Classificar todos os field accesses com this

  • Javadocs

    • Não utilize “@author”

    • Inclui parágrafos adicionais dentro de “<p>” e “</p>”

    • Utilize letra maiúscula na primeira letra das descrições dentro de cada “at clause”, ex: @param name Player to affect e não utilize pontos finais

  • Fim do Ficheiro

    • Cada ficheiro deve terminar com uma linha em branco

Convenções de Código

  • Use Opcionais em vez de retornar null na API

  • Os parâmetros dos métodos que aceitem “null” têm de ter a notação “@Nullable” (de javax.*), todos os métodos e parâmetros são “@Nonnull” por defeito.

  • API: Use java.util.Objects.requireNonNull para a verificação de nulos e ifs para a verificação de argumentos.

  • Impl: Use Google Preconditions para verificação de nulos e argumentos.

A essência

Esperamos que leia as Google’s Java Conventions, ainda que sejam documentos bastante extensos. Para um início rápido, tem aqui um exemplo de código formatado corretamente:

/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.example;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.inject.Inject;
import org.slf4j.Logger;

import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

import javax.annotation.Nullable;

/**
* An example class which generates a new ID based on a specified base string
* and a randomly generated integer.
*
* <p>There is a chance the integer purposely fails to generate, in which case
* you can choose to provide a backup integer.</p>
*/
public class Example {

    private static final long SEED = 4815162342L;

    @Inject
    private Logger logger;

    private final String base;
    private final Random random;

    public Example(String base) {
        checkNotNull(base, "The specified base string cannot be null!");
        this.base = base;
        this.random = ThreadLocalRandom.current();
        this.random.setSeed(SEED);
    }

    /**
    * Generates and returns an ID using the base string specified on creation
    * or the alternative string if specified as well as a randomly generated
    * integer, which purposely fails to generate around 50% of the time.
    *
    * <p>A {@link ThreadLocalRandom} is used to check if the integer should
    * be generated and generates the integer itself if so.</p>
    *
    * @param alternate An alternate base string which will be used if not null
    * @return The generated ID, if available
    */
    public Optional<String> generateId(@Nullable String alternate) {
        if (this.random.nextBoolean()) {
            return Optional.of(alternate == null ? this.base : alternate + " - " + this.random.nextInt());
        }

        return Optional.empty();
    }

    /**
    * Generates and returns an ID using the base string specified on creation,
    * using a randomly generated integer if it was generated successfully, or
    * using the backup integer you specify.
    *
    * <p>A {@link ThreadLocalRandom} is used to check if the integer should
    * be generated and generates the integer itself if so. If it was not
    * generated, that is when your backup integer will be used.</p>
    *
    * @param backup A backup integer to use to create the ID with
    * @return The generated ID using the generated integer or the ID created
    *     using the backup integer specified
    */
    public String generateId(int backup) {
        return generateId(null).orElse(this.base + " - " + backup);
    }

}