Interfész konstansok

A Java programozási nyelvben az interfész konstans minta meghatározza az interfészt, hogy csak konstansok tárolását hajtja végre és az ezt leszerződő osztály jogosultságot szerez ezeknek a szintetikus konstansoknak a használatára. Mivel azonban a konstansok nagyon gyakran csak egy megvalósítás részeit képezik, és az osztály által megvalósított interfészek az exportált API részét, ez a gyakorlat azt jelenti, hogy az implementációk részleteit az API-ba helyezik, melyre nem megfelelőnek ítélték (Joshua Bloch) Általánosságban elmondható, hogy a rendszer konstansok viselkedésétől független osztályokba történő összegyűjtése egy rossz objektum-orientált kialakítást eredményezhet, mert gyakran az alacsony kohézió jele.

Példa:

public interface Constants {

    double PI = 3.14159;
    double PLANCK_CONSTANT = 6.62606896e-34;
}

public class Calculations implements Constants {

    public double getReducedPlanckConstant() {
        return PLANCK_CONSTANT / (2 * PI);
    }
}

Ennek a mintának a használata további hátrányokat jelenthet:

  • Szennyezi az osztály névtérét csak olvasható változókkal, amelyek másra nem használhatók.
  • A konstans interfész megvalósítási idejével ellentétben a véletlenszerű futási időfüggvények kevés gyakorlati céllal rendelkeznek (ilyenek a jelölő interfészek, amelyeknek nincsenek metódusaik, de a futásidőben ettől függetlenül hasznosak).
  • Ha a jövőbeni kiadásokban bináris kód kompatibilitás szükséges, az állandósult interfésznek örökre egy interfésznek kell maradnia (ezt nem lehet osztályba konvertálni), még akkor is, ha nem használták interfészként a hagyományos értelemben.
  • IDE nélkül, amely megoldja, hogy az állandó rendelkezésre álljon, az időigényes lehet, ha visszavezetjük az adott osztályba vagy az interfészbe.
  • Az interfész változója (egy példányt reprezentáló) szintaktikailag nem hasznosabb, mint maga az interfész neve (mivel nincsenek módszerei).
  • Hacsak a fejlesztő nem ellenőrzi a megvalósított interfészeket, amikor egy osztályhoz hozzárendel egy konstansot, vagy nem, de az új konstans nevében hibázik, a konstans értéke hiba nélkül megváltoztatható. Lásd. 2. példa

Érdemes megjegyezni, hogy a Java könyvtárak maguk is állandó interfészmintát használnak, bizonyítva, hogy bizonyos helyzetekben ésszerű választás lehet.

2. példa

public interface Constants {

    public static final int    CONSTANT = 1;
}

public class Class1 implements Constants {

    public static final int CONSTANT = 2;    // *

    public static void main(String args[]) throws Exception {
        System.out.println(CONSTANT);
    }
}

Mielőtt hozzáadnánk a csillaggal jelölt sort a Class1 osztályhoz, a futási eredmény a helyes 1 eredményt adja. A sor hozzáadása után azonban Class1 osztály kimenete 2 lesz. Mindkét változat figyelmeztetés vagy hiba nélkül fordul le.

Alternatívák

Az anti-pattern számos buktatója elkerülhető az állandók felületének megfelelő példányra való konvertálásával:

public final class Constants {

    private Constants() {
        // restrict instantiation
    }

    public static final double PI = 3.14159;
    public static final double PLANCK_CONSTANT = 6.62606896e-34;
}

Az alábbi példa meghagyja az eredeti minta célját, főleg nem címzettként (azaz nem áll rendelkezésre a konstansokhoz való hozzáférés szintaxisa). A Java 5 óta azonban megfontolandó a statikus import használata ugyanazon cél eléréséhez:

import static Constants.PLANCK_CONSTANT;
import static Constants.PI;

public class Calculations {

    public double getReducedPlanckConstant() {
        return PLANCK_CONSTANT / (2 * PI);
    }
}

Az állandókat is importálható statikus Constants.* utasítás hozzáadásával lehet importálni. Ezzel ugyanazokat a célokat érheti el, mint egy interfész használata, lehetővé téve a konstansok névtér nélküli hivatkozását.

Különböző mértékben, a fent felsorolt kérdések most már tisztábbak lehetnek:

  •  Mivel a statikus tagok specifikusan importálhatók, az osztálynévtartományt nem kell szennyezni a konstans interfész összes tagjával.
  •  A futási idő és a fordítási idő szemantika szorosabban illeszkedik a statikus importhoz a konstans interfészekkel szemben.
  •  A lefordított kódnak eggyel kevesebb bináris kompatibilitási kényszere van (a "Calculations osztály megvalósítja a Constants-t").
  •  Mivel a statikus import csak az aktuális fájlra vonatkozik (és nem az egész osztály hierarchiára), könnyebben felfedezhető, hogy az egyes statikus tagok hol kerülnek deklarálásra.
  •  Kevésbé szükséges a konstans interfész típusú változóinak deklarálása, és potenciálisan egyértelműbb, a nincs példány létrehozva.
  • Megjegyzendő azonban, hogy a változások semmit sem tesznek a Constants osztály kohéziójának javítására, és nem akadályozzák meg a konstans értékének véletlen csendes módosítását sem, így a statikus import nem tekinthető csodaszernek.

 
 Forrás: https://en.wikipedia.org/wiki/Constant_interface