Konstans interfész

A Java programozásban a konstans interfész minta azt jelenti, hogy interfészeket használnak megosztott konstansok definiálására. Azok az osztályok, amelyeknek ezekre szükségük van, megvalósítják az interfészt.

A konstansok gyakran csak implementációs részletek, így nem kellene az osztály API-jához tartozniuk.[1] Általában a rendszerkonstansok kihelyezése egy viselkedéstől független osztályba a gyenge kohézió jele, így kerülendő. Mindemiatt a konstans interfész antimintának tekinthető.

Hátrányok szerkesztés

A konstans interfész hátrányai közé tartoznak:

  • Szennyezi az osztály névterét olyan konstansokkal, amiket nem biztos, hogy használ.
  • A fordításidejű taktikai hasznával szemben futásidőben kicsi a jelentősége. Szemben a jelölő interfészekkel, amelyek nem írnak elő metódusokat, de futásidőben hasznosak.
  • Ha fenn kell tartani a bináris kompatibilitást, akkor az interfészt nem lehet osztállyá alakítani, még akkor sem, ha úgy már több értelme lenne.
  • Fejlesztőkörnyezet segítsége nélkül (ami segít visszakövetni, hogy mi honnan származik), sok időbe telhet visszanyomozni, amíg kiderül, hogy ezek a konstansok honnan származnak.
  • Mivel az interfésznek nincsenek metódusai, azért egy interfésszel megadott változó szintaktikailag nem hasznosabb, mint az interfész maga.
  • Ha konstans hozzáadása előtt a fejlesztő nem ellenőrzi az osztály összes interfészét, vagy ezt megteszi ugyan, de elírja a konstans nevét, akkor a konstans értéke figyelmeztetés nélkül megváltozhat.

Lásd a 2. példát.

Egyes Java könyvtárak használják ezt a módszert, ami néhány helyzetben indokolható.[2]

1. példa szerkesztés

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);
	}
}

2. példa szerkesztés

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);
	}
}

A csillaggal jelölt sor nélkül a Class1 kiírása: 1. A csillag utáni sort betéve a kiíratás eredménye: 2. Mindkét változat hiba és figyelmeztetés nélkül fordul.

Megoldás szerkesztés

Az interfész átalakítása állapot nélküli osztállyá megoldja a legtöbb problémát:

public final class Constants {

	private Constants() {
		// restrict instantiation
	}

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

A Java 1.5 óta a static import segít abban, hogy ezek a nevek minősítés nélkül elérhetők legyenek: [3]

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

public class Calculations {

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

Az összes konstans is importálható az import static Constants.* deklarációval, ezzel eléri ugyanazt a célt, mint az interfész, a konstansok névtér nélkül hozzáférhetők.

Az interfész használatának több problémája is megoldódik:

  • Nincs névtérszennyezés. Vagy minősítve hivatkozzuk a konstansokat, vagy importáljuk azokat, amelyek kellenek, és másokat nem.
  • A futásidejű és fordításidejű szemantika jobban igazodik egymáshoz a static importtal, mint az interfész esetén.
  • Kevesebb a megkötöttség a bináris kompatibilitással kapcsolatban.
  • Mivel csak az adott fájlra vonatkozik, és nem a teljes hierarchiára, könnyebb visszakövetni a konstansok származását.
  • Nem akarnak példányokat létrehozni ezzel a típussal.

Azonban a kohéziót nem erősíti, mivel még mindig meg lehet változtatni egyes konstansok értékét, tehát nem old meg mindent.

Jegyzetek szerkesztés

  1. Bloch, Joshua, Effective Java, 2nd Edition, p. 98
  2. "SwingConstants"
  3. "Static Import"

Fordítás szerkesztés

Ez a szócikk részben vagy egészben a Constant interface című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.