it-swarm-tr.com

Java'da sabitleri uygulamanın en iyi yolu nedir?

Bunun gibi örnekler gördüm:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

ve sabitleri sarmak için statik bir final olduğunu bildiren bir Sabitler sınıfına sahip olabileceğimi farz ettim. Neredeyse hiç Java olmadığını biliyorum ve bunun sabitleri yaratmanın en iyi yolu olup olmadığını merak ediyorum.

373
mk.

Bu kesinlikle kabul edilebilir, hatta standart bile.

(public/private) static final TYPE NAME = VALUE;

TYPE, türdür; NAME, boşluklar için alt çizgi içeren tüm büyük harflerin içindeki addır ve VALUE, sabit değerdir;

Sabitlerinizi kendi sınıflarına veya arayüzlerine yerleştirmemenizi şiddetle tavsiye ederim.

Not olarak: Kesin olarak bildirilen ve değişken olan değişkenler yine de değiştirilebilir; ancak değişken hiçbir zaman farklı bir nesneyi gösteremez.

Örneğin:

public static final Point Origin = new Point(0,0);

public static void main(String[] args){

    Origin.x = 3;

}

Bu yasal ve Origin sonra (3, 0) bir noktaya gelirdi.

403
jjnguy

Tek bir sabit sınıfa sahip olmamı şiddetle tavsiye ediyorum. O zaman iyi bir fikir gibi görünebilir, ancak geliştiriciler sabitleri belgelemeyi reddettiğinde ve sınıf tamamen birbiriyle ilgili olmayan (uygulamanın tamamen farklı yönleriyle ilişkili) 500 sabitin üstünü kaplayacak şekilde büyür. genellikle tamamen okunamayan sabit dosyaya dönüşür. Yerine:

  • Java 5+ erişimine sahipseniz, bir uygulama alanı için belirli sabitlerinizi tanımlamak için enums kullanın. Uygulama alanının tüm kısımları, bu sabitler için sabit değerlere değil, numaralara atıfta bulunmalıdır. Sınıf ilan etme şeklinize benzer bir enum ilan edebilirsiniz. Enums, belki de Java 5+ ürününün belki de en (ve belki de tartışmalı) faydalı özelliğidir.
  • Yalnızca belirli bir sınıf veya alt sınıflarından biri için geçerli olan sabitleriniz varsa, bunları korumalı veya genel olarak ilan edin ve hiyerarşideki en üst sınıfa yerleştirin. Bu şekilde, alt sınıflar bu sabit değerlere erişebilir (ve diğer sınıflar herkese genel olarak erişirse, sabitler yalnızca belirli bir sınıf için geçerli değildir ... bu, bu sabiti kullanan dış sınıfların çok sıkı bir şekilde bağlanabileceği anlamına gelir sabiti içeren sınıf)
  • Tanımlanmış davranışı olan bir arayüze sahipseniz, ancak döndürülen değerler veya argüman değerleri özel olmalı, diğer uygulayıcıların bunlara erişebilmesi için bu arayüz üzerinde sabitler tanımlamak tamamen kabul edilebilir. Ancak, sadece sabitleri tutmak için bir arayüz oluşturmaktan kaçının: sadece sabitleri tutmak için yaratılmış bir sınıf kadar kötü olabilir.
235
MetroidFan2002

Bir KÖTÜ UYGULAMA sadece sabitleri tutmak için arayüzleri kullanmaktır ( Josh Bloch tarafından yazılmış sabit arayüz deseni ). İşte Josh'un önerdiği şey:

Sabitler mevcut bir sınıfa veya arayüze güçlü bir şekilde bağlıysa, bunları sınıfa veya arayüze eklemelisiniz. Örneğin, Tamsayı ve Çift gibi kutulu sayısal ilkel sınıfların tümü, MIN_VALUE ve MAX_VALUE sabitlerini dışa aktarır. Sabitler en çok sayılan bir türün üyeleri olarak görülüyorsa, bunları bir enum türüyle dışa aktarmalısınız. Aksi halde, sabitleri dayanılmaz bir yardımcı program sınıfı ile dışa aktarmalısınız.

Örnek:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

Adlandırma kuralı hakkında:

Geleneksel olarak, bu tür alanların alt harflerden oluşan, alt çizgi ile ayrılmış kelimelerden oluşan adları vardır. Bu alanların ilkel değerler veya değişmez nesnelere referanslar içermesi çok önemlidir.

120
Marcio Aguiar

Etkili Java'da (2. baskı), sabitler için statik girdi yerine enums kullanmanız önerilir.

Java'da burada enums hakkında iyi bir yazı var: http://Java.Sun.com/j2se/1.5.0/docs/guide/language/enums.html

Bu makalenin sonunda sorulan soru:

Peki enumları ne zaman kullanmalısın?

Bir cevap ile:

Sabit bir sabitler dizisine ihtiyacınız olduğunda

36
shelfoo

Sadece bir arayüz kullanmaktan kaçının:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

Baştan çıkarıcı, ancak kapsülleme ihlal ve sınıf tanımları ayrımını bulanıklaştırır.

21
stimpy

Aşağıdaki yaklaşımı kullanıyorum:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

Daha fazla, örneğin, sabit almak için Constants.DB.Connection.URL kullanın. Bana göre daha "nesne yönelimli" görünüyor.

19
albus.ua

Ayrı bir sınıfta statik son sabitler oluşturmak sizi belaya sokabilir. Java derleyicisi bunu gerçekten optimize edecek ve sabitin gerçek değerini referans veren herhangi bir sınıfa yerleştirecektir.

Eğer daha sonra 'Sabitler' sınıfını değiştirirseniz ve o sınıfa atıfta bulunan diğer sınıflar üzerinde tekrar derleme yapmazsanız, kullanılan eski ve yeni değerlerin bir kombinasyonuyla birleşirsiniz.

Bunları sabit olarak düşünmek yerine, onları yapılandırma parametreleri olarak düşünün ve onları yönetmek için bir sınıf oluşturun. Değerlerin nihai olmamasını sağlayın ve hatta alıcıları kullanmayı düşünün. Gelecekte, bu parametrelerin bazılarının aslında kullanıcı veya yönetici tarafından yapılandırılması gerektiğini belirlediğiniz için, yapılması çok daha kolay olacaktır.

17
Kevin Day

Yapabileceğiniz bir numaralı hata, Sabitler gibi genel bir adla adlandırılan global olarak erişilebilir bir sınıf oluşturmaktır. Bu sadece çöplerle doludur ve sisteminizin hangi bölümünün bu sabitleri kullandığını bulmak için tüm yeteneklerinizi kaybedersiniz.

Bunun yerine, sabitler kendilerine ait olan sınıfa girmelidir. TIMEOUT adlı bir sabitiniz var mı? Muhtemelen Communications () veya Connection () sınıfınıza girmelidir. MAX_BAD_LOGINS_PER_HOUR? Kullanıcıya () gider. Ve diğerleri ve diğerleri.

Diğer olası kullanım, "sabitler" çalışma zamanında tanımlanabildiği ancak kolayca kullanıcı tarafından değiştirilemediğinde Java .properties dosyalarıdır. Bunları .jars'ınıza paketleyebilir ve Class resourceLoader ile başvuruda bulunabilirsiniz.

13
Yann Ramin

Gitmenin doğru yolu bu.

Genellikle sabitler değil ayrı "Sabitler" sınıflarında tutulurlar çünkü keşfedilemezler. Sabit, geçerli sınıfa uygunsa, orada tutulması bir sonraki geliştiriciye yardımcı olur.

6
Jason Cohen

Bir arayüz kullanmanın yol değil olduğuna katılıyorum. Bu kalıptan kaçınmak Bloch'un Etkili Java içinde kendi maddesine (# 18) sahiptir.

Bloch'un sabit arabirim modeline karşı yaptığı bir argüman, sabitlerin kullanımının bir uygulama detayı olduğudur, ancak bunları kullanmak için bir arayüz uygulamak, dışa aktarılan API'nizde bu uygulama detayını ortaya çıkarır.

public|private static final TYPE NAME = VALUE; modeli, bir sabit bildirmek için iyi bir yoldur. Şahsen, tüm sabitlerinize ev sahipliği yapmak için ayrı bir sınıf yapmaktan kaçınmanın daha iyi olduğunu düşünüyorum, ancak kişisel tercih ve tarz dışında, bunu yapmamak için hiçbir neden görmedim.

Sabitleriniz bir numaralandırma olarak iyi modellenebilirse, 1.5 veya daha sonraki sürümlerde mevcut olan enum yapısını göz önünde bulundurun.

1.5'ten önceki bir sürümü kullanıyorsanız, normal Java sınıflarını kullanarak typesafe numaralandırmalarını yine de kaldırabilirsiniz. (Bakınız bu site bunun hakkında daha fazla bilgi için).

5
Rob Dickerson

Ya bir numaralandırma?

5
Sébastien D.

Sabitler yerine alıcıları kullanmayı tercih ederim. Bu alıcılar sabit değerler, ör. public int getMaxConnections() {return 10;}, ama sabiti gerektiren herhangi bir şey bir alıcıdan geçer.

Bunun bir yararı, eğer programınız sabiti aşıyorsa - bunun yapılandırılabilir olması gerektiğini bulursunuz - alıcının sabiti döndürme şeklini değiştirebilmenizdir.

Diğer fayda, sabiti değiştirmek için onu kullanan her şeyi yeniden derlemeniz gerekmemesidir. Statik bir son alana başvurduğunuzda, bu sabitin değeri, kendisine başvuran herhangi bir byte kodunda derlenir.

5
big_peanut_horse

Yukarıdaki yorumlara dayanarak, bunun eski moda küresel sabit sınıfı (genel statik statik değişkenleri olan) bunun enum benzeri eşdeğeriyle değiştirmeye yönelik iyi bir yaklaşım olduğunu düşünüyorum:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_Host("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Öyleyse onları şöyle ifade edebilirim:

Constants.StringConstant.DB_Host
4
Lorand Bendig

İyi bir nesne yönelimli tasarım, halka açık birçok sabite ihtiyaç duymaz. Sabitlerin çoğu, işlerini yapmalarını gerektiren sınıfta kapsüllenmelidir.

3
Bradley Harris

Buna cevap verecek belirli bir miktar görüş vardır. Başlamak için, Java’daki sabitlerin genel, statik ve final olduğu bildirilir. Nedenler aşağıdadır:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Bir CONSTANTS erişimcisi/nesnesi için hiçbir zaman bir arayüz kullanmam, çünkü arayüzlerin genellikle uygulanması bekleniyor. Bu komik görünmüyor mu:

String myConstant = IMyInterface.CONSTANTX;

Bunun yerine, bazı küçük takaslara dayanarak birkaç farklı yol arasında seçim yapacağım ve bu da ihtiyacınız olan şeylere bağlı:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe
2
djangofan

Java'da sabitleri uygulamanın en iyi yolu nedir?

Gerçekten kaçınmamız gereken bir yaklaşım: sabitleri tanımlamak için arayüzleri kullanmak.

Özellikle sabitleri bildirmek için bir arayüz oluşturmak gerçekten en kötü şeydir: arayüzlerin tasarlanma nedenini ortadan kaldırır: yöntem (ler) sözleşmesini tanımlama.

Belirli bir ihtiyacı karşılamak için bir arayüz zaten mevcut olsa bile, aralarındaki sabitleri bildirmek, sabitlerin API ve müşteri sınıflarına verilen sözleşmenin bir parçası olmamasını gerektiği gibi anlam ifade etmemektedir.


Basitleştirmek için, genel olarak 4 geçerli yaklaşımımız var.

static final String/Integer alanı ile:

  • 1) İçinde sabitleri ilan eden bir sınıf kullanmak, fakat sadece değil.
  • 1 değişkeni) yalnızca sabitleri bildirmeye adanmış bir sınıf oluşturma.

Java 5 enum ile:

  • 2) enum'un ilişkili bir sınıfta ilan edilmesi (iç içe geçmiş sınıf olarak).
  • 2 değişken - enum bağımsız bir sınıf olarak yaratılır (kendi sınıf dosyasında tanımlanır).

TLDR: En iyi yol hangisi ve sabitleri nerede bulabilirim?

Çoğu durumda, enum yolu muhtemelen static final String/Integer yolundan daha incedir ve kişisel olarak static final String/Integer yolunun yalnızca enum kullanmamak için iyi nedenlerimiz varsa kullanılması gerektiğini düşünüyorum.
Ve sabit değerleri nerede bildirmemiz gerektiği hakkında, fikir, sabit değerlerle belirli ve güçlü bir işlevsel uyumluluğa sahip tek bir mevcut sınıf olup olmadığını araştırmaktır. Böyle bir sınıfı bulursak, Bunu sabitler sahibi olarak kullanmalıyız. Aksi takdirde, sabit, belirli bir sınıfla ilişkilendirilmemelidir.


static final String/static final Integer, enum ile karşılaştırıldığında

Enums kullanımı, gerçekten çok iyi düşünülmüş bir yoldur.
Numaraların String veya Integer sabit alanlarına göre büyük bir avantajı vardır.
Daha güçlü bir derleme kısıtı getirdiler. Enum değerini parametre olarak alan bir yöntem tanımlarsanız, yalnızca enum sınıfında (veya null) tanımlanan bir enum değerini iletebilirsiniz.
String ve Integer ile bunları uyumlu tipteki herhangi bir değerle değiştirebilirsiniz ve değer static final String/static final Integer alanlarında tanımlanmış bir sabit olmasa bile derleme iyi olur.

Örneğin, bir sınıfta static final String alanları olarak tanımlanan iki sabitin altında:

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

İşte bu sabitlerden birine sahip olmayı bekleyen bir parametre:

public void process(String constantExpected){
    ...    
}

Bu şekilde çağırabilirsin:

process(MyClass.ONE_CONSTANT);

veya

process(MyClass.ANOTHER_CONSTANT);

Ancak hiçbir derleme kısıtı, onu bu şekilde çağırmanızı engellemez:

process("a not defined constant value");

Yalnızca çalışma zamanında ve yalnızca iletilen değeri denetleme işleminde bir hata yaparsanız hata alırsınız.

Enum ile kontroller gerekli değildir çünkü müşteri bir enum parametresinde sadece bir enum değerini geçebilir.

Örneğin, burada bir enum sınıfında tanımlanan iki değer (yani kutudan sabit):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

İşte bu enum değerlerinden birini parametre olarak almayı bekleyen bir yöntem:

public void process(MyEnum myEnum){
    ...    
}

Bu şekilde çağırabilirsin:

process(MyEnum.ONE_CONSTANT);

veya

process(MyEnum.ANOTHER_CONSTANT);

Ancak derleme, bu şekilde çağırmanıza asla izin vermez:

process("a not defined constant value");

Sabitleri nerede bildirmeliyiz?

Uygulamanız, sabit değerlerle belirli ve güçlü bir işlevsel uyumluluğa sahip tek bir mevcut sınıf içeriyorsa, 1) ve 2) daha sezgisel görünür.
Genel olarak, eğer onları yönlendiren ana sınıfta bildirilirse ya da içinde bulacağımızı tahmin etmek için çok doğal bir isme sahiplerse, sabitlerin kullanımını kolaylaştırır.

Örneğin, JDK kütüphanesinde üstel ve pi sabit değerleri, yalnızca sabit bildirimleri bildirmeyen bir sınıfta bildirilir (Java.lang.Math).

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

Matematik işlevlerini kullanan istemciler çoğunlukla Math sınıfına güvenirler. Böylece, kolayca yeterince sabit bulabilirler ve ayrıca E ve PI öğelerinin nerede çok doğal bir şekilde tanımlandığını da hatırlayabilirler.

Uygulamanız, sabit değerlerle çok özel ve güçlü bir işlevsel uyumu olan mevcut bir sınıfı içermiyorsa, 1 değişken) ve 2 değişken) yolları daha sezgisel görünür.
Genel olarak, eğer bunları manipüle eden bir sınıfta bildirilirse, bu sınıfları hiç kimsenin manipüle edemediği 3 veya 4 başka sınıfımız varken, bunları sınıflandıran bir sınıfta bildirilirse, sabitlerin kullanımını kolaylaştırmaz. Sabit değerleri barındırmak diğerlerinden daha doğal.
Burada sadece sabit değerleri tutacak özel bir sınıf tanımlamak mantıklı.
Örneğin JDK kütüphanesinde, Java.util.concurrent.TimeUnit enum, belirli bir sınıfta bildirilmez, çünkü onu tutmak için en sezgisel olarak görünen yalnızca bir ve yalnızca bir JDK'ya özgü sınıf yoktur:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Java.util.concurrent öğesinde bildirilen birçok sınıf bunları kullanır: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... ve gerçekten hiçbiri enum tutmak için daha uygun görünmüyor.

2
davidxxx

FWIW, saniye cinsinden bir zaman aşımı değerinin muhtemelen bir konfigürasyon ayarı olması gerekir (bir özellik dosyasından veya Spring'deki enjeksiyon yoluyla okunan) ve sabit değil.

1
Tim Howland

Fark ne

1.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2.

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

ve bu sabite ihtiyacımız olan her yerde MyGlobalConstants.TIMEOUT_IN_SECS kullanarak. Sanırım ikisi de aynı.

1
chandrayya

Tek, genel sabitler sınıfı kötü bir fikirdir. Sabitler, en mantıklı olarak ilişkili oldukları sınıfla birlikte gruplandırılmalıdır.

Her türlü değişkenleri (özellikle enums) kullanmak yerine, yöntemleri kullanmanızı öneririm. Değişkenle aynı ada sahip bir yöntem oluşturun ve değişkene atadığınız değeri döndürmesini isteyin. Şimdi değişkeni silin ve tüm referansları yeni oluşturduğunuz yöntemi çağırmak için kullanın. Sabitin yeterince genel olduğunu düşünüyorsanız, yalnızca kullanmak için sınıfın bir örneğini oluşturmak zorunda kalmamanız gerektiğini, o zaman sabit yöntemi bir sınıf yöntemi haline getirin.

1
ab

Her türden bir Sabit, bir sınıf içinde değişmeyen bir özellik (bu, final değiştiricisinin bir üye değişkeni olan) oluşturularak bildirilebilir. Genellikle static ve public değiştiricileri de sağlanır.

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

Bir sabitin değerinin n-Tuple (örneğin numaralandırma) seçeneklerinden bir seçimi işaret ettiği çok sayıda uygulama vardır. Örneğimizde, olası atanmış değerleri sınırlandıracak bir Numaralandırılmış Tür tanımlamayı seçebiliriz (ör. Gelişmiş tür güvenliği):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}
1
Ryan Delucchi

Sınıfı sabit olarak aynı (kasanın dışında) olarak adlandırmazdım ... Tüm sabitlerin yaşayacağı en az bir "Ayarlar" veya "Değerler" veya "Sabitler" sınıfına sahip olurdum. Çok sayıda varsa, onları mantıksal sabit sınıflarda gruplandırırdım (UserSettings, AppSettings, vb.)

0
Joel Martinez

static final benim tercihimdir, eğer öğe gerçekten numaralandırılabilir olsaydı, yalnızca enum kullanırdım.

0
wulfgarpro

Temel temel-sıfır köktenciliğini anlamadan Joshua Bloch'u alıntılamak YASADIŞI alışkanlığı ve son derece YÜRÜTME uygulamasıdır .

Ben de Joshua Bloch’tan hiçbir şey okumamıştım.

  • o korkunç bir programcı
  • ya da şu ana kadar onu alıntı yaparken bulduğum insanlar (Joshua, tahmin ettiğim bir çocuğun adıdır), materyallerini dini müsamahalarını meşrulaştırmak için dini senaryolar olarak kullanıyor.

İncil köktenciliğinde olduğu gibi, tüm İncil yasaları ile özetlenebilir.

  • Tüm kimliğinizle ve tüm aklınızla Temel Kimliğinizi Sevin
  • Komşunu kendin gibi sev

ve benzer şekilde, yazılım mühendisliği köktenciliği şöyle özetlenebilir:

  • tüm programlama gücün ve zihninle kendini sıfır temel prensiplerine ada.
  • ve programcı arkadaşlarınızın mükemmelliğini kendiniz için yapın.

Ayrıca, incildeki köktendinci çevreler arasında güçlü ve makul bir sonuç çıkarıldı

  • İlk önce kendini sev. Çünkü kendinizi fazla sevmiyorsanız, o zaman "komşunuzu kendiniz gibi sevin" kavramı çok fazla ağırlık taşımaz, çünkü "kendinizi ne kadar çok seversiniz", başkalarını seveceğiniz referans çizgisidir.

Benzer şekilde, kendinize bir programcı olarak saygı duymuyorsanız ve sadece bazı programlama gurelerinin açıklamasını ve kehanetlerini kabul ederseniz, temellerini sorgulamadan, alıntılarınız ve Joshua Bloch'a (ve benzerlerine) güvenmeniz anlamsızdır. Bu nedenle, programcı arkadaşlarınıza gerçekten saygı duymazsınız.

Yazılım programlamanın temel yasaları

  • tembellik, iyi bir programcının erdemidir
  • programlama ömrünüzü kolay, tembel ve bu nedenle mümkün olduğu kadar verimli hale getireceksiniz
  • sizinle birlikte çalışan komşu programcılarınız için programlamanın sonuçlarını ve meraklarını kolay, tembel ve dolayısıyla mümkün olduğunca etkili hale getireceksiniz.

Arayüz deseni sabitleri kötü bir alışkanlıktır ???

Hangi dini temelde etkili ve sorumlu programlama yasaları altında bu dini imgeleme giriyor?

Sadece arayüz deseni sabitleri hakkındaki wikipedia makalesini okuyun ( https://en.wikipedia.org/wiki/Constant_interface ) ve aptalca arayüz desen sabitlerine karşı koyduğu aptalca mazeretleri okuyun.

  • IDE yok mu? Yazılım programcısı olarak dünyadaki kim IDE kullanmaz? Birçoğumuz, IDE kullanımından kaçınmak suretiyle maço estetik sağkalımcılığa sahip olduğunun kanıtlanması gerekmeyen programcılar.

    • Ayrıca - bir IDE'ye ihtiyaç duymamak için ikinci bir mikro-işlevsel programlama destekçisi bekleyin. Veri modeli normalizasyonu ile ilgili açıklamamı okuyana kadar bekleyin.
  • Geçerli alanı içinde kullanılmayan değişkenlerle ad alanını kirletir mi? Bu fikrin savunucuları olabilir

    • veri modeli normalleşmesinin farkında değil ve gerekliliği
  • Sabitleri zorlamak için arayüzleri kullanmak, arayüzlerin kötüye kullanılmasıdır. Bunun savunucuları kötü bir alışkanlığa sahip

    • "sabitlerin" sözleşme olarak değerlendirilmemesi gerektiğini görmemek. Arayüzler, bir sözleşmeye uyumu uygulamak veya yansıtmak için kullanılır.
  • Gelecekte arayüzlerin uygulamalı sınıfa dönüştürülmesi imkansız değilse de zordur. Hah .... hmmm ... ???

    • Niçin geçim kaynağınız gibi bir programlama biçimine katılmak istiyorsunuz? IOW, neden kendini böyle bir AMBIVALENT ve kötü programlama alışkanlığına adamak?

Mazeretler ne olursa olsun, arabirim sabitlerinin kullanımını yetkilendirmek veya genel olarak cesaretlendirmek için FONKSEL ETKİLİ yazılım mühendisliği söz konusu olduğunda NO VALID EXCUSE yoktur.

Amerika Birleşik Devletleri Anayasasını hazırlayan kurucu babaların orijinal niyetlerinin ve zihinsel durumlarının ne olduğu önemli değildir. Kurucu babaların asıl amaçlarını tartışabiliriz, ancak tek umursadığım şey, ABD Anayasası'nın yazılı beyanları. Ve her ABD vatandaşının, ABD Anayasası'nın yazılı olmayan kurucu amaçlarından değil, yazılı edebi-köktencilikten faydalanması sorumluluğu.

Benzer şekilde, Java platformunun kurucularının ve programlama dilinin "orijinal" amaçlarının arayüz için ne anlama geldiği umurumda değil. Önemli olan şey Java spesifikasyonunun sağladığı etkili özellikler ve sorumlu yazılım programlamanın temel yasalarını yerine getirmeme yardımcı olmak için bu özelliklerden sonuna kadar yararlanmayı düşünüyorum. "Arabirim niyetini ihlal ettiğim" algılanması umrumda değil. Gosling'in ya da Bloch'un "Java kullanmanın uygun yolu" hakkında ne dediği umurumda değil, söyledikleri ETKİLİ temelleri yerine getirme ihtiyacımı ihlal etmediği sürece.

Temel Veri Modeli Normalleştirme

Veri modelinizin nasıl barındırıldığı veya iletildiği önemli değildir. Veri modeli normalizasyonunun gerekliliğini ve sürecini anlamıyorsanız, ara yüzleri veya enumları veya ne olursa olsun, ilişkisel veya no-SQL kullanıp kullanmadığınız.

Öncelikle bir dizi işlemin veri modelini tanımlamalı ve normalleştirmeliyiz. Ve tutarlı bir veri modeline sahip olduğumuzda, SADECE, işlevsel davranışı tanımlamak için bileşenlerinin proses akışını kullanabiliriz ve proses bir alan veya uygulama alanını engeller. Ve ancak o zaman her bir işlevsel sürecin API'sini tanımlayabiliriz.

EF Codd tarafından önerilen veri normalleşmesinin farklı yönleri bile şimdi ciddi biçimde zorlanıyor ve ciddi biçimde zorlanıyor. Örneğin. 1NF konusundaki ifadesi, özellikle modern veri hizmetleri, repo-teknoloji ve iletimin ortaya çıkışında yaptığı gibi, belirsiz, yanlış hizalanmış ve fazla basitleştirilmiş olarak eleştirilmiştir. IMO, EF Codd ifadeleri tamamen kaldırılmalı ve yeni matematiksel olarak daha mantıklı ifadeler kümesi tasarlanmalı.

EF Kodlarının göze çarpan bir kusuru ve etkili insan kavrama konusundaki yanlış hizalanmasının nedeni, insanca algılanabilir çok boyutlu, değişken boyutlu verilerin bir parça parça 2 boyutlu haritalamada etkili bir şekilde algılanabileceği inancıdır.

Veri Normalleşmesinin Temelleri

EF Kodunun ifade edemediği şey.

Her tutarlı veri modelinde bunlar, elde edilecek veri modeli tutarlılığının sıralı dereceli sıralamasıdır.

  1. Veri örneklerinin birliği ve kimliği.
    • her veri bileşeninin ayrıntı derecesini tasarlayın, ki bunların ayrıntı derecesi bir bileşenin her bir örneğinin benzersiz şekilde tanımlanabileceği ve alınabileceği bir seviyededir.
    • örnek takma adının olmaması. yani, bir tanımlamanın bir bileşenin birden fazla örneğini ürettiği hiçbir yol yoktur.
  2. Örnek çapraz konuşmaların olmaması. Bir bileşenin örneğini tanımlamaya katkıda bulunmak için bir veya daha fazla başka bileşenin örneğini kullanma zorunluluğu yoktur.
  3. Veri bileşenlerinin/boyutlarının birliği ve kimliği.
    • Bileşen de-aliasing varlığı. Bir bileşen/boyutun benzersiz olarak tanımlanabileceği bir tanım bulunmalıdır. Bir bileşenin birincil tanımı hangisidir;
    • birincil tanımın, amaçlanan bir bileşenin parçası olmayan alt boyutların veya üye bileşenlerin ortaya çıkmasına neden olmayacağı;
  4. Bileşen dealiasing'in benzersiz yolları. Bir bileşen için bir ve tek bir bileşen bulunmalıdır.
  5. Bileşenlerin hiyerarşik bir ilişkisinde bir ana bileşeni tanımlamak için bir ve sadece bir tane tanım arayüzü veya sözleşme vardır.
  6. Bileşen karışmalarının olmaması. Bir bileşenin kesin tanımlamasına katkıda bulunmak için başka bir bileşenin bir üyesini kullanma zorunluluğu yoktur.
    • Böyle bir ebeveyn-çocuk ilişkisinde, bir ebeveynin tanımlayıcı tanımı, bir çocuğun üye bileşenlerinin bir kısmına bağlı olmamalıdır. Bir ebeveynin kimliğinin bir üye bileşeni, çocuğun çocuklarından herhangi birine veya tümüne atıfta bulunmadan başvuru yapmadan tam çocuk kimliği olmalıdır.
  7. Bir veri modelinin iki modlu veya çoklu mod görünüşlerini önleme
    • Bir bileşenin iki aday tanımı bulunduğunda, iki farklı veri modelinin bir olarak karıştırıldığının bir işaretidir. Bu, veri modeli düzeyinde veya alan düzeyinde tutarsızlık olduğu anlamına gelir.
    • Bir uygulama alanı tutarlı bir şekilde bir ve sadece bir veri modeli kullanmalıdır.
  8. Bileşen mutasyonunu tespit edin ve tanımlayın. Çok büyük verilerin istatistiki bileşen analizini yapmadıysanız, bileşen mutasyonunu tedavi etmenin gereğini görmez veya görmezsiniz.
    • Bir veri modeli bazı bileşenlerini döngüsel olarak veya kademeli olarak mutasyona sahip olabilir.
    • Mod üye dönüşü veya aktarma dönüşü olabilir.
    • Üye-rotasyon mutasyonu, bileşenler arasında alt bileşenlerin değişmesi farklı olabilir. Veya tamamen yeni bileşenlerin tanımlanması gereken yerler.
    • Transpozisyonel mutasyon, tam tersi bir özniteliğe mutasyona uğramış boyutsal bir üye olarak tezahür eder.
    • Her mutasyon döngüsü, ayrı bir veri modeli olarak tanımlanmalıdır.
  9. Her mutasyonun versiyonunu yapın. Öyle ki, veri modelinin 8 yıllık bir mutasyonunu tedavi etme ihtiyacı ortaya çıktığında, veri modelinin önceki bir sürümünü çıkarabilirsiniz.

Hizmet veren bileşen uygulamaları alanındaki bir alanda ya da tek bir tutarlı tek veri modeli olmalı ya da kendini tanımlamak için bir veri modeli/sürümü için bir araç bulunmalıdır.

Arayüz Sabitlerini kullanıp kullanamayacağımızı hala mı soruyoruz? Gerçekten mi ?

Bu sıradan sorudan daha fazla tehlikede olan veri normalleştirme sorunları var. Bu sorunları çözmüyorsanız, arayüz sabitlerinin neden olduğunu düşündüğünüz karışıklık karşılaştırmalı olarak hiçbir şey değildir. Sıfır.

Veri modeli normalizasyonundan sonra bileşenleri değişkenler olarak, özellikler olarak sözleşme arayüzü sabitleri olarak belirlersiniz.

Sonra hangisinin değer enjeksiyonuna, mülk konfigürasyonunda yer tutmaya, ara yüzlere, son karakterlere vb.

Arayüz sabitlerine karşı dikte etmek daha kolay bir bileşeni bulmak için ihtiyaç duyma mazeretini kullanmak zorunda kalırsanız, veri modeli normalizasyonu yapmama alışkanlığınız var demektir.

Belki de veri modelini bir vcs sürümünde derlemek istiyorsunuz. Bir veri modelinin belirgin bir şekilde tanımlanabilir bir versiyonunu çıkarabilirsiniz.

Arayüzlerde tanımlanan değerlerin tamamen değişken olmadıkları garanti edilir. Ve paylaşılabilir. İhtiyacınız olan tek şey bu sabitler kümesi olduğunda neden bir dizi son dizeyi sınıfınıza başka bir sınıftan yükleyin?

Peki neden bu bir veri modeli sözleşmesi yayınlamak için değil? Yani, tutarlı bir şekilde yönetebilir ve normalleştirebilirseniz, neden olmasın? ...

public interface CustomerService {
  public interface Label{
    char AssignmentCharacter = ':';
    public interface Address{
      String Street = "Street";
      String Unit= "Unit/Suite";
      String Municipal = "City";
      String County = "County";
      String Provincial = "State";
      String PostalCode = "Zip"
    }

    public interface Person {
      public interface NameParts{
        String Given = "First/Given name"
        String Auxiliary = "Middle initial"
        String Family = "Last name"
      }
    }
  }
}

Artık uygulamalarımın sözleşmeli etiketlerine şu şekilde başvurabilirim:

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family

Bu jar dosyasının içeriğini karıştırıyor mu? Bir Java programcısı olarak kavanozun yapısını umursamıyorum.

Bu osgi-motivated çalışma zamanı takas için karmaşıklık sunuyor? Osgi, programcıların kötü alışkanlıklarına devam etmelerine izin vermek için son derece etkili bir araçtır. Osgi'den daha iyi alternatifler var.

Ya da neden bu değil? Özel Sabitlerin yayınlanmış sözleşmeye sızması yoktur. Tüm özel sabitler "Sabitler" adında özel bir arayüzde gruplandırılmalıdır, çünkü sabitleri aramak zorunda kalmak istemiyorum ve tekrar tekrar "private final String" yazamayacak kadar tembelim.

public class PurchaseRequest {
  private interface Constants{
    String INTERESTINGName = "Interesting Name";
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Belki bu bile:

public interface PurchaseOrderConstants {
  public interface Properties{
    default String InterestingName(){
       return something();
    }
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Arayüz sabitlerinin dikkate alınması gereken tek sorun, arayüzün ne zaman uygulanacağıdır.

Bu, arayüzlerin "asıl amacı" değil midir? Müteakip babanın ABD Anayasasını hazırlamadaki "asıl niyetini" umursardım, Yüksek Mahkeme'nin ABD Anayasası'nın yazılı yazılarını nasıl yorumlayacağı yerine ???

Ne de olsa, özgürlerin, vahşilerin ve cesurların ülkesinde yaşıyorum. Cesur ol, özgür ol, vahşi ol - arayüzü kullan. Eğer programcı arkadaşlarım verimli ve tembel bir programlama aracı kullanmayı reddederse, altıncı kural gereği programlama verimliliğimi, onlarınki ile aynı hizaya getirmek için düşürmek zorunda mıyım? Belki de yapmalıyım, ama bu ideal bir durum değil.

0
Blessed Geek

Bir adım daha ileri gitmek için, global olarak kullanılan sabitleri bir arabirime yerleştirerek sistem genelinde kullanılabilirler. Örneğin.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

Ancak daha sonra uygulamayın. Tamamen kalifiye sınıf adı üzerinden doğrudan kodlara bakın.

0

Sabitleri bildirmek ve ALL_CAPS adlandırma notasyonu ile gitmek için static final kullanıyorum. Tüm sabitlerin bir ara yüze bir araya getirildiği birkaç gerçek hayat örneği gördüm. Birkaç yayın haklı olarak kötü bir uygulama olarak adlandırılıyor, çünkü öncelikle bunun için bir arayüz bu değil. Arabirim bir sözleşmeyi uygulamalı ve ilişkisiz sabitleri içine koyacak bir yer olmamalıdır. Sabit semantik belirli bir sınıfa ait değilse (özel bir kurucu aracılığıyla) somutlaştırılamayan bir sınıfa bir araya getirmek de iyidir. es). Her zaman en çok ilgili olduğu sınıfa bir sabit koyarım, çünkü bu mantıklıdır ve aynı zamanda kolayca idare edilebilir.

Enums, bir değer aralığını temsil etmek için iyi bir seçimdir, ancak mutlak değere vurgu yapan bağımsız sabitleri saklıyorsanız (örn. TIMEOUT = 100 ms) sadece static final yaklaşımı için gidebilirsiniz.

0
bincob

Sabitler için, Enum daha iyi bir seçimdir IMHO. İşte bir örnek

genel sınıf myClass {

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}
0
mmansoor

En çok ne söylediğine katılıyorum, sabit bir koleksiyonla uğraşırken enums kullanmak en iyisidir. Ancak, Android'de programlama yapıyorsanız, daha iyi bir çözüm var: IntDef Annotation .

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

IntDef ek açıklama basit bir şekilde numaralandırma üstündür, sadece bir derleme zamanı işaretleyicisi olduğu için önemli ölçüde daha az yer kaplar. Bu bir sınıf değildir ve otomatik dize dönüştürme özelliğine de sahip değildir.

0
Quinn Turner

Bunu yapmamın yollarından biri, sabit değerlere sahip bir 'Global' sınıf oluşturmak ve sabite erişmesi gereken sınıflarda statik bir ithalat yapmaktır.

0
Javamann