JavaRush /Java Blogu /Random-AZ /Kod qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şə...

Kod qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər

Qrupda dərc edilmişdir
Kod yazma qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər - 1 Nə qədər tez-tez başqasının kodunu başa düşməli olmusunuz? Bir neçə saat əvəzinə, baş verənlərin məntiqini başa düşmək üçün günlər sərf etdiyiniz zaman. Gülməlisi odur ki, bu kodu yazan şəxs üçün hər şey aydın və çox şəffafdır. Və bu təəccüblü deyil: bütün bunlardan sonra mükəmməl və ya ideal kod çox qeyri-müəyyən bir anlayışdır, çünki hər bir tərtibatçının müvafiq olaraq dünya və kod haqqında öz baxışı var. Bir dəfədən çox belə bir vəziyyətlə qarşılaşdım ki, həmkarımla eyni koda baxdıq və onun düzgünlüyünə və təmizliyinə dair fərqli fikirlərə sahib olduq. Kod yazma qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər - 2Bu tanış hissdir, elə deyilmi? Bununla belə, riayət edilməli olan bəzi vaxtla sınaqdan keçirilmiş məqamlar var ki, bunlar da son nəticədə bizim xeyrimizə işləyəcək, çünki kodunu özünüz almaq istədiyiniz vəziyyətdə qoysanız, dünya bir az daha xoşbəxt olacaq və təmizləyici. Kod yazma qaydaları haqqında (daha doğrusu kiçik bələdçi) keçən məqaləmizdəKod yazma qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər - 3 bütövlükdə sistemin və onun obyektlər, onların interfeysləri, sinifləri, metodları və dəyişənləri kimi elementlərinin yazılması ilə bağlı tövsiyələrə bir az toxunduq. Orada bəzi elementlərin düzgün adlandırılmasını qısaca qeyd etdim. Bu gün mən məhz bu haqda danışmaq istərdim, çünki düzgün adlar kodun oxunmasını xeyli asanlaşdırır. Koddakı əkslər və kiçik şərh nümunələri ilə düzgün kod mövzusunu bağlayacağıq - bu yaxşıdır, yoxsa o qədər də yaxşı deyil. Beləliklə, başlayaq.

Düzgün adlandırma

Düzgün adlar kodun oxunuşunu yaxşılaşdırır, müvafiq olaraq tanışlığa vaxta qənaət edir, çünki ad onun funksionallığını təqribən təsvir etdikdə metoddan istifadə etmək daha asandır. Kodda hər şey adlardan (dəyişənlər, metodlar, siniflər, fayl obyektləri və s.) ibarət olduğundan, düzgün, təmiz kod yaratarkən bu məqam çox vacib olur. Yuxarıda göstərilənlərə əsasən, ad, məsələn, dəyişənin niyə mövcud olduğunu, nə etdiyini və necə istifadə edildiyini ifadə etməlidir. Mən dönə-dönə qeyd edəcəm ki, dəyişəni təsvir etmək üçün ən yaxşı şərh onun düzgün adıdır. Kod yazma qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər - 4

Adlandırma interfeysləri

İnterfeyslər adətən böyük hərflə başlayan və dəvə hərfində (CamelCase) yazılmış adlardan istifadə edir. Əvvəllər interfeys yazarkən onu interfeys kimi təyin etmək üçün I hərfi ilə prefiks qoymaq yaxşı təcrübə idi (məsələn, IUserService), lakin bu, olduqca çirkin və diqqəti yayındırır. Belə hallarda, onsuz (UserService) yazmaq və onun həyata keçirilməsinə -Impl (UserServiceImpl) əlavə etmək daha yaxşıdır. Yaxşı və ya son çarə olaraq onun həyata keçirilməsinə C (CUserService) prefiksini əlavə edin.

Sinif adları

İnterfeyslər kimi adlar da böyük hərflə yazılır və dəvə üslubundan (CamelCase) istifadə olunur. Nə cür apokalipsis baş verirsə etsin, son tarixlər nə qədər sürətli olursa olsun, amma heç vaxt, unutmayın ki, bir sinfin adı heç vaxt fel olmamalıdır! Sinif və obyekt adları isimlər və onların birləşmələri olmalıdır (UserController, UserDetails, UserAccount və s.). Siz hər bir sinfin adını bu proqramın abbreviaturası ilə təqdim etməməlisiniz, çünki bu, yalnız lazımsız mürəkkəblik əlavə edəcək (məsələn, bizdə İstifadəçi Məlumatlarının Miqrasiya proqramı var və biz hər sinfə UDM əlavə edəcəyik - UDMUserDeatils, UDMUserAccount, UDMUserController ).

Metod adları

Adətən metodların adları kiçik hərflə başlayır, lakin onlar da dəvə üslubundan (CamelCase) istifadə edirlər. Yuxarıda sinif adlarının heç vaxt feil olmamasından danışdıq. Burada vəziyyət diametrik olaraq əksinədir: metodların adları fe'llər və ya onların fe'llərlə birləşmələri olmalıdır: findUserById, findAllUsers, createUser və s. Metod (həmçinin dəyişənlər və siniflər) yaratarkən çaşqınlığın qarşısını almaq üçün bir adlandırma yanaşmasından istifadə edin. Məsələn, istifadəçi tapmaq üçün metod getUserById və ya findUserById kimi yazıla bilər. Və bir şey daha: üsul adlarında yumordan istifadə etməyin, çünki onlar zarafatı, eləcə də bu metodun nə etdiyini başa düşməyə bilərlər.

Dəyişən adlar

Əksər hallarda dəyişən adları kiçik hərflə başlayır və həmçinin dəyişənin qlobal sabit olduğu hallar istisna olmaqla, Camelcase hərfindən istifadə edir. Belə hallarda adın bütün hərfləri böyük hərflə yazılır və sözlər alt xətt - “_” ilə ayrılır. Dəyişənləri adlandırarkən, rahatlıq üçün mənalı kontekstdən istifadə edə bilərsiniz. Başqa sözlə, daha böyük bir şeyin bir hissəsi kimi dəyişən olduqda - məsələn, ad, soyad, status - belə hallarda bu dəyişənin hissəsi olduğu obyekti göstərən prefiks əlavə edə bilərsiniz. Məsələn: userFirstName, userLastName, userStatus. Siz həmçinin dəyişənlər üçün tamamilə fərqli mənalara malik olduqda oxşar adlardan istifadə etməkdən çəkinməlisiniz. Dəyişənlər üçün ümumi antonimlər:
  • başlamaq/bitmək
  • birinci/son
  • kilidli/kilidsiz
  • min/maks
  • sonrakı/əvvəlki
  • köhnə/yeni
  • açıldı/bağlandı
  • görünən/görünməz
  • mənbə/hədəf
  • mənbə/təyinat
  • yuxarı aşağı

Qısa dəyişən adları

X və ya n və ya buna bənzər dəyişənlərimiz olduqda, kodu yazan şəxsin niyyətini dərhal görmürük. n metodunun nə etdiyi aydın deyil: bu, daha çox düşünülmüş düşünmə tələb edir (və bu zaman, vaxt, vaxtdır). Məsələn, bizdə bir sahə var - məsul istifadəçinin id-si və x və ya sadəcə id kimi bəzi adların əvəzinə biz bu dəyişəni məsuliyyətliUserId adlandıracağıq ki, bu da dərhal oxunaqlılığı və mənalılığı artırır. Bununla belə, n kimi qısa adlar kiçik metodlara yerli dəyişikliklər kimi öz yerini tutur, burada həmin dəyişikliklə kod bloku sadəcə bir neçə kod sətirindən ibarətdir və metodun adı orada baş verənləri mükəmməl şəkildə təsvir edir. Belə bir dəyişəni görən bir tərtibatçı onun ikinci dərəcəli əhəmiyyətini və çox məhdud əhatə dairəsini başa düşür. Nəticədə dəyişənin adının uzunluğundan müəyyən dərəcədə asılılıq yaranır: nə qədər uzun olarsa, dəyişən bir o qədər qlobal olur və əksinə. Nümunə olaraq, tarixə görə son saxlanan istifadəçini tapmaq üçün bir üsul:
public User findLastUser() {
   return findAllUsers().stream()
           .sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
           .findFirst()
           .orElseThrow(() -> new ResourceNotFoundException("Any user doesn't exist "));
}
Burada axın sıralamasını təyin etmək üçün x və y qısa adlarından istifadə edirik və onları unuduruq.

Optimal uzunluq

Ad uzunluğu mövzusuna davam edək. Optimal ad uzunluğu maksimumNumberOfUsersInTheCurrentGroup ad uzunluğu ilə n arasındadır. Yəni çox qısa olanlar mənasızlıqdan əziyyət çəkir, çox uzun olanlar isə oxunaqlılıq əlavə etmədən proqramı uzadırlar və hər dəfə onları yazmağa tənbəl olurlar. Yuxarıdakı halı nəzərə almadan, n kimi qısa adı olan dəyişənlər üçün uzunluğu təxminən 8 -16 simvolda saxlamaq lazımdır. Bu ciddi bir qayda deyil: daha çox təlimatdır.

Kiçik fərqlər

Adlardakı incə fərqləri görməməzlikdən gələ bilmərəm, çünki bu da pis bir təcrübədir, çünki adlardakı kiçik fərqləri görmək üçün sadəcə çaşıb qala və ya çox vaxt sərf edə bilərsiniz. Məsələn, InvalidDataAccessApiUsageException və InvalidDataAccessResourceUsageException arasındakı fərqi bir baxışda görmək çətindir. Həmçinin, kiçik L və O-dan istifadə edərkən tez-tez dezinformasiya yarana bilər, çünki onlar asanlıqla 1 və 0 ilə qarışdırıla bilər: bəzi şriftlərdə fərq daha aydın, digərlərində isə daha az olur.

Semantik hissə

Semantik hissəni adlara qoymalıyıq, lakin sinonimlərlə həddindən artıq yükləməməliyik, çünki, məsələn, UserData və UserInfo əslində eyni mənaya malikdir və hansı konkret obyektə ehtiyacımız olduğunu başa düşmək üçün kodu bir az daha dərindən qazmalı olacağıq. . Məlumatsız sözlərdən çəkinin, məsələn, firstNameString: nə üçün bizə sətir sözü lazımdır? Ad tarix tipli obyekt ola bilərmi? Əlbəttə ki, yox: buna görə də, sadəcə olaraq - birinci ad. Nümunə olaraq, məntiqi dəyişənləri qeyd etmək istərdim, məsələn, flagDelete. Bayraq sözünün heç bir semantik mənası yoxdur. Bunu isDelete adlandırmaq daha məqsədəuyğun olardı.

Dezinformasiya

Yanlış adlandırma ilə bağlı bir neçə kəlmə də demək istərdim. Tutaq ki, bizdə userActivityList adı var və belə adlandırılan obyekt List tipli deyil, saxlama üçün başqa konteyner və ya fərdi obyektdir. Bu, orta proqramçını çaşdıra bilər: bunu userActivityGroup və ya userActivities kimi adlandırmaq daha yaxşı olardı.

Axtar

Qısa və sadə adların çatışmazlıqlarından biri odur ki, onları böyük miqdarda kodda tapmaq çətindir, çünki nə tapmaq daha asan olardı: name və ya NAME_FOR_DEFAULT_USER adlı dəyişən? Təbii ki, ikinci variant. Adlarda tez-tez rast gəlinən sözlərdən (hərflərdən) qaçınmaq lazımdır, çünki bu, axtarış zamanı yalnız tapılan faylların sayını artıracaq, bu da yaxşı deyil. Sizə xatırlatmaq istərdik ki, proqramçılar kodu yazmaqdansa, oxumağa daha çox vaxt sərf edirlər, ona görə də tətbiqinizin elementlərinin adlandırılmasına diqqət yetirin. Bəs onu uğurla adlandıra bilməsəniz nə olacaq? Əgər metodun adı onun funksionallığını yaxşı təsvir etmirsə? Bu, oyuna girdiyi yerdir, növbəti maddəmiz şərhlərdir.

Şərhlər

Kod yazma qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər - 5Müvafiq şərh kimi heç nə yoxdur, lakin heç bir modulu mənasız, köhnəlmiş və ya yanıltıcı şərhlər kimi qarışdırmır. Bu iki tərəfli qılıncdır, elə deyilmi? Yenə də şərhlərə birmənalı yaxşılıq kimi baxmamalısınız: daha az pislik kimi. Axı şərh, mahiyyətinə görə, kodda uğursuz ifadə edilmiş fikrin kompensasiyasıdır. Məsələn, çox qarışıq olduğu ortaya çıxarsa, metodun mahiyyətini bir şəkildə çatdırmaq üçün onlardan istifadə edirik. Belə bir vəziyyətdə, təsviri qeydlər yazmaqdansa, kodu düzgün şəkildə refaktor etmək daha yaxşıdır. Şərh nə qədər köhnə olsa, bir o qədər pisdir, çünki kod böyüməyə və təkamülə meyllidir, lakin şərh eyni qala bilər və irəli getdikcə bu qeydlər bir o qədər şübhəli olur. Qeyri-dəqiq şərhlər şərhsiz olmaqdan qat-qat pisdir, çünki onlar çaşdırır və aldadır, yalan gözləntilər verir. Çox çətin kodumuz olsa belə, yenə də onu şərh etməməyə, onu yenidən yazmağa dəyər.

Şərhlərin növləri

  • hüquqi şərhlər hüquqi səbəblərdən hər bir mənbə kodu faylının əvvəlində qalan şərhlərdir, məsələn:

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

  • informativ şərhlər - kodun izahını verən şərhlər (əlavə məlumat və ya kodun müəyyən hissəsinin niyyətini təmin edən).

    Nümunə olaraq:

    /*
    * Объединяет пользователя из бд и пришедшего для обновления
    * Когда в 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()
           );
           }

    Bu vəziyyətdə, şərhlər olmadan edə bilərsiniz, çünki metodun adı və onun arqumentləri çox şəffaf funksionallıqla birlikdə özlərini olduqca yaxşı təsvir edir.

  • xəbərdarlıq şərhi - məqsədi bəzi hərəkətlərin arzuolunmaz nəticələri barədə digər tərtibatçıları xəbərdar etmək olan şərh (məsələn, testin niyə @Ignore kimi qeyd edilməsi):

    // Слишком долго отрабатывает
    // Не запускайте, если не располагаете избытком времени
    @Ignore
    @Test
    public void someIntegrationTest() {
           ……
           }
  • TODO - yerinə yetirilməsi lazım olan, lakin nədənsə indi etmək mümkün olmayan gələcək üçün qeydlər olan şərhlər. Bu, yaxşı təcrübədir, lakin qarışıqlığın qarşısını almaq üçün uyğun olmayanları aradan qaldırmaq üçün hələ də mütəmadi olaraq nəzərdən keçirilməlidir.

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

    //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 контекста) с тем, кто сохранил.

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

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

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

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

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

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

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

Kod yazma qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər - 7
  • бормочущий комментарий — комментарии, которые обычно пишут на скорую руку, смысл которых понятен только разработчику, писавшего их, так How только он видит ту ситуацию с теми нюансами, на которые он и ссылается.

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

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

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

  • избыточный комментарий — комментарий, который не несёт смысловой нагрузки, так How и так понятно что происходит в заданном участке 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();
    }

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

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

    Пример:

    /**
    *  Creation пользователя по переданным параметрам
    * @param firstName Name созданного пользователя
    * @param middleName среднее Name созданного пользователя
    * @param lastName фамorя созданного пользователя
    * @param age возраст созданного пользователя
    * @param address addressс созданного пользователя
    * @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а.

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

    * @author  Bender Benderovich

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

  • şərh edilmiş kod bu və ya digər səbəbdən şərh edilmiş koddur. Ən pis vərdişlərdən biri, çünki siz bunu şərh etdiniz və unutmusunuz və digər tərtibatçıların sadəcə onu silməyə cəsarətləri yoxdur (əgər bu dəyərli bir şeydirsə).

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

    Nəticədə zibil kimi yığılır. Heç bir halda belə kod buraxılmamalıdır. Həqiqətən ehtiyacınız varsa, versiyaya nəzarət sistemi haqqında unutmayın.

  • qeyri-aşkar şərhlər bir şeyi lazımsız dərəcədə mürəkkəb şəkildə təsvir edən şərhlərdir.

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

    Şərh kodu izah etməlidir, izahata ehtiyac yoxdur. Burada nə var? “Filtr baytları” nədir? +1-in bununla nə əlaqəsi var? Niyə məhz 300?

Şərh yazmaq qərarına gəlsəniz, onlardan istifadə etmək üçün bir neçə ipucu:
  1. Saxlanması asan olan üslublardan istifadə edin: çox dəbdəbəli və ekzotik üslubları saxlamaq zəhlətökən və vaxt apara bilər.
  2. Tək sətirlərə istinad edən sətirlərin sonunda şərhlərdən istifadə etməyin: bu, böyük şərh yığını yaradır və hər sətir üçün ifadəli şərh tapmaq çətindir.
  3. Şərh yaratarkən “necə” yox, “niyə” sualına cavab verməyə çalışın.
  4. İxtisarlardan çəkinin. Yuxarıda dediyim kimi şərhə izaha ehtiyacımız yoxdur: şərh izahdır.
  5. Siz ölçü vahidlərini və məqbul dəyərlər diapazonunu qeyd etmək üçün şərhlərdən istifadə edə bilərsiniz.
  6. Şərhləri təsvir etdikləri koda yaxın qoyun.
Nəticə olaraq, yenə də xatırlatmaq istərdim: ən yaxşı şərhlər şərhin olmaması və bunun əvəzinə tətbiqdə düzgün adlandırmadır. Bir qayda olaraq, biz çox vaxt hazır kodla işləyəcəyik, onu saxlayacağıq və genişləndirəcəyik. Bu kodun oxunması və başa düşülməsi asan olduqda daha rahatdır, çünki pis kod mane olur, təkərlərə nitq qoyur və tələskənlik onun sadiq yoldaşıdır. Və nə qədər pis kodumuz varsa, performans da bir o qədər aşağı düşür, ona görə də biz vaxtaşırı refaktorla məşğul olmalıyıq. Ancaq əvvəldən kod yazmağa çalışırsınızsa, onun üçün sonrakı tərtibatçılar sizi tapmaq və öldürmək istəməzlər, onda daha az tez-tez refaktor etməlisiniz. Ancaq yenə də lazım olacaq, çünki məhsul üçün şərtlər və tələblər daim dəyişir, əlavə əlaqələr əlavə etməklə tamamlanır və bundan qaçmaq mümkün deyil. Nəhayət, bu mövzu ilə tanış olmanız üçün bir neçə maraqlı link buraxacağam , burada , buradaburada deyəsən, bu gün mənim üçün hamısıdır, oxuyan hər kəsə təşəkkür edirəm)) Kod yazma qaydaları: düzgün adlandırmanın gücü, yaxşı və pis şərhlər - 8
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION