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.
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.
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:
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.
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
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.
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.
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.
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.
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.
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).
Ya bir numaralandırma?
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.
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
İ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.
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
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:
Java 5 enum
ile:
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.
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.
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ı.
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.
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;
}
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.)
static final
benim tercihimdir, eğer öğe gerçekten numaralandırılabilir olsaydı, yalnızca enum
kullanırdım.
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.
İncil köktenciliğinde olduğu gibi, tüm İncil yasaları ile özetlenebilir.
ve benzer şekilde, yazılım mühendisliği köktenciliği şöyle özetlenebilir:
Ayrıca, incildeki köktendinci çevreler arasında güçlü ve makul bir sonuç çıkarıldı
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ı
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.
Geçerli alanı içinde kullanılmayan değişkenlerle ad alanını kirletir mi? Bu fikrin savunucuları olabilir
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
Gelecekte arayüzlerin uygulamalı sınıfa dönüştürülmesi imkansız değilse de zordur. Hah .... hmmm ... ???
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.
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.
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.
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.
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.
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.
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.
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 }
}
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.
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.