Sabitleri tanımlamak için bir arayüze sahip olmak kötü bir uygulama mıdır?


40

Java'da bir dizi test testi sınıfı yazıyorum. Birkaç sabit var, örneğin farklı test sınıflarında ihtiyacım olacak dizeler. Onları tanımlayan bir arayüz düşünüyorum ve her test sınıfı onu uygulayacaktır.

Orada gördüğüm faydalar:

  • Sabitlere kolay erişim: MY_CONSTANTyerineThatClass.MY_CONSTANT
  • her sabit sadece bir kez tanımlanır

Bu yaklaşım iyi ya da kötü bir uygulama mıdır? Arayüz kavramını biraz kötüye kullanmak gibi hissediyorum.

Genel olarak arayüzler / sabitler hakkında ama ayrıca özel bir şey varsa birim testleri hakkında da cevap verebilirsiniz.


“Arayüzün X'i tanımlaması kötü bir uygulamadır?” Yanıtı, X'in “yöntem imzaları” olmayan bir şey olduğu hemen hemen her zaman kesinlikle “Evet” tir.
T. Sar - Monica

Yanıtlar:


79

Joshua Bloch, Etkin Java adlı kitabında buna karşı tavsiyelerde bulunuyor :

Bir sınıfın dahili olarak bazı sabitleri kullanması bir uygulama detayıdır. Sabit bir arayüz uygulamak, bu uygulama detayının dışa aktarılan API sınıflarına sızmasına neden olur. Sınıfın sabit bir arayüz uyguladığı bir sınıfın kullanıcıları için bir sonuç değildir. Aslında, onların kafasını bile karıştırabilir. Daha da kötüsü, bir taahhüdü temsil eder: ileriki bir sürümde, sınıf artık sabitleri kullanmaya gerek kalmayacak şekilde değiştirildiyse, yine de ikili uyumluluğu sağlamak için arayüzü uygulamalıdır.

Aynı efekti sabitleri tanımlayan normal bir sınıfla alabilir ve sonra kullanabilirsiniz. import static com.example.Constants.*;


13

Bizim durumumuzda bunu yapıyoruz çünkü sabitlerin değerleri, bir hizmet uygulamasının sağlanması gerektiğine dair bir sözleşmeyi temsil ediyor. Bu sabitleri ara yüze koymak, son durumları sözleşmenin bir parçası olarak belirtir ve ara yüzün herhangi bir uygulaması bunları kullanmadıysa, işini yapmaz.

Bazı sabitler uygulama detaylarıdır. Birileri onlar değil. Her zamanki gibi, bir mühendis ne yapacağına karar vermek için beynini kullanmalı ve kapsamlı bir forma veya uygulamaya dayanmamalı.


7

Arayüzlerin sadece sabitler için olması iyi bir şey değil .

Ancak, davranışı tanımlayan bir arayüzde (sınıfları uygulayan yöntemler uygulanmalıdır), sabitler varsa, tamamdır. O takdirde "Bazı implementor en detay sızdırıyor" API içine olması gerektiği yolu becasuse, bu kadar. Ayrıca, uygulayıcının foo ve bar yöntemlerini uygulamasından da kaçıyorlar.

Örneğin, java.awt.Transparency arayüzünü ele alalım. OPAQUE, BITMASK ve TRANSLUCENT sabitlerine sahiptir, ancak getTransparency () metoduna sahiptir.

Tasarımcı bu sabitleri koyarsa, getTransparency () olduğu gibi arayüzün bir parçası olacak kadar kararlı olacağını düşündü.


2

Bunun, sözleşmeyle tasarımın hakim olduğu yerlerde çoğunlukla popüler olan bir bakış açısı olduğunu düşünüyorum.
Arayüzler sözleşmelerdir. Arayüzlere sabitler koymak, sözleşmenin uyguladığı her sınıfın sabit tarafından tanımlanan değeri / kavramı kabul ettiği anlamına gelir.


1
Arayüzler kamu ihaleleridir. Sabit DEĞERLER özel kaygılardır, kamu arayüzü en çok isimlerini göstermelidir. Bu soyut bir sınıfa kalan en iyisidir.
jwenting

Buradaki vakalar: javax.naming.Context, javax.ims.Session ve bu tür arayüzlerin yüzlerce ...
CMR

2
@jwenting Ayrıca, "at most expose their names"değerleri açığa vurmadan ortak bir arayüz olabilir mi?
CMR

Bu sanırım programlama diline bağlı. Java durumunda, hayır.
Ağustos'ta

2

Çalıştığım bir şirket arayüzü ithal 1 sabitleri ağır kullandı . Hiçbir zarar geldiğini hissetmiyorum.

Kendine sorman gereken soru şu, senin için isim alanı ne kadar önemli? Sabitler söz konusu olduğunda, gerçekten tüm sınıflar böyle davranır. Binlerce sabitiniz varsa, bu sabitlerin tümünü her zaman kullanılabilir durumda istemeyebilirsiniz.

Arayüzlerle ilgili harika şey, size her iki şekilde de çalışmanın faydasını verir - ihtiyacınız olan tüm ad alanlarını getirin veya hiçbirini getirmeyin (ve onlara açıkça erişin MyInterface.CONSTANT). Hemen hemen aynı şey import static MyInterface.*, ama biraz daha açık.


1: Java’ya aşina değilseniz, importanahtar kelimeyi kastetmiyorum, sadece üzerinden getirilenleri kastettim.implements MyConstantsInterface


1

Çoğunlukla 'Ada yolu' ve '.Net yolu' tarafından etkilenen bir arka plandan geliyorum. Hayır derdim, muhtemelen arayüzler içinde sabitleri bildirmenin en iyisi değil. Teknik olarak c # 'a izin verilmez.

Hayır dememin sebebi, arayüzün durumu veya yapıyı değil davranışı tanımlayan bir sözleşme şekli olmasıdır. Bir sabit, bir tür devlet (ilkel) veya bir devlet yönü (bileşik veya toplu) anlamına gelir.

Varsayılanları ve önceden tanımlanmış değerleri arayüzü uygulayan herkes için erişilebilir hale getirme dürtüsünü takdir edebilirim, ancak varsayılan değer, varsayılan değerlerin en az minimum içeriğe sahip olacağı bir soyut veya değer nesnesinde veya şablonunda daha iyi tanımlanabilir.

Daha teknik bir rehber için: download.oracle.com/javase/1.5.0/docs/guide/language/static-import.html


Statik İthalat'a (1.5) atıfta bulunarak daha fazla bağlantı ekleme: 1. Vikipedi 2. Oracle Docs referansı @Justinc
Abhijeet

1
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Oracle
Docs'tan

1

Hayır, genel bir kötü uygulama değildir.

Mesele şu ki, herhangi bir başka eserde olduğu gibi sabitler asgari görünürlük ve uygun soyutlama seviyesi kuralları altında tanıtılmalıdır.

Sözdizimi yalnızca yapabildiğiniz için kullanmak asıl sorun olabilir.

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.