Estetyka kodu w programowaniu
Wciąż prężnie podążamy za Google’s Java - Estetyka w kodzie z kilkoma dodatkami i zmianami, które są opisane w tym dokumencie.
Wskazówka
Możesz użyć naszych stylów kodu Eclipse lub IntelliJ IDEA, aby Twój IDE poprawnie formatował kod dla Ciebie. Odwiedź style kodu Sponge.
Line endings - Zakończenia linii
Używaj Unixowych zakończeń linii w commitach (\n)
Ci użytkownicy, którzy są skazani na Windowsa mogą wykonać komende
git config --global core.autocrif true
, aby GitHub konwertował je automatycznie.
Szerokości kolumn
80 dla Javadocs
150 dla kodu źródłowego
Zawijaj tekst wedle uznania jeśli to zwiększy jego czytelność
Intentation - Wcięcie, tabulacja
Użyj 4 razy spacja do wcięcia, nie używaj 2 spacji
Vertical whitespace - Odstępy w pionie
Pozostaw pustą linię przed pierwszym elementem klasy, interfejsu, itd. (np.: po
class Example {
) jak również po ostatnim elemencie
File headers - Nagłówki plików
Nagłówki plików muszą zawierać nagłówki licencji dla projektu. Użyj
updateLicenses
zadania Gradle aby dodać je automatycznie
Imports - definiowanie ścieżek pakietów
Importy muszą być pogrupowane według podanej kolejności, gdzie każda grupa jest oddzielona pustą linią:
Static imports - Importy statyczne
All other imports - pozostałe importy
java
importsjava
imports
Jest to jedna z różnic od Google`s Style, w tym Importy nie są pogrupowane według najwyższego poziomu pakietu, ale są one zgrupowane w jednym.
Exceptions (wyjątki)
Dla wyjątków, które mają być ignorowane użyj
ignored
jako nazwy zmiennej wyjątku.
Field accesses - Pole dostępu
Kwalifikują się wszystkie pola dostępu z
this
Javadocs - dokumentacja java
Nie używać
@author
Wykorzystaj dodatkowe znaczniki
<p>
i</p>
, aby oznaczyć paragrafyW opisie każdej klauzuli rozpoczynaj opis wielką literą, bez kropek np.:
@param name Player na którego działamy
, żadnych kropek i przecinków
Koniec pliku
Każdy plik powinien kończyć się pustą linią
Zasady umowne programowania
Użyj Optionals zamiast zwracania
null
w APIParametry metod, które mogą przyjąć wartość
null
muszą być oznaczone@Nullable
(z javax.*), domyślnie wszystkie parametry metod są oflagowane jako@Nonull
.Użyj «Google warunki <https://github.com/google/guava/wiki/PreconditionsExplained> dla zera- oraz kontroli argumentu.
W kierunku sedna sprawy - czyli o co mu chodzi?!
Podczas gdy namawiamy Ciebie, abyś przeczytał dokładnie Google Java conventions particularly, powstały dwa dość długie dokumenty. Zacznij szybko! Oto przykład poprawnie sformatowanego kodu:
/*
* 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);
}
}