it-swarm-eu.dev

Je špatné mít rozhraní pro definování konstant?

Píšu sadu junitských testovacích tříd v Javě. Existuje několik konstant, například řetězce, které budu potřebovat v různých testovacích třídách. Mám na mysli rozhraní, které je definuje a každá testovací třída by jej implementovala.

Výhody, které vidím, jsou:

  • snadný přístup ke konstantám: MY_CONSTANT namísto ThatClass.MY_CONSTANT
  • každá konstanta je definována pouze jednou

Je tento přístup spíše dobrou nebo špatnou praxí? Cítím se, jako by to bylo trochu jako zneužívání pojmu rozhraní.

Obecně můžete odpovídat na rozhraní/konstanty, ale také na testy jednotek, pokud je na tom něco zvláštního.

45
FabianB

Joshua Bloch proti tomu radí ve své knize s názvem Efektivní Java:

To, že třída interně používá některé konstanty, je detail implementace. Implementace konstantního rozhraní způsobí, že tento detail implementace vyteče do exportovaného API tříd. Pro uživatele třídy nemá žádný důsledek, že třída implementuje konstantní rozhraní. Ve skutečnosti je dokonce může zaměnit. Horší je, že jde o závazek: pokud je třída v budoucnu upravena tak, že již nemusí používat konstanty, musí implementovat rozhraní, aby zajistila binární kompatibilitu.

Stejného efektu můžete dosáhnout s normální třídou, která definuje konstanty, a poté použijte import static com.example.Constants.*;

88
matt

V našem případě to děláme proto, že hodnoty konstant představují smlouvu pro koncové stavy, které je vyžadována implementace služby. Vložení těchto konstant do rozhraní specifikuje konečné stavy jako součást smlouvy, a pokud by je nějaká implementace rozhraní nevyužila, nedělala by svou práci.

Konstanty SOMETIMES jsou detaily implementace. Někdy nejsou. Jako obvykle musí technik použít svůj mozek, aby se rozhodl, co má dělat, a nespoléhal se na zametací vzorec nebo praxi.

14
user144901

Nemyslím si, že je dobré mít rozhraní pouze pro konstanty.

Ale pokud rozhraní, které definuje chování (metody implementující třídy by se měly implementovat), má konstanty, je to v pořádku. Pokud „uniká nějaký detail implementátoru“ do API, je to proto, že by to tak mělo být. Rovněž unikají, že implementátor implementuje metody .foo() a .bar().

Vezměme si například rozhraní Java.awt.Transparency. Má OPAQUE, BITMASK a TRANSLUCENT konstanty, ale také má metodu .getTransparency().

Pokud tam konstruktér umístil tyto konstanty, je to proto, že si myslel, že by byl dostatečně stabilní, aby byl součástí rozhraní, jako je .getTransparency().

6

Společnost, na které jsem pracoval, intenzivně využívala importované rozhraní1 konstanty. Necítím žádnou škodu.

Otázka, na kterou byste se měli ptát, zní: jak důležité je pro vás jmenování? V případě konstant je to opravdu všechno, co třída funguje. Máte-li tisíce konstant, možná nebudete chtít, aby všechny tyto konstanty byly vždy k dispozici.

Skvělá věc o rozhraních je, že vám přináší výhodu práce v obou směrech - přineste všechny jmenné prostory, které potřebujete, nebo žádné z nich (a k nim explicitně přistupujte pomocí MyInterface.CONSTANT). Skoro stejná věc jako import static MyInterface.*, ale trochu více zřejmé.


1: Pokud nejste obeznámeni s Javou, nemyslím tím klíčové slovo import, myslím tím přivedeno přes implements MyConstantsInterface

2
Nicole

Mysli si, že je to hledisko, které je většinou oblíbené v místech, kde převažuje design na zakázku.
Rozhraní jsou smlouvy. Umístění konstant do rozhraní znamená, že každá třída, která dodržuje smlouvu, souhlasí s hodnotou/konceptem identifikovaným konstantou.

2
CMR

Ne, nejedná se o všeobecnou špatnou praxi.

Jde o to, že konstanty jako jakýkoli jiný artefakt by měly být zavedeny podle pravidel minimální viditelnosti a správné úrovně abstrakce.

Použití syntaxe pouze proto, že můžete, je skutečný problém.

1
oopexpert

Pocházím z pozadí, které je většinou ovlivněno především „Ada“ a „.Net“. Řekl bych ne, že asi není nejlepší deklarovat konstanty uvnitř rozhraní. V c # není technicky povoleno.

Důvod, proč říkám ne, je, že rozhraní je forma smlouvy, která definuje chování, nikoli stav nebo strukturu. Konstanta znamená nějaký druh stavu (primitivní) nebo aspekt státu (složený nebo agregovaný).

Oceňuji nutkání zpřístupnit výchozí hodnoty a předdefinované hodnoty každému, kdo implementuje rozhraní, ale výchozí stav by byl lépe popsán v abstraktním nebo hodnotovém objektu nebo šabloně, kde by výchozí hodnoty měly alespoň minimální kontext.

Další technický průvodce: download.Oracle.com/javase/1.5.0/docs/guide/language/static-import.html

1
JustinC