JavaRush /Java-Blog /Random-DE /Kodexregeln: Die Macht der richtigen Benennung, guter und...

Kodexregeln: Die Macht der richtigen Benennung, guter und schlechter Kommentare

Veröffentlicht in der Gruppe Random-DE
Regeln für das Schreiben von Code: die Macht der korrekten Benennung, gute und schlechte Kommentare – 1 Wie oft mussten Sie den Code eines anderen verstehen? Wenn man statt ein paar Stunden Tage damit verbringt, die Logik dessen zu verstehen, was passiert. Das Lustige ist, dass für die Person, die diesen Code geschrieben hat, alles klar und sehr transparent ist. Und das ist nicht überraschend: Schließlich ist perfekter oder idealer Code ein sehr vages Konzept, da jeder Entwickler seine eigene Vision der Welt bzw. des Codes hat. Mehr als einmal bin ich auf eine Situation gestoßen, in der mein Kollege und ich uns denselben Code angesehen haben und unterschiedliche Meinungen über seine Korrektheit und Sauberkeit hatten. Regeln für das Schreiben von Code: die Macht der korrekten Benennung, gute und schlechte Kommentare – 2Es ist ein vertrautes Gefühl, nicht wahr? Allerdings gibt es einige bewährte Punkte, die beachtet werden sollten, was uns am Ende in die Hände spielt, denn wenn Sie Ihren Code in dem Zustand belassen, in dem Sie ihn selbst gerne erhalten würden, wäre die Welt ein bisschen kleiner glücklicher und sauberer. Regeln für das Schreiben von Code: die Macht der korrekten Benennung, gute und schlechte Kommentare – 3In unserem letzten Artikel über die Regeln zum Schreiben von Code (oder besser gesagt einem kleinen Leitfaden) haben wir ein wenig auf die Empfehlungen zum Schreiben des Systems als Ganzes und seiner Elemente wie Objekte, deren Schnittstellen, Klassen, Methoden und Variablen eingegangen. Dort habe ich kurz die korrekte Benennung bestimmter Elemente erwähnt. Heute möchte ich genau darüber sprechen, denn richtige Namen erleichtern die Lesbarkeit des Codes erheblich. Das Thema korrekter Code schließen wir mit Hilfe von Überlegungen und kleinen Beispielkommentaren im Code ab – ist dieser gut oder nicht so gut? Also lasst uns anfangen.

Richtige Benennung

Richtige Namen verbessern die Lesbarkeit des Codes und sparen dementsprechend Zeit bei der Einarbeitung, da es viel einfacher ist, eine Methode zu verwenden, wenn der Name ihre Funktionalität grob beschreibt. Da alles im Code aus Namen besteht (Variablen, Methoden, Klassen, Dateiobjekte usw.), ist dieser Punkt für die Erstellung korrekten, sauberen Codes sehr wichtig. Basierend auf dem oben Gesagten sollte der Name die Bedeutung vermitteln, warum beispielsweise eine Variable existiert, was sie tut und wie sie verwendet wird. Ich werde immer wieder darauf hinweisen, dass der beste Kommentar zur Beschreibung einer Variablen ihr korrekter Name ist. Regeln für das Schreiben von Code: die Macht der korrekten Benennung, gute und schlechte Kommentare – 4

Benennung von Schnittstellen

Schnittstellen verwenden normalerweise Namen, die mit einem Großbuchstaben beginnen und in Kamel-Schreibweise (CamelCase) geschrieben werden. Früher war es eine gute Praxis, beim Schreiben einer Schnittstelle ein I voranzustellen, um sie als Schnittstelle zu kennzeichnen (z. B. IUserService), aber das ist ziemlich hässlich und lenkt ab. In solchen Fällen ist es besser, ohne (UserService) zu schreiben und -Impl (UserServiceImpl) zu seiner Implementierung hinzuzufügen. Nun, oder fügen Sie als letzten Ausweg das Präfix C (CUserService) zu seiner Implementierung hinzu.

Klassennamen

Genau wie Schnittstellen werden Namen großgeschrieben und verwenden den Kamelstil (CamelCase). Egal welche Art von Apokalypse gerade passiert, egal wie schnell die Fristen sind, aber denken Sie niemals daran, der Name einer Klasse sollte niemals ein Verb sein! Klassen- und Objektnamen müssen Substantive und deren Kombinationen sein (UserController, UserDetails, UserAccount usw.). Sie sollten den Namen jeder Klasse nicht mit der Abkürzung dieser Anwendung angeben, da dies nur unnötige Komplexität erhöht (wir haben beispielsweise eine Anwendung zur Benutzerdatenmigration und fügen jeder Klasse ein UDM hinzu – UDMUserDeatils, UDMUserAccount, UDMUserController). ).

Methodennamen

Normalerweise beginnen die Methodennamen mit einem Kleinbuchstaben, sie verwenden jedoch auch den Kamelstil (CamelCase). Oben haben wir darüber gesprochen, dass Klassennamen niemals Verben sein sollten. Hier ist die Situation genau umgekehrt: Die Namen der Methoden müssen Verben oder deren Kombinationen mit Verben sein: findUserById, findAllUsers, createUser usw. Um Verwirrung zu vermeiden, verwenden Sie beim Erstellen einer Methode (sowie von Variablen und Klassen) einen Namensansatz. Um beispielsweise einen Benutzer zu finden, kann die Methode als getUserById oder findUserById geschrieben werden. Und noch etwas: Verwenden Sie keinen Humor in den Namen von Methoden, da diese den Witz und die Wirkung dieser Methode möglicherweise nicht verstehen.

Variablennamen

In den meisten Fällen beginnen Variablennamen mit einem Kleinbuchstaben und verwenden auch Camelcase, außer in Fällen, in denen die Variable eine globale Konstante ist. In solchen Fällen werden alle Buchstaben des Namens in Großbuchstaben geschrieben und die Wörter werden durch einen Unterstrich – „_“ – getrennt. Beim Benennen von Variablen können Sie der Einfachheit halber einen aussagekräftigen Kontext verwenden. Mit anderen Worten: Wenn eine Variable Teil von etwas Größerem ist – zum Beispiel Vorname, Nachname, Status – können Sie in solchen Fällen ein Präfix hinzufügen, das das Objekt angibt, zu dem diese Variable gehört. Zum Beispiel: userFirstName, userLastName, userStatus. Sie müssen auch ähnliche Namen für Variablen vermeiden, wenn diese völlig unterschiedliche Bedeutungen haben. Häufige Antonyme für Variablen:
  • Anfang/Ende
  • erster/letzter
  • gesperrt/entsperrt
  • Minimal Maximal
  • weiter zurück
  • alt neu
  • geöffnet/geschlossen
  • sichtbar/unsichtbar
  • Quellenziel
  • Zielort
  • oben unten

Kurze Variablennamen

Wenn wir Variablen wie x oder n oder ähnliches haben, erkennen wir nicht sofort die Absicht der Person, die den Code geschrieben hat. Es ist nicht offensichtlich, was Methode n bewirkt: Sie erfordert mehr nachdenkliches Denken (und das ist Zeit, Zeit, Zeit). Wir haben zum Beispiel ein Feld – die ID des verantwortlichen Benutzers, und statt eines Namens wie x oder einfach nur id nennen wir diese Variable „ResponsibleUserId“, was die Lesbarkeit und Aussagekraft sofort erhöht. Kurznamen wie n haben jedoch ihre Berechtigung als lokale Änderungen an kleinen Methoden, bei denen der Codeblock mit dieser Änderung nur ein paar Codezeilen umfasst und der Methodenname perfekt beschreibt, was dort passiert. Wenn ein Entwickler eine solche Variable sieht, erkennt er deren zweitrangige Bedeutung und ihren sehr begrenzten Umfang. Dadurch besteht eine gewisse Abhängigkeit von der Länge des Variablennamens: Je länger er ist, desto globaler ist die Variable und umgekehrt. Als Beispiel eine Methode zum Suchen des zuletzt gespeicherten Benutzers nach Datum:
public User findLastUser() {
   return findAllUsers().stream()
           .sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
           .findFirst()
           .orElseThrow(() -> new ResourceNotFoundException("Any user doesn't exist "));
}
Hier verwenden wir die Kurznamen x und y, um die Stream-Sortierung festzulegen, und vergessen sie.

Optimale Länge

Fahren wir mit dem Thema Namenslänge fort. Die optimale Namenslänge liegt irgendwo zwischen der maximalen Namenslänge NumberOfUsersInTheCurrentGroup und n. Das heißt, zu kurze Texte haben keinen Sinn, zu lange überfordern das Programm, ohne die Lesbarkeit zu verbessern, und sie sind einfach zu faul, sie jedes Mal zu schreiben. Wenn Sie den obigen Fall nicht berücksichtigen, müssen Sie für Variablen mit einem Kurznamen wie n die Länge auf etwa 8 bis 16 Zeichen beschränken. Dabei handelt es sich nicht um eine strenge Regel, sondern eher um eine Richtlinie.

Kleine Unterschiede

Ich kann subtile Unterschiede in den Namen nicht ignorieren, da dies ebenfalls eine schlechte Praxis ist, da man einfach verwirrt sein kann oder viel zusätzliche Zeit damit verbringt, geringfügige Unterschiede in den Namen zu bemerken. Beispielsweise ist der Unterschied zwischen InvalidDataAccessApiUsageException und InvalidDataAccessResourceUsageException auf den ersten Blick schwer zu erkennen. Auch bei der Verwendung kleiner L und O kann es häufig zu Fehlinformationen kommen, da diese leicht mit 1 und 0 verwechselt werden können: Bei manchen Schriftarten ist der Unterschied offensichtlicher, bei anderen weniger.

Semantischer Teil

Wir müssen den semantischen Teil in die Namen einbauen, aber nicht mit Synonymen übertreiben, da beispielsweise UserData und UserInfo tatsächlich die gleiche Bedeutung haben und wir etwas tiefer in den Code eintauchen müssen, um zu verstehen, welches spezifische Objekt wir benötigen . Vermeiden Sie nicht aussagekräftige Wörter, zum Beispiel „firstNameString“: Warum brauchen wir die Wortfolge? Kann ein Name ein Datumsobjekt sein? Natürlich nicht: also einfach - Vorname. Als Beispiel möchte ich boolesche Variablen nennen, zum Beispiel flagDelete. Das Wort Flagge hat keine semantische Bedeutung. Es wäre vernünftiger gewesen, es „isDelete“ zu nennen.

Desinformation

Ich möchte auch noch ein paar Worte zur falschen Namensgebung sagen. Nehmen wir an, wir haben den Namen „userActivityList“ und das so benannte Objekt ist nicht vom Typ „Liste“, sondern ein anderer Container oder ein benutzerdefiniertes Objekt zur Speicherung. Dies kann den durchschnittlichen Programmierer verwirren: Es wäre besser, es so etwas wie „userActivityGroup“ oder „userActivities“ zu nennen.

Suchen

Einer der Nachteile kurzer und einfacher Namen besteht darin, dass sie in einer großen Codemenge schwer zu finden sind, denn was wäre einfacher zu finden: eine Variable namens name oder NAME_FOR_DEFAULT_USER? Natürlich die zweite Option. Es ist notwendig, häufig vorkommende Wörter (Buchstaben) in den Namen zu vermeiden, da dies nur die Anzahl der bei der Suche gefundenen Dateien erhöht, was nicht gut ist. Wir möchten Sie daran erinnern, dass Programmierer mehr Zeit damit verbringen, Code zu lesen als ihn zu schreiben. Achten Sie daher auf die Benennung der Elemente Ihrer Anwendung. Was aber, wenn es Ihnen nicht gelingt, es erfolgreich zu benennen? Was passiert, wenn der Name einer Methode ihre Funktionalität nicht gut beschreibt? Hier kommt es ins Spiel, unser nächster Punkt sind Kommentare.

Kommentare

Regeln zum Schreiben von Code: die Kraft der richtigen Benennung, gute und schlechte Kommentare – 5Es gibt nichts Schöneres als einen relevanten Kommentar, aber nichts überfüllt ein Modul so sehr wie bedeutungslose, veraltete oder irreführende Kommentare. Es ist ein zweischneidiges Schwert, nicht wahr? Dennoch sollten Sie Kommentare nicht als eindeutiges Gut, sondern eher als geringeres Übel betrachten. Schließlich ist ein Kommentar im Wesentlichen eine Entschädigung für einen erfolglos ausgedrückten Gedanken im Code. Wir nutzen sie zum Beispiel, um das Wesentliche der Methode irgendwie zu vermitteln, wenn sie sich als zu verwirrend herausstellt. In einer solchen Situation ist es besser, den Code korrekt umzugestalten, als beschreibende Notizen zu schreiben. Je älter der Kommentar, desto schlimmer, denn der Code neigt dazu, zu wachsen und sich weiterzuentwickeln, aber der Kommentar kann derselbe bleiben, und je weiter er geht, desto zweifelhafter werden diese Notizen. Ungenaue Kommentare sind viel schlimmer als keine Kommentare, weil sie verwirren und täuschen und falsche Erwartungen wecken. Und selbst wenn wir einen sehr kniffligen Code haben, lohnt es sich dennoch, ihn nicht zu kommentieren, sondern ihn neu zu schreiben.

Arten von Kommentaren

  • Rechtliche Kommentare sind Kommentare, die aus rechtlichen Gründen am Anfang jeder Quellcodedatei hinterlassen werden, wie zum Beispiel:

    * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
    * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.

  • informative Kommentare – Kommentare, die eine Erläuterung des Codes liefern (zusätzliche Informationen oder die Absicht eines bestimmten Codeabschnitts bereitstellen).

    Als Beispiel:

    /*
    * Объединяет пользователя из бд и пришедшего для обновления
    * Когда в requestUser поле пустое, оно заполняется старыми данными из foundUser
    */
    private User mergeUser(User requestUser, User foundUser) {
           return new User(
           foundUser.getId(),
           requestUser.getFirstName() == null ? requestUser.getFirstName() : foundUser.getFirstName(),
           requestUser.getMiddleName() == null ? requestUser.getMiddleName() : foundUser.getMiddleName(),
           requestUser.getLastName() == null ? requestUser.getLastName() : foundUser.getLastName(),
           requestUser.getAge() == null ? requestUser.getAge() : foundUser.getAge()
           );
           }

    In diesem Fall kann auf Kommentare verzichtet werden, da sich der Name der Methode und ihre Argumente, gepaart mit der sehr transparenten Funktionalität, recht gut beschreiben.

  • Warnkommentar – ein Kommentar, dessen Zweck darin besteht, andere Entwickler vor den unerwünschten Folgen einer Aktion zu warnen (z. B. warum der Test als @Ignore markiert wurde):

    // Слишком долго отрабатывает
    // Не запускайте, если не располагаете избытком времени
    @Ignore
    @Test
    public void someIntegrationTest() {
           ……
           }
  • TODO – Kommentare, bei denen es sich um Notizen für die Zukunft handelt, die gemacht werden müssen, aber aus irgendeinem Grund jetzt nicht gemacht werden können. Dies ist eine bewährte Vorgehensweise, sie müssen jedoch regelmäßig überprüft werden, um irrelevante zu entfernen und Unordnung zu vermeiden.

    Примером послужит:

    //TODO: Add a check for the current user ID (when will be created security context)
    
    @Override
    public Resource downloadFile(File file) {
           return fileManager.download(file);
           }

    Тут мы помечаем, что нужно добавить проверку юзера, который скачивает (id которого мы вытащим из security контекста) с тем, кто сохранил.

  • усoderвающий комментарий — комментарий, подчеркивающий важность Wieого-то обстоятельства, что на первый взгляд может показаться несущественным.

    Как пример, кусочек метода, заполняющий тестовую БД, некими скриптами:

    Stream.of(IOUtils.resourceToString("/fill-scripts/" + x, StandardCharsets.UTF_8)
           .trim()
           .split(";"))
           .forEach(jdbcTemplate::update);
    // Вызов trim() очень важен, убирает возможные пробелы в конце скрипта
    // чтобы при считке и разбивке на отдельные Anfrageы не было пустых

  • javaDoc — комментарии, которые описывают API определенного функционала для общего пользования. Наверное, самые полезные комментарии, так Wie с dokumentierenированным API в разы легче работать, но они также могут устаревать, Wie и любые другие. Поэтому не забываем, что главный вклад в dokumentierenацию вносится не комментариями, а хорошим Codeом.

    Пример вполне обычного метода обновления пользователя:

    /**
    * Обновляет передаваемые поля для пользователя по id.
    *
    * @param id  id обновляемого пользователя
    * @param user пользователь с заполненными полями для обновления
    * @return обновленный пользователь
    */
           User update(Long id, User user);

Плохие сценарии комментариев

Regeln zum Schreiben von Code: die Kraft der richtigen Benennung, gute und schlechte Kommentare – 7
  • бормочущий комментарий — комментарии, которые обычно пишут на скорую руку, смысл которых понятен только разработчику, писавшего их, так Wie только он видит ту ситуацию с теми нюансами, на которые он и ссылается.

    Рассмотрим данный пример:

    public void configureSomeSystem() {
           try{
           String configPath = filesLocation.concat("/").concat(CONFIGURATION_FILE);
           FileInputStream stream = new FileInputStream(configPath);
           }  catch (FileNotFoundException e) {
           //В случае отсутствия конфигурационного Datei, загружается конфигурация по умолчанию
          }
    }

    Кто загружает эти настройки? Были ли они загружены ранее? Метод предназначен для перехвата исключений и вызова дефолтных настроек? Слишком много вопросов возникает, ответы на которые можно получить лишь углубившись в изучение других частей системы.

  • избыточный комментарий — комментарий, который не несёт смысловой нагрузки, так Wie и так понятно что происходит в заданном участке Codeа (он читается не проще, чем Code).

    Смотрим пример:

    public class JdbcConnection{
    public class JdbcConnection{
       /**
        * Журнальный компонент, связанный с текущим классом
        */
       private Logger log = Logger.getLogger(JdbcConnection.class.getName());
    
       /**
        * Создаёт и возвращает connection с помощью входящих параметров
        */
       public static Connection buildConnection(String url, String login, String password, String driver) throws Exception {
           Class.forName(driver);
           connection = DriverManager.getConnection(url, login, password);
           log.info("Created connection with db");
           return connection;
       }

    Какой смысл таких комментариев, если мы и так всё прекрасно видим

  • недостоверные комментарии — комментарии, не соответствующие истине и лишь вгоняющие в заблуждение (дезинформирующие). Как например:

    /**
    * Вспомогательный метод, закрывает соединение со сканером, если isNotUsing истинно
    */
    private void scanClose(Scanner scan, boolean isNotUsing) throws Exception {
       if (!isNotUsing) {
           throw new Exception("The scanner is still in use");
       } scan.close();
    }

    Was в этом комменте не так? А то, что он немножко врёт нам, ведь соединение закрывается, если isNotUsing = false, но ниWie не наоборот, Wie нам вещает пометка.

  • обязательные комментарии — комментарии, которые считают обязательными (Javadoc), но кои по факту иногда бывают излишне нагромождающими, недостоверными и ненужными (нужно задуматься, а нужны ли здесь такие комментарии).

    Пример:

    /**
    *  Schaffung пользователя по переданным параметрам
    * @param firstName Name созданного пользователя
    * @param middleName среднее Name созданного пользователя
    * @param lastName фамoderя созданного пользователя
    * @param age возраст созданного пользователя
    * @param address Adresseс созданного пользователя
    * @return пользователь который был создан
    */
    User createNewUser(String firstName, String middleName, String lastName, String age, String address);

    Смогли бы вы понять, что делает метод без этих комментариев? Скорее всего да, поэтому комментарии в этом случае стают бессмысленными.

  • журнальные комментарии — комментарии, которые иногда добавляют в начало модуля, при каждом его редактировании (что-то вроде журнала вносимых изменений).

    /**
    *  Записи ведутся с 09 января 2020;
    **********************************************************************
    *  09.01.2020  : Обеспечение соединения с БД с помощью Jdbc Connection;
    *  15.01.2020  : Добавление интерфейсов уровня дао для работы с БД;
    *  23.01.2020  : Добавление интеграционных тестов для БД;
    *  28.01.2020  : Имплементация интерфейсов уровня дао;
    *  01.02.2020  : Разработка интерфейсов для сервисов,
    *  согласно требованиям прописанным в user stories;
    *  16.02.2020  : Имплементация интерфейсов сервисов
    *  (реализация бизнес логики связанной с работой БД);
    *  25.02.2020  : Добавление тестов для сервисов;
    *  08.03.2020  : Празднование восьмого марта(Миша опять в хлам);
    *  21.03.2020  : Рефакторинг сервис слоя;
    */

    Когда-то этот проход был оправдан, но с появлением систем управления исходным Codeом (например — Git), это стало лишним нагромождением и усложнением Codeа.

  • комментарии ссылки на авторов — комментарии, преднаBedeutungм которых является, указание человека, писавшего Code, чтобы можно было связаться и обсудить, Wie что и зачем:

    * @author  Bender Benderovich

    Опять же, системы контроля версий прекрасно запоминают, кто и когда добавил данный Code, и подобный подход излишен.

  • Kommentierter Code ist Code, der aus dem einen oder anderen Grund auskommentiert wurde. Eine der schlimmsten Angewohnheiten, weil Sie es auskommentiert und vergessen haben und andere Entwickler einfach nicht den Mut haben, es zu löschen (was, wenn es etwas Wertvolles ist).

    //    public void someMethod(SomeObject obj) {
    //    .....
    //    }

    Dadurch sammelt es sich wie Müll an. Unter keinen Umständen sollte ein solcher Code zurückgelassen werden. Wenn Sie es wirklich brauchen, vergessen Sie nicht das Versionskontrollsystem.

  • Nicht offensichtliche Kommentare sind Kommentare, die etwas unnötig komplex beschreiben.

    /*
        * Начать с массива, размер которого достаточен для хранения
        * всех Byteов данных (плюс Byteы фильтра) с запасом, плюс 300 Byte
        * для данных заголовка
        */
    this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];

    Ein Kommentar sollte den Code erläutern und nicht selbst eine Erklärung erfordern. Was ist denn hier los? Was sind „Filterbytes“? Was hat +1 damit zu tun? Warum genau 300?

Wenn Sie sich dazu entschließen, Kommentare zu schreiben, finden Sie hier einige Tipps für deren Verwendung:
  1. Verwenden Sie Stile, die leicht zu pflegen sind: Die Pflege von Stilen, die zu ausgefallen und exotisch sind, kann lästig und zeitaufwändig sein.
  2. Verwenden Sie keine Kommentare am Ende von Zeilen, die sich auf einzelne Zeilen beziehen: Dadurch entsteht ein großer Kommentarstapel, und es ist schwierig, für jede Zeile einen aussagekräftigen Kommentar zu finden.
  3. Versuchen Sie beim Erstellen eines Kommentars, die Frage „Warum“ und nicht „Wie“ zu beantworten.
  4. Vermeiden Sie Abkürzungen. Wie ich oben sagte, brauchen wir keine Erklärung für den Kommentar: Der Kommentar ist die Erklärung.
  5. Sie können Kommentare verwenden, um die Maßeinheiten und den Bereich akzeptabler Werte zu kennzeichnen.
  6. Platzieren Sie Kommentare in der Nähe des Codes, den sie beschreiben.
Deshalb möchte ich Sie noch einmal daran erinnern: Die besten Kommentare sind das Fehlen eines Kommentars und stattdessen die richtige Nennung in der Bewerbung. In der Regel werden wir die meiste Zeit bereits mit vorgefertigtem Code arbeiten, diesen pflegen und erweitern. Es ist viel bequemer, wenn dieser Code leicht zu lesen und zu verstehen ist, denn schlechter Code stört, macht einem einen Strich durch die Rechnung und Eile ist sein treuer Begleiter. Und je mehr fehlerhaften Code wir haben, desto stärker sinkt die Leistung, sodass wir von Zeit zu Zeit eine Umgestaltung vornehmen müssen. Wenn Sie jedoch von Anfang an versuchen, Code zu schreiben, für den spätere Entwickler Sie nicht finden und töten wollen, müssen Sie ihn seltener umgestalten. Aber es wird trotzdem notwendig sein, da sich die Bedingungen und Anforderungen an das Produkt ständig ändern, ergänzt durch das Hinzufügen zusätzlicher Verbindungen, und daran führt kein Weg vorbei. Abschließend hinterlasse ich hier , hier und hier noch ein paar interessante Links, damit Sie sich mit diesem Thema vertraut machen können . Ich schätze, das ist alles für mich heute, vielen Dank an alle, die es gelesen haben)) Regeln zum Schreiben von Code: die Kraft der richtigen Benennung, gute und schlechte Kommentare – 8
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION