CodeGym /Java Blogu /Rastgele /Kodlama Kuralları: Doğru İsimlerin, İyi ve Kötü Yorumları...
John Squirrels
Seviye
San Francisco

Kodlama Kuralları: Doğru İsimlerin, İyi ve Kötü Yorumların Gücü

grupta yayınlandı
Kodlama Kuralları: Doğru İsimlerin, İyi ve Kötü Yorumların Gücü - 1Ne sıklıkla başka birinin kodunu kazmak zorunda kaldınız? İki saat yerine, sadece olan bitenin mantığını anlamak için iki gün harcayabilirsiniz. Komik olan şu ki, kodu yazan kişi için her şey açık ve tamamen şeffaf. Bu şaşırtıcı değil: Sonuçta, mükemmel kod çok belirsiz bir kavram çünkü her geliştiricinin de kendi dünya ve kod vizyonu var. Bir iş arkadaşımla aynı koda baktığımız ve doğruluğu ve temizliği hakkında farklı görüşlere sahip olduğumuz bir durumda birden çok kez bulundum.Kodlama kuralları: doğru isimlerin gücü, iyi ve kötü yorumlar - 2Tanıdık geliyor, değil mi? Yine de, uyulması gereken zaman içinde test edilmiş bazı ilkeler vardır. Sonunda sizin için avantajlı olacaklar çünkü kodunuzu almak istediğiniz durumda bırakırsanız, dünya biraz daha mutlu ve temiz hale gelir. Bir önceki yazımızda(veya daha doğrusu, küçük kılavuz) kodlama kuralları hakkında, bir sistemi bir bütün olarak ve nesneler, arayüzler, sınıflar, yöntemler ve değişkenler gibi onu oluşturan parçalar olarak yazmak için küçük bir öneri anlayışımız var. Aynı makalede gelişigüzel bir şekilde belirli öğelerin doğru adlandırılmasından bahsetmiştim. Bugün bundan bahsetmek istiyorum çünkü doğru isimler kodun okunmasını birçok kez kolaylaştırır. Doğru kod konusunu bazı yansımalar, koddaki küçük yorum örnekleri ve bunun iyi olup olmadığı üzerine bir değerlendirme ile kapatacağız. Pekala, başlayalım.

Doğru isimler

Doğru adlar kodun okunabilirliğini artırır, böylece kodu tanımak için gereken süreyi azaltır, çünkü adı kabaca işlevselliğini tanımladığında bir yöntemi kullanmak çok daha kolaydır. Koddaki her şey isimlerden (değişkenler, yöntemler, sınıflar, nesneler, dosyalar vb.) oluşur, bu nedenle doğru, temiz kod oluştururken bu nokta çok önemli hale gelir. Yukarıdakilere dayanarak, ad, örneğin değişkenin neden var olduğu, ne yaptığı ve nasıl kullanıldığı gibi anlamlar taşımalıdır. Bir değişken için en iyi yorumun ona iyi bir isim vermek olduğunu defalarca not edeceğim.Kodlama kuralları: doğru isimlerin gücü, iyi ve kötü yorumlar - 3

"Sherlock" dizisinden (2010-2017)

Arayüzleri adlandırma

Arabirimlerin genellikle büyük harfle başlayan ve CamelCase ile yazılan adları vardır. Bir arayüz yazarken, onu bir arayüz (örneğin, IUserService) olarak belirtmek için "I" ön ekini eklemek iyi bir uygulama olarak kabul edilirdi, ancak bu oldukça çirkin ve dikkat dağıtıcı görünüyor. Bu gibi durumlarda, öneki (UserService) çıkarmak ve uygulamanın adına bir sonek olarak "Impl" eklemek daha iyidir (örn. UserServiceImpl). Ya da son çare olarak uygulamanın adına bir "C" öneki ekleyin (örn. CUserService).

sınıf isimleri

Tıpkı arabirimler gibi, sınıf adları da büyük harfle yazılır ve CamelCase'i kullanır. Bir zombi kıyametiyle karşı karşıya olmamızın bir önemi yok, sonun yakın olup olmamasının da bir önemi yok — asla, asla, asla bir sınıfın adı fiil olmamalı! Sınıf ve nesne adları isimler veya bileşik isimler olmalıdır (UserController, UserDetails, UserAccount vb.). Uygulamanın kısaltmasını her sınıfın adının sonuna yapıştırmamalısınız, çünkü bu sadece gereksiz bir karmaşıklık katacaktır. Örneğin, bir Kullanıcı Verisi Taşıma uygulamamız varsa, lütfen her sınıfa "UDM" eklemeyin, yani UDMUserDetails, UDMUserAccount, UDMUserController.

Yöntem adları

Yöntem adları genellikle küçük harfle başlar, ancak aynı zamanda camel case stilini (camelCase) kullanırlar. Yukarıda, sınıf isimlerinin asla fiil olmaması gerektiğini söylemiştik. Burada durum tam tersidir: yöntemlerin adları fiiller veya fiil tümceleri olmalıdır: findUserById, findAllUsers, createUser, vb. Bir yöntem (ayrıca değişkenler ve sınıflar) oluştururken, karışıklığı önlemek için tutarlı bir adlandırma kuralı kullanın. Örneğin, bir kullanıcı bulmak için bir yöntem getUserById veya findUserById olarak adlandırılabilir. Ve bir şey daha: yöntemlerin adlarında mizah kullanmayın, çünkü başkaları espriyi anlamayabilir. Sonuç olarak, yöntemin ne yaptığını anlayamayabilirler.

Değişken adları

Çoğu durumda, değişken adları küçük harfle başlar ve değişkenin global bir sabit olduğu durumlar dışında camelCase'i de kullanır. Bu gibi durumlarda ismin tüm harfleri büyük yazılır ve kelimeler alt çizgi ("_") ile ayrılır. Kolaylık sağlamak için, değişkenleri adlandırırken anlamlı bağlam kullanabilirsiniz. Başka bir deyişle, bir değişken daha büyük bir şeyin parçası olarak var olduğunda, örneğin firstName, lastName veya status. Bu gibi durumlarda, bu değişkenin ait olduğu nesneyi gösteren bir önek ekleyebilirsiniz. Örneğin: userFirstName, userLastName, userStatus. Tamamen farklı anlamlara sahip olduklarında değişkenler için benzer adlardan da kaçınmalısınız. Değişken adlarında sıklıkla karşılaşılan bazı zıt anlamlı sözcükler şunlardır:
  • başlangıç/bitiş
  • ilk son
  • kilitli/kilidi açık
  • en az en çok
  • Sonraki önceki
  • eski yeni
  • açıldı/kapandı
  • görünür/görünmez
  • kaynak hedef
  • kaynak/hedef
  • yukarı aşağı

Kısa değişken adları

x veya n gibi değişkenlerimiz olduğunda veya buna benzer bir şey olduğunda, kodu yazan kişinin niyetini hemen görmeyiz. n'nin ne yaptığı açık değil. Bunu anlamak daha dikkatli tefekkür gerektirir (ve bu zaman, zaman, zaman anlamına gelir). Örneğin, sorumlu kullanıcının kimliğini temsil eden bir alanımız olduğunu varsayalım. x veya kısaca id gibi bir değişken adı yerine, bu değişkeni okunabilirliği ve bilgi içeriğini anında iyileştiren "sorumluKullanıcıKimliği" olarak adlandıracağız. Bununla birlikte, n gibi kısa isimlerin, bu değişkeni içeren kod bloğunun yalnızca birkaç satır uzunluğunda olduğu ve yöntem adının orada ne olduğunu mükemmel bir şekilde tanımladığı küçük yöntemlerde yerel değişkenler olarak bir yeri vardır. Böyle bir değişkeni gören bir geliştirici, bunun ikincil öneme sahip olduğunu ve çok sınırlı bir kapsamı olduğunu anlar. Sonuç olarak, kapsamın bir değişken adının uzunluğuna belirli bir bağımlılığı vardır: ad ne kadar uzunsa, değişken o kadar geneldir ve bunun tersi de geçerlidir. Örnek olarak, tarihe göre son kaydedilen kullanıcıyı bulmak için bir yöntem aşağıda verilmiştir:

public User findLastUser() {
   return findAllUsers().stream()
           .sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
           .findFirst()
           .orElseThrow(() -> new ResourceNotFoundException("No user exists"));
}
Burada akışı sıralamak için x ve y adlı kısa değişkenleri kullanırız ve sonra onları unuturuz.

optimum uzunluk

İsim uzunluğu konusuna devam edelim. En uygun ad uzunluğu, n ile maximumNumberOfUsersInTheCurrentGroup arasında bir yerdedir. Başka bir deyişle, kısa adlar anlam eksikliğinden muzdaripken, çok uzun adlar okunabilirlik sağlamadan programı uzatır ve biz onları her seferinde yazmak için çok tembeliz. n gibi kısa isimli değişkenler için yukarıda açıklanan durum dışında, yaklaşık 8-16 karakterlik bir uzunluğa bağlı kalmalısınız. Bu katı bir kural değil, sadece bir yönerge.

Küçük farklılıklar

İsimlerdeki ince farklılıklardan bahsetmeden geçemeyeceğim. Bu aynı zamanda kötü bir uygulamadır, çünkü bu farklılıklar sadece kafa karıştırıcı olabilir veya onları fark etmek için çok fazla zaman harcamayı gerektirebilir. Örneğin, InvalidDataAccessApiUsageException ve InvalidDataAccessResourceUsageException arasındaki farkı bir bakışta anlamak zordur. Küçük L ve O harfleri kullanılırken de sıklıkla kafa karışıklığı ortaya çıkabilir, çünkü kolayca 1 ve 0 ile karıştırılabilirler. Bazı yazı tiplerinde fark daha belirgindir, bazılarında ise daha azdır.

Anlam

Adları anlamlı hale getirmemiz gerekiyor, ancak eşanlamlılar yoluyla belirsizlik yaratmamalıyız, çünkü örneğin, UserData ve UserInfo aslında aynı anlama sahiptir. Bu durumda, hangi nesneye ihtiyacımız olduğunu anlamak için kodu daha derine inmemiz gerekir. Yararlı bilgiler aktarmayan kelimelerden kaçının. Örneğin, firstNameString'de String kelimesine neden ihtiyacımız var? Bu gerçekten bir Date nesnesi olabilir mi? Tabii ki değil. Yani, sadece firstName kullanıyoruz. Boole değişkenlerinden de bahsetmek isterim. Örnek olarak, flagDeleted adlı bir boole alın. Bayrak kelimesinin bir anlamı yoktur. Buna isDeleted demek daha mantıklı.

dezenformasyon

Yanlış adlandırma kuralları hakkında da birkaç söz söylemek istiyorum. Diyelim ki userActivityList adında bir değişkenimiz var, ancak bu nesne List olmak yerine başka bir kapsayıcı türü veya özel depolama nesnesi. Bu, ortalama bir programcının kafasını karıştırabilir: buna userActivityGroup veya userActivities gibi bir şey demek daha iyidir.

Aramak

Kısa ve basit adların dezavantajlarından biri, büyük bir kod gövdesinde bulunmalarının zor olmasıdır — Hangisini bulmak daha kolay olur: "ad" mı yoksa "NAME_FOR_DEFAULT_USER" mı? İkinci seçenek tabii ki. İsimlerde sık karşılaşılan kelimelerden (harflerden) kaçınmalıyız çünkü bunlar sadece arama sırasında eşleşen dosyaların sayısını artıracaktır ki bu iyi değildir. Programcıların kodu yazmaktan çok okumakla daha fazla zaman harcadıklarını hatırlatmak isterim, bu nedenle uygulamanızın öğelerini adlandırma konusunda akıllı olun. Ama ya iyi bir isim bulunamazsa? Bir yöntemin adı işlevselliğini iyi tanımlamıyorsa ne olur? Yorumların sahneye girdiği yer burasıdır.

Yorumlar

Kodlama kuralları: doğru isimlerin gücü, iyi ve kötü yorumlar - 4Uygun bir yorumdan daha iyi bir şey yoktur, ancak hiçbir şey bir modülü boş, modası geçmiş veya yanlış yorumlar kadar karıştıramaz. İki ucu keskin bir kılıç olabilirler, değil mi? Yine de, yorumları açık bir şekilde iyi olarak değil, daha az kötü olarak ele almalısınız. Ne de olsa yorum, esasen kodda net bir şekilde ortaya çıkmayan düşünceyi telafi etmenin bir yoludur. Örneğin, yöntemin kendisi çok kafa karıştırıcı olduğu ortaya çıkarsa, bunları bir yöntemin özünü bir şekilde iletmek için kullanırız. Bu durumda, açıklayıcı notlar yazmaktansa kodu doğru şekilde yeniden düzenlemek daha iyidir. Yorum ne kadar eskiyse, yorum o kadar kötüdür çünkü kod büyüme ve gelişme eğilimindedir, ancak yorumlar aynı kalabilir. Bir yorumun oluşturulmasından bu yana ne kadar çok zaman geçtiyse, o kadar sorgulanabilir olabilir. Yanlış yorumlar, hiç yorum yapılmamasından çok daha kötüdür, çünkü bunlar kafa karıştırıcı ve yanıltıcıdır, yanlış beklentiler doğurur. Ve çok zor bir kodumuz olsa bile, onu yorumlamak yerine yeniden yazmalıyız.

yorum türleri

  • Yasal yorumlar — Yasal nedenlerle her kaynak dosyanın başındaki yorumlar, örneğin:

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

  • Bilgilendirici yorumlar - Kodun açıklamasını temsil eden yorumlar (ek bilgi sağlayan veya belirli bir kod bölümünün amacını açıklayan).

    Örneğin:

    
    /*
    * Combines the user from the database with the one passed for updating
    * When a field in requestUser is empty, it is filled with old data from 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 durumda, yöntemin adı ve parametreleri çok şeffaf işlevsellik ile birleştiğinde kendilerini iyi tanımladıkları için yorum yapmadan yapabilirsiniz.

  • Uyarı yorumları — Diğer geliştiricileri bir eylemin istenmeyen sonuçları hakkında uyarmayı amaçlayan yorum (örneğin, bir testin neden @Ignore olarak işaretlendiği konusunda onları uyarmak):

    
    // Takes too long to run
    // Don't run if you don't have a lot of time
    @Ignore
    @Test
    public void someIntegrationTest() {
           ……
           }
    

  • YAPILACAKLAR — Gelecekte yapılması gereken ancak herhangi bir nedenle şimdi yapılamayan bir şey hakkında not olan yorumlar. Bu iyi bir uygulamadır, ancak alakasız olanları kaldırmak ve dağınıklığı önlemek için bu tür yorumlar düzenli olarak gözden geçirilmelidir.

    Bir örnek:

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

    Burada, indirme işlemini gerçekleştiren (kimliğini güvenlik bağlamından çıkaracağımız) kullanıcı ile kaydetme işlemini gerçekleştiren kullanıcının bir karşılaştırmasını eklememiz gerektiğine dikkat çekiyoruz.

  • Güçlendirici yorumlar - İlk bakışta önemsiz görünebilecek bir durumun önemini vurgulayan yorumlar.

    Örnek olarak, bir test veritabanını bazı betiklerle dolduran bir yöntemi düşünün:

    
    Stream.of(IOUtils.resourceToString("/fill-scripts/" + x, StandardCharsets.UTF_8)
           .trim()
           .split(";"))
           .forEach(jdbcTemplate::update);
    // The trim() call is very important. It removes possible spaces at the end of the script
    // so that when we read and split into separate requests, we don't end up with empty ones
    

  • Javadoc yorumları — Belirli işlevler için API'yi açıklayan yorumlar. Belgelenmiş API ile çalışmak çok daha kolay olduğu için muhtemelen en yararlı yorumlar vardır. Bununla birlikte, diğer yorum türleri gibi modası geçmiş olabilirler. Bu nedenle, belgelere asıl katkının yorumlarla değil, iyi kodlarla yapıldığını asla unutmayın.

    İşte bir kullanıcıyı güncellemek için oldukça yaygın bir yöntem örneği:

    
    /**
    * Updates the passed fields for a user based on its id.
         *
    * @param id id of the user to be updated
    * @param user user with populated fields for updating
    * @return updated user
    */
           User update(Long id, User user);
    

Kötü yorumlar

  • mırıldanan yorum — Genellikle aceleyle yazılan ve anlamı yalnızca onları yazan geliştirici tarafından anlaşılabilen yorumlar, çünkü yorumun atıfta bulunduğu nüanslı durumu yalnızca kendisi algılar.

    Bu örneği göz önünde bulundurun:

    
    public void configureSomeSystem() {
           try{
           String configPath = filesLocation.concat("/").concat(CONFIGURATION_FILE);
           FileInputStream stream = new FileInputStream(configPath);
           } catch (FileNotFoundException e) {
           // If there is no configuration file, the default configuration is loaded 
          }
    }
    

    Bu ayarları kim yüklüyor? Zaten yüklendiler mi? Bu yöntemin istisnaları yakalaması ve varsayılan ayarları yüklemesi mi gerekiyor? Ancak sistemin diğer bölümlerinin araştırılmasıyla yanıtlanabilecek çok fazla soru ortaya çıkıyor.

  • Gereksiz yorumlar — Kodun belirli bir bölümünde neler olup bittiği son derece açık olduğundan, herhangi bir anlam yükü taşımayan yorumlar. Başka bir deyişle, yorumun okunması koddan daha kolay değildir.

    Bir örnek görelim:

    
    public class JdbcConnection{
    public class JdbcConnection{
       /**
        * The logger associated with the current class
        */
       private Logger log = Logger.getLogger(JdbcConnection.class.getName());
    
       /**
        * Creates and returns a connection using the input parameters
        */
       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;
       }
    

    Bu tür yorumların amacı nedir? Açıkladıkları her şey zaten tamamen açık.

  • Güvenilir olmayan yorumlar — Gerçek olmayan ve yalnızca yanıltıcı olan (dezenformasyon) yorumlar. Örneğin, işte bir tane.

    
    /**
    * Helper method. Closes the connection with the scanner if isNotUsing is true
    */
    private void scanClose(Scanner scan, boolean isNotUsing) throws Exception {
       if (!isNotUsing) {
           throw new Exception("The scanner is still in use");
       } scan.close();
    }
    

    Bu yorumda yanlış olan ne? Bize biraz yalan söylemesi, isNotUsing yanlışsa bağlantının kapatılması, yorumun bize bildirdiği gibi yanlış değil.

  • Zorunlu yorumlar — Zorunlu olarak kabul edilen yorumlar (örn. Javadoc yorumları), ancak gerçekte bazen aşırı derecede biriken, güvenilmez ve gereksiz olan yorumlar (bu yorumların gerçekten gerekli olup olmadığını düşünmeniz gerekir).

  • Örnek:

    
    /**
    * Create a user based on the parameters
    * @param firstName first name of the created user
    * @param middleName middle name of the created user
    * @param lastName last name of the created user
    * @param age age of the created user
    * @param address address of the created user
    * @return user that was created
    */
    User createNewUser(String firstName, String middleName, String lastName, String age, String address);
    

    Bu yorumlar olmadan yöntemin ne işe yaradığını anlayabilir misiniz? Büyük olasılıkla, evet, bu nedenle yorumlar burada anlamsız hale geliyor.

  • Günlük yorumları — Bazen her düzenlendiğinde modülün başına eklenen yorumlar (değişiklik günlüğü gibi bir şey).

    
    /**
    * Records kept since January 9, 2020;
    **********************************************************************
    * 9 Jan 2020: Providing a database connection using JDBC Connection;
    * 15 Jan 2020: Adding DAO-level interfaces for working with the database;
    * 23 Jan 2020: Adding integration tests for the database;
    * 28 Jan 2020: Implementation of DAO-level interfaces;
    * 1 Feb 2020: Development of interfaces for services,
    * in accordance with the requirements specified in user stories;
    * 16 Feb 2020: Implementation of service interfaces
    * (implementation of business logic related to the work of the database);
    * 25 Feb 2020: Adding tests for services;
    * 8 Mar 2020: Celebration of International Women's Day (Terry is drunk again);
    * 21 Mar 2020: Refactoring the service layer;
    */
    

    Bu yaklaşım bir zamanlar haklıydı, ancak sürüm kontrol sistemlerinin ortaya çıkmasıyla (örneğin Git), kodun gereksiz bir karmaşası ve karmaşıklığı haline geldi.

  • Yazarlık yorumları — Amacı, kodu yazan kişiyi belirtmek olan, böylece onunla iletişime geçip nasıl, ne ve neden olduğunu tartışabileceğiniz yorumlar, örneğin:

    
    * @author Bender Bending
    

    Bir kez daha, sürüm kontrol sistemleri, herhangi bir kod parçasını kimin ve ne zaman eklediğini tam olarak hatırlar, bu nedenle bu yaklaşım gereksizdir.

  • Yorumlanmış kod — Şu ya da bu nedenle yorumlanmış kod. Bu en kötü alışkanlıklardan biridir, çünkü bir şeyi yorumlayıp unutursunuz ve sonra diğer geliştiriciler onu silmeye cesaret edemezler (sonuçta, ya değerli bir şeyse?).

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

    Sonuç olarak, yorumlanmayan kod çöp gibi birikir. Hiçbir durumda böyle bir kod bırakmamalısınız. Gerçekten ihtiyacınız varsa, sürüm kontrol sistemini unutmayın.

  • Açık olmayan yorumlar — Bir şeyi aşırı derecede karmaşık bir şekilde tanımlayan yorumlar.

    
    /*
        * Start with an array large enough to store
        * all the data bytes (plus filter bytes) with a cushion, plus 300 bytes
        * for header data
        */
    this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];
    

    Bir yorum kodu açıklamalıdır. Kendi başına bir açıklamaya ihtiyaç duymamalıdır. Öyleyse burada yanlış olan ne? "Filtre baytları" nedir? Bu "+1" ne hakkında? Neden tam olarak 300?

Zaten yorum yazmaya karar verdiyseniz, işte birkaç ipucu:
  1. Bakımı kolay stiller kullanın: Çok süslü ve egzotik stilleri sürdürmek sinir bozucu ve zaman alıcıdır.
  2. Tek satırlara atıfta bulunan satır sonu yorumları kullanmayın: sonuç, büyük bir yorum yığınıdır. Dahası, her satır için anlamlı bir yorum düşünmek zordur.
  3. Bir yorum yazarken "nasıl" sorusuna değil "neden" sorusuna cevap vermeye çalışın.
  4. Kısaltılmış bilgilerden kaçının. Yukarıda da söylediğim gibi, bir yorum için açıklamaya ihtiyacımız yok: Açıklamanın kendisi yorumun kendisidir.
  5. Birimleri ve değer aralıklarını not etmek için yorumları kullanabilirsiniz.
  6. Yorumları, tanımladıkları kodun yakınına yerleştirin.
Son olarak, yine de en iyi yorumun yorum yapmamak olduğunu hatırlatmak istiyorum, bunun yerine başvurunuz boyunca ustaca adlandırma kullanmaktır. Kural olarak, çoğu zaman mevcut kodla çalışır, onu korur ve genişletiriz. Kötü kod bir engel olduğu için bu kodun okunması kolay ve anlaşılır olması çok daha uygundur. İşlere bir İngiliz anahtarı atmak gibi ve acele onun sadık arkadaşıdır. Ve ne kadar kötü kodumuz olursa, performans o kadar düşer. Bu, zaman zaman yeniden düzenleme yapmamız gerektiği anlamına gelir. Ancak en başından, sonraki geliştiricilerin sizi bulup öldürmek istemesine neden olmayacak bir kod yazmaya çalışırsanız, o zaman onu eskisi kadar sık ​​yeniden düzenlemeniz gerekmez. Ancak, yeni bağımlılıklar ve bağlantıların eklenmesiyle ürünün koşulları ve gereksinimleri sürekli değiştiği için yine de gerekli olacaktır. Sanırım bugünlük benim için bu kadar. Buraya kadar okuyan herkese teşekkürler :)
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION