Sabitleri düzenlemek için iç içe ortak sınıfları kullanma


21

Bir çok sabit olan bir uygulama üzerinde çalışıyorum. Son kod incelemesinde, sabitlerin çok dağınık olduğu ve hepsinin tek bir "ana" sabit dosya halinde düzenlenmesi gerektiği ortaya çıktı. Anlaşmazlık onları nasıl organize edeceğimizle ilgili. Çoğunluk, sabit ismi kullanmanın yeterince iyi olması gerektiğini düşünmektedir, ancak bu, şuna benzer bir koda yol açacaktır:

public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";

Bu tür bir adlandırma kuralını hantal buluyorum. İç içe geçmiş sınıfı kullanmanın ve bunun gibi bir şeye sahip olmanın daha kolay olabileceğini düşündüm:

public class IntegrationSystemConstants
{
    public class CreditCard
    {
        public static final String UI_EXPIRY_MONTH = "3524";
        public static final String UI_ACCOUNT_ID = "3524";
        ...
    }
    public class BankAccount
    {
        public static final String UI_ACCOUNT_ID = "9987";
        ...
    }
}

Bu fikir iyi karşılanmadı çünkü “çok karmaşıktı” (bunun neden bu kadar karmaşık olabileceğine dair fazla ayrıntı alamadım ). Bunun, ilgili sabit gruplar arasında daha iyi bir ayrım yarattığını ve otomatik tamamlamanın da bunları bulmayı kolaylaştırdığını düşünüyorum. Bunu daha önce hiç görmedim, bu yüzden bunun kabul edilebilir bir uygulama olup olmadığını veya yapılmaması gereken daha iyi nedenlerin olup olmadığını merak ediyorum.


1
Fikri sevdim. C # tarzı enum benzeri kapsam ve davranış istediğimde kendimi C ++ 'ta benzer bir şey yaparken buldum, ancak anlamlı değerlerle (Scala'daki vakalar yerine vaka sınıfları kullanmaya alışmamın sebebi ortaya çıktı, çünkü fikir ortaya çıktı). Verilmiş, bu eğlence için kişisel bir proje ve takım çalışması değil.
KChaloux

Yanıtlar:


13

İki teklifin hiçbirine katılmıyorum.

Sabitler kendi olmalıdır ilgili sınıflar , değil tamamen sabit sınıfında içinde iki formun her iki önerdi.

Sadece sabit sınıflar / arayüzler olmamalıdır.

Bir sınıf CreditCard(iç sınıf değil) mevcut olmalıdır. Bu sınıf / arabirim kredisi kartlarının yanı sıra sabitleri göre yöntemleri vardır UI_EXPIRY_MONTHve UI_ACCOUNT_ID.

Bir sınıf / arayüz BankAccount(iç sınıf değil) bulunmalıdır . Bu sınıf / arayüz sabit hesapların yanı sıra banka hesaplarına göre metodlara sahiptir UI_ACCOUNT_ID.

Örneğin, Java API'sinde her sınıf / arayüz sabitleri vardır. Bir Sabitler sınıfında / arayüzünde değil, ya iç sınıflara ayrılmış ya da sınıflandırılmamış yüzlerce sabit.

Örneğin, sonuç kümeleriyle ilgili bu sabitler arayüzdedir ResultSet:

static int  CLOSE_CURSORS_AT_COMMIT 
static int  CONCUR_READ_ONLY 
static int  CONCUR_UPDATABLE 
static int  FETCH_FORWARD 
static int  FETCH_REVERSE 
static int  FETCH_UNKNOWN 
static int  HOLD_CURSORS_OVER_COMMIT 
static int  TYPE_FORWARD_ONLY 
static int  TYPE_SCROLL_INSENSITIVE 
static int  TYPE_SCROLL_SENSITIVE 

Bu arayüz, sonuç kümelerine göre yöntem imzalarına sahiptir ve uygulama sınıfları bu davranışı uygular. Onlar sadece sabit sahipleri değiller.

UI eylemleriyle ilgili bu sabitler arayüzdedir javax.swing.Action:

static String   ACCELERATOR_KEY 
static String   ACTION_COMMAND_KEY 
static String   DEFAULT 
static String   LONG_DESCRIPTION 
static String   MNEMONIC_KEY 
static String   NAME 
static String   SHORT_DESCRIPTION 
static String   SMALL_ICON 

Uygulama sınıfları, UI eylemlerine göre davranışa sahiptir, bunlar yalnızca sabit sahipleri değildir.

SwingConstantsHiçbir yöntemi olmayan en az bir "sabit" ara yüz ( ) biliyorum, ancak yalnızca birkaç tanesi yüzlerce sabit değil ve hepsi UI öğelerinin yönleri ve konumları ile ilgili:

static int  BOTTOM 
static int  CENTER 
static int  EAST 
static int  HORIZONTAL 
static int  LEADING 
static int  LEFT 
static int  NEXT 
static int  NORTH 
static int  NORTH_EAST 
static int  NORTH_WEST 
static int  PREVIOUS 
static int  RIGHT 
static int  SOUTH 
static int  SOUTH_EAST 
static int  SOUTH_WEST 
static int  TOP 
static int  TRAILING 
static int  VERTICAL 
static int  WEST 

Bence sadece sınıflar sabit değil, sınıflar iyi değil.


1
Sabitlerin yalnızca sınıfların çoğu durumda kötü bir tasarımın işareti olduğuna katılıyorum, ancak meşru kullanımlar var. Örneğin, sabit her zaman belirli bir sınıfa "ait" değildir. Android programlamada Amaç ekstraları için anahtarlar bunun somut bir örneğidir.
curioustechizen

1
+1, ancak UI sabitleri muhtemelen BankAccount gibi iş modellerinde olmamalıdır. Bazı UI sınıflarına aitler.
kevin cline

10

Sabitlerin çok dağınık olduğu ve hepsinin tek bir "ana" sabit dosya halinde düzenlenmesi gerektiği ortaya çıktı.

Bu, "bulmak zor" olan sabitlerin sorununa % 100 yanlış bir çözümdür . Bir şeyleri (ne yazık ki hepsi programcılar tarafından çok sık yapılan) sabit bir şey, numaralandırma veya ara yüz gibi teknik kriterlere göre gruplandırmak temel bir hatadır.

Katman mimarileri dışında, işler kendi alanlarına göre gruplandırılmalı ve çok düşük seviyeli öğeler oldukları için daha da sabit tutulmalıdır . Sabitler, kendilerini API'lerinin bir parçası olarak kullanan sınıfların veya arayüzlerin bir parçası olmalıdır. Yaşamak için doğal bir yer bulamazsanız, API tasarımınızı temizlemeniz gerekir.

Ek olarak, tek bir büyük sabit dosya, Java'daki geliştirme hızını öldürür çünkü sabitler, derleme zamanında bunları kullanan sınıfların içine girer, bu nedenle herhangi bir değişiklik, tüm bu dosyaların ve bunlara bağlı olanların yeniden derlenmesini zorlar. Her yerde kullanılan sabitleri olan bir dosyanız varsa, artımlı derlemenin avantajını büyük ölçüde kaybedersiniz: Eclipse'in tüm dosyalarınızı değiştirerek tüm projenizi yeniden derlemesi için 15 dakika boyunca kilitlenmesini izleyin. Ve bu dosya her yerde kullanılan tüm sabitleri içerdiğinden, oldukça sık değiştireceksiniz. Evet, kişisel deneyimlerden konuşuyorum.


Geliştirme ortamı üzerindeki potansiyel etkinin farkında değildim ve iç içe sınıf yaklaşımının bu konuda pek faydası olmayacağını düşünüyorum.
Hayal kırıklığına

1
@FrustratedWithFormsDesigner: Artımlı derleme mekanizmasının modelleme bağımlılıklarına ne kadar çaba harcadığına bağlıdır.
Michael Borgwardt

9

Haklısın. Öneriniz bir programcının import static Constants.BankAccount.*'BANKACCOUNT_' sayısız tekrarını yapmasını ve ortadan kaldırmasını sağlar . Birleştirme, gerçek kapsam belirleme için zayıf bir ikamedir. Bununla birlikte, takım kültürünü değiştirebilmeniz için çok fazla umut tutmadım. Uygun uygulamalar nosyonları vardır ve yanlış olduklarını söyleyen 100 uzman gösterseniz bile değişme ihtimalleri yoktur.

Ayrıca neden tek bir 'Sabit' dosyanız olduğunu merak ediyorum. Bu sabitlerin hepsi bir şekilde ilgili olmadıkça ve çok kararlı olmadıkça, bu çok kötü bir uygulamadır. Daha tipik olarak, sürekli değişen ve her şeye bağlı olan bir tür mutfak lavabo sınıfı haline gelir.


Şu anda UI-field ID sabitlerinin çoğunu içeren bir Constants dosyası ve alt projeye özgü birkaç sabit dosya var. Ancak şimdi alt projeye özgü sabitlerin diğer ilgili alt projeler tarafından kullanılması gerekiyor, bu yüzden hepsini bir "ana" sabit dosyada birleştirme fikrine neden oldu. Hangisi daha iyi, çünkü bazen hangi değerin bir değer için refernece için dosyayı sabitleyeceğini bile bilmiyorum ve başka bir alt projenin sabit dosyasında bulamadıkları için başka bir sabitin kopyasını yarattı.
Hayal kırıklığına

8
Sürekli değişen sabit bir sınıf ... yeterince sert kazarsanız, içinde bir zen var.
KChaloux

2
@FrustratedWithFormsDesigner: UI alan kimlikleri? Nerede bir değer bulacağınızı bilmiyor musunuz? Büyük bir WTF yığını gibi geliyor. Sende benim sempati var.
kevin cline

6

Her iki yaklaşım da işe yarar ve günün sonunda önemli olan budur.

Bununla birlikte, yaklaşımınız bir model olarak kabul edilebilecek kadar yaygındır veya sabit arayüz anti-patern üzerinde daha doğru bir gelişmedir . Neyin karmaşık olduğunu anlamıyorum, ama bu senin ekibinle yapman gereken bir tartışma.


Yeterince uzun bir sabitler listesi için, hepsinin aynı sınıfta olması yerine sabit arayüzleri bile tercih ederim. Otomatik tamamlamadan yanlış olanı seçmek tehlikeli olabilir. Tabii ki, bu ne kadar uzun olduğuna bağlı olarak :)
Goran Joviç

1
@GoranJovic Her anti-patern bir şekilde faydalıdır (veya en azından elverişli), olmasa da bir kalıp olmazdı.
yannis

1

Uzun sabit listesindeki zorluklardan biri, kullanılacak olan "doğru" sabiti bulmaktır. Her zaman, birileri hattın sonunda ait olduğu gruba eklemek yerine, bir sabitleme işaretler.

Bu, ekibinizle tartışmak için başka bir noktayı ortaya çıkarıyor - zaten sabitlerin isimleri üzerinden fiili bir kategorizasyonu var. Bu yüzden onlar için şu anki durumdan teklif ettiğiniz şeye büyük bir değişim olmamalıdır. Otomatik tamamlama özelliğinin kullanılması, sürekli aramayı daha da kolaylaştırır.

Herhangi bir şey varsa, öneriniz belirli bir duruma uygun olsa bile "yanlış" sabiti kullanmaktan vazgeçmenize yardımcı olur. Sabitleri temsili bir sınıf içine alarak geliştiricilerin kullanmaları gerekip gerekmediğini düşünmelerini teşvik edecektir. Örneğin, CreditCard.SomeConstantgenel kullanım General.SomeConstantiçin çekersem bunun yerine neden böyle bir durum olmadığını merak etmeliyim .

Canavar miktarları sabit olan projelerde bulundum ve önerdiğiniz yönteme sahip olmayı tercih ederdim. Daha temiz, daha doğrudan ve istemeden kullanılmamasını sağlar.


1

Bunu zaman zaman (C #) yapıyorum, özellikle iyi bilinen ve sabit bir XML yapısına veya benzer şekilde iç içe geçmiş ve dize ağır bir şeye karşı programlamam / ayrıştırmam gerekirse, örneğin özel bir yapılandırma bloğu ayrıştırıcısı.

Bir const string "ElementName" özelliğini ve her bir Özniteliğe (varsa) karşılık gelen benzer bir özelliği içeren öğelere karşılık gelen sınıf adlarını içeren XML'nin hiyerarşik yapısına uygun iç içe geçmiş bir sınıf yapısı oluşturdum.

İlgili Xml'ye karşı programlamayı çok kolaylaştırır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.