it-swarm-eu.dev

Jaký je nejlepší způsob implementace konstant v Javě?

Viděl jsem takové příklady:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

a předpokládal jsem, že bych mohl mít třídu Constants, do které by byly konstanty zabaleny, a prohlásit je za statické finále. Nevím prakticky žádnou Javu a zajímalo by mě, jestli je to nejlepší způsob, jak vytvořit konstanty.

373
mk.

To je naprosto přijatelné, pravděpodobně i standardní.

(public/private) static final TYPE NAME = VALUE;

kde TYPE je typ, NAME je jméno ve všech velkých písmenech s podtržítky pro mezery a VALUE je konstantní hodnota;

Vřele doporučuji NE vkládat vaše konstanty do svých vlastních tříd nebo rozhraní.

Jako vedlejší poznámka: Proměnné, které jsou prohlášeny za konečné a jsou proměnlivé, lze stále měnit; Proměnná však nikdy nemůže ukazovat na jiný objekt.

Například:

public static final Point Origin = new Point(0,0);

public static void main(String[] args){

    Origin.x = 3;

}

To je legální a Origin by pak byl bod na (3, 0).

403
jjnguy

Velmi doporučuji, abyste neměli jednu třídu konstant. To se může v tuto chvíli zdát dobrý nápad, ale když vývojáři odmítnou dokumentovat konstanty a třída roste, bude zahrnovat více než 500 konstant, které se navzájem nesouvisejí vůbec (vztahují se k úplně odlišným aspektům aplikace), toto obecně se stává, že soubor konstant je zcela nečitelný. Místo toho:

  • Pokud máte přístup k Java 5+, pomocí výčtů definujte své specifické konstanty pro oblast aplikace. Všechny části oblasti aplikace by se měly vztahovat na výčty, nikoli konstantní hodnoty, pro tyto konstanty. Můžete vyhlásit výčet podobný tomu, jak vyhlašujete třídu. Výčty jsou možná nejužitečnější (a pravděpodobně pouze) užitečnou funkcí Java 5+.
  • Pokud máte konstanty, které jsou platné pouze pro určitou třídu nebo jednu z jejích podtříd, deklarujte je jako chráněné nebo veřejné a umístěte je do nejvyšší třídy v hierarchii. Tímto způsobem mohou podtřídy přistupovat k těmto konstantním hodnotám (a pokud k nim přistupují jiné třídy přes veřejnost, konstanty nejsou platné pouze pro určitou třídu ... což znamená, že externí třídy používající tuto konstantu mohou být příliš pevně spojeny s třída obsahující konstantu)
  • Pokud máte rozhraní s definovaným chováním, ale vrácené hodnoty nebo hodnoty argumentů by měly být konkrétní, je naprosto přijatelné definovat konstanty na tomto rozhraní, aby k nim měli přístup další implementátoři. Vyhněte se však vytváření rozhraní pouze pro udržení konstant: může to být stejně špatné jako třída vytvořená pouze pro udržování konstant.
235
MetroidFan2002

Je to BAD PRACTICE používat rozhraní pouze k udržení konstant (pojmenovaných konstantních vzorů rozhraní Josh Bloch). Zde je to, co Josh radí:

Pokud jsou konstanty pevně svázány s existující třídou nebo rozhraním, měli byste je přidat do třídy nebo rozhraní. Například všechny číselné primitivní třídy v rámečku, například Integer a Double, exportují MIN_VALUE a MAX_VALUE konstanty. Pokud jsou konstanty nejlépe zobrazeny jako členové typu výčtu, měli byste je exportovat s typem enum. V opačném případě byste měli exportovat konstanty s neinstantibilní třídou obslužných programů.

Příklad:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

O pojmenování konvence:

Obvykle mají tato pole jména složená z velkých písmen, přičemž slova jsou oddělena podtržítky. Je důležité, aby tato pole obsahovala buď primitivní hodnoty, nebo odkazy na neměnné objekty.

120
Marcio Aguiar

V Efektivní Java (2. vydání) se doporučuje použít konstanty místo výčtu statických ints.

Na výčtech v Javě je dobrý zápis zde: http://Java.Sun.com/j2se/1.5.0/docs/guide/language/enums.html

Upozorňujeme, že na konci tohoto článku je položena otázka:

Kdy byste tedy měli používat výčty?

S odpovědí:

Kdykoli potřebujete pevnou sadu konstant

36
shelfoo

Vyhněte se použití rozhraní:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

Je to lákavé, ale porušuje zapouzdření a rozmazává rozlišení definic tříd.

21
stimpy

Používám následující přístup:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

Pak například používám Constants.DB.Connection.URL, abych byl konstantní. Vypadá to spíš „objektově orientovaně“ jako pro mě.

19
albus.ua

Vytvoření statických konečných konstant v oddělené třídě vás může dostat do potíží. Kompilátor Java to ve skutečnosti optimalizuje a umístí skutečnou hodnotu konstanty do jakékoli třídy, která ji odkazuje.

Pokud později změníte třídu „Constants“ a neděláte těžké kompilace na jiné třídy, které odkazují na tuto třídu, skončíte kombinací starých a nových použitých hodnot.

Namísto toho, abyste je považovali za konstanty, přemýšlejte o nich jako o konfiguračních parametrech a vytvořte třídu pro jejich správu. Nechte hodnoty být nekonečné a dokonce zvažte použití getterů. V budoucnu, jak zjistíte, že některé z těchto parametrů by měl být skutečně konfigurovatelný uživatelem nebo správcem, bude mnohem snazší.

17
Kevin Day

Chyba číslo jedna, kterou můžete udělat, je vytvořit globálně přístupnou třídu nazvanou s obecným názvem, jako je Constants. To se jednoduše posype odpadky a ztratíte veškerou schopnost zjistit, jaká část vašeho systému tyto konstanty používá.

Místo toho by konstanty měly jít do třídy, která je „vlastní“. Máte konstantu nazvanou TIMEOUT? Pravděpodobně by měla jít do třídy Communications () nebo Connection (). MAX_BAD_LOGINS_PER_HOUR? Přechod na uživatele (). A tak dále a tak dále.

Dalším možným použitím jsou soubory Java .properties, kdy lze za běhu definovat „konstanty“, ale snadno je uživatel změnit. Můžete je zabalit do svých .jars a odkazovat na ně s Class resourceLoader.

13
Yann Ramin

To je správná cesta.

Obecně jsou konstanty ne udržovány v oddělených třídách „konstant“, protože nejsou zjistitelné. Pokud je konstanta relevantní pro aktuální třídu, její udržení tam pomůže dalšímu vývojáři.

6
Jason Cohen

Souhlasím s tím, že používání rozhraní není cesta. Vyhnout se tomuto vzoru má dokonce svou vlastní položku (# 18) v Blochově Efektivní Java .

Argument Bloch proti konstantnímu vzoru rozhraní spočívá v tom, že použití konstant je detail implementace, ale implementace rozhraní k jejich použití odhalí tento detail implementace v exportovaném API.

Vzorec public|private static final TYPE NAME = VALUE; je dobrý způsob, jak deklarovat konstantu. Osobně si myslím, že je lepší vyhnout se vytvoření samostatné třídy, ve které budou umístěny všechny vaše konstanty, ale nikdy jsem neviděl důvod, proč to nedělat, kromě osobních preferencí a stylu.

Pokud lze vaše konstanty dobře modelovat jako výčet, zvažte strukturu enum dostupnou za 1.5 nebo novější.

Používáte-li verzi starší než 1,5, můžete stále vyčíst výčty typů pomocí běžných tříd Java. (Další informace najdete v části tento web ).

5
Rob Dickerson

A co výčet?

5
Sébastien D.

Raději používám getery než konstanty. Tito uživatelé mohou vrátit konstantní hodnoty, např. public int getMaxConnections() {return 10;}, ale vše, co potřebuje konstantu, projde getterem.

Jednou z výhod je, že pokud váš program překoná konstantu - zjistíte, že musí být konfigurovatelný - stačí změnit, jak getter vrací konstantu.

Další výhodou je, že pro úpravu konstanty nemusíte překompilovat vše, co ji používá. Když odkazujete na statické konečné pole, hodnota této konstanty se zkompiluje do jakéhokoli bajtkódu, který ji odkazuje.

5
big_peanut_horse

Na základě výše uvedených komentářů si myslím, že je to dobrý přístup, jak změnit staromódní globální konstantní třídu (mající veřejné statické konečné proměnné) na její ekvivalent jako ve výčtu takto:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_Host("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Takže je mohu označit jako:

Constants.StringConstant.DB_Host
4
Lorand Bendig

Dobrý objektově orientovaný design by neměl vyžadovat mnoho veřejně dostupných konstant. Většina konstant by měla být zapouzdřena ve třídě, která je potřebuje k výkonu své práce.

3
Bradley Harris

Odpověď na tuto otázku je určitá. Nejprve jsou konstanty v Javě obecně deklarovány jako veřejné, statické a konečné. Důvody jsou níže:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Nikdy bych nepoužíval rozhraní pro přístupový objekt/objekt CONSTANTS jednoduše proto, že se očekává, že rozhraní budou implementována. Nevypadalo by to vtipně:

String myConstant = IMyInterface.CONSTANTX;

Místo toho bych si vybral několik různých způsobů, založených na některých malých kompromisech, a tak záleží na tom, co potřebujete:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe
2
djangofan

Jaký je nejlepší způsob implementace konstant v Javě?

Jeden přístup, kterému bychom se měli opravdu vyhnout: použití rozhraní k definování konstant.

Vytvoření rozhraní konkrétně pro deklaraci konstant je opravdu to nejhorší: překonává důvod, proč byla rozhraní navržena: definování smlouvy (metod).

I když již existuje rozhraní pro řešení konkrétní potřeby, deklarace konstant v nich nemá smysl, protože konstanty by neměly být součástí API a smlouvy poskytované třídám klientů.


Pro zjednodušení máme obecně 4 platné přístupy.

S polem static final String/Integer:

  • 1) použití třídy, která deklaruje konstanty uvnitř, ale nejen.
  • 1 varianta) vytvoření třídy věnované pouze deklaraci konstant.

S Java 5 enum:

  • 2) deklarování výčtu v související třídě účelu (jako vnořená třída).
  • 2 varianta) vytvoření výčtu jako samostatné třídy (definované v jejím vlastním souboru třídy).

TLDR: Jaký je nejlepší způsob a kde najít konstanty?

Ve většině případů je cesta výčtu pravděpodobně lepší než cesta static final String/Integer a osobně si myslím, že cesta static final String/Integer by měla být použita pouze v případě, že máme dobré důvody k nepoužití výčtů.
A o tom, kde bychom měli deklarovat konstantní hodnoty, myšlenkou je hledat, zda existuje jediná existující třída, která vlastní specifickou a silnou funkční soudržnost s konstantními hodnotami. Pokud takovou třídu najdeme, měli bychom ji použít jako konstanty. Jinak by konstanta neměla být přiřazena k žádné konkrétní třídě.


static final String/static final Integer VERSUS enum

Použití výčtů je skutečně způsob, jak se důrazně zvážit.
Výčty mají oproti konstantnímu poli String nebo Integer velkou výhodu.
Stanovili silnější omezení kompilace. Pokud definujete metodu, která bere enum jako parametr, můžete předat pouze enum hodnotu definovanou ve třídě enum (nebo null).
Pomocí String a Integer je můžete nahradit libovolnými hodnotami kompatibilního typu a kompilace bude v pořádku, i když hodnota není definovaná konstanta v polích static final String/static final Integer.

Například pod dvě konstanty definované ve třídě jako pole static final String:

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

Zde metoda, která očekává, že bude mít jednu z těchto konstant jako parametr:

public void process(String constantExpected){
    ...    
}

Můžete to vyvolat takto:

process(MyClass.ONE_CONSTANT);

nebo

process(MyClass.ANOTHER_CONSTANT);

Ale žádné omezení kompilace vám nezabrání v vyvolání tímto způsobem:

process("a not defined constant value");

Tuto chybu byste měli pouze za běhu a pouze v případě, že provedete kontrolu přenášené hodnoty.

U enumu nejsou kontroly vyžadovány, protože klient mohl předat pouze enum hodnotu v enum parametru.

Například zde jsou dvě hodnoty definované ve třídě výčtu (tak konstantní mimo pole):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

Zde metoda, která očekává, že bude mít jednu z těchto hodnot výčtu jako parametr:

public void process(MyEnum myEnum){
    ...    
}

Můžete to vyvolat takto:

process(MyEnum.ONE_CONSTANT);

nebo

process(MyEnum.ANOTHER_CONSTANT);

Kompilace vám však nikdy nedovolí vyvolat to takto:

process("a not defined constant value");

Kde bychom měli deklarovat konstanty?

Pokud vaše aplikace obsahuje jednu existující třídu, která vlastní specifickou a silnou funkční soudržnost s konstantními hodnotami, objeví se 1) a 2) intuitivnější.
Obecně to usnadňuje použití konstant, pokud jsou deklarovány v hlavní třídě, která s nimi manipuluje nebo která má jméno velmi přirozené k hádání, že ji najdeme uvnitř.

Například v knihovně JDK jsou exponenciální a pí konstantní hodnoty deklarovány ve třídě, která deklaruje nejen konstantní deklarace (Java.lang.Math).

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

Klienti používající matematické funkce se často spoléhají na třídu Math. Mohou tedy najít konstanty snadno a mohou si také pamatovat, kde E a PI jsou definovány velmi přirozeným způsobem.

Pokud vaše aplikace neobsahuje existující třídu, která má velmi specifickou a silnou funkční soudržnost s konstantními hodnotami, je varianta 1) a 2 varianta) intuitivnější.
Obecně to neuľahčuje použití konstant, pokud jsou deklarovány v jedné třídě, která s nimi manipuluje, zatímco máme také 3 nebo 4 další třídy, které s nimi manipulují stejně, a zdá se, že žádná z těchto tříd není přirozenější než ostatní pro hostování konstantních hodnot.
Zde má smysl definovat vlastní třídu pro uchovávání pouze konstantních hodnot.
Například v knihovně JDK není výčet Java.util.concurrent.TimeUnit v určité třídě deklarován, protože ve skutečnosti neexistuje jedna a pouze jedna třída specifická pro JDK, která se jeví jako nejintuitivnější pro její držení:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Mnoho tříd deklarovaných v Java.util.concurrent je používá: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... a opravdu nikdo z nich se nezdá být vhodnější držet výčet.

2
davidxxx

FWIW, hodnota časového limitu v sekundách by pravděpodobně měla být konfiguračním nastavením (načteno ze souboru vlastností nebo pomocí injekce jako na jaře) a ne konstantou.

1
Tim Howland

Jaký je rozdíl

1.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2.

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

a pomocí MyGlobalConstants.TIMEOUT_IN_SECS kdekoli potřebujeme tuto konstantu. Myslím, že oba jsou stejné.

1
chandrayya

Jedna třída generických konstant je špatný nápad. Konstanty by měly být seskupeny společně se třídou, se kterou nejvíce logicky souvisejí.

Namísto použití proměnných jakéhokoli druhu (zejména výčtů) bych navrhl použít metody. Vytvořte metodu se stejným názvem jako proměnná a nechte ji vrátit hodnotu, kterou jste proměnné přiřadili. Nyní smažte proměnnou a nahraďte všechny její odkazy voláními právě vytvořené metody. Pokud máte pocit, že konstanta je natolik obecná, že byste nemuseli vytvářet instanci třídy, abyste ji mohli použít, pak z konstantní metody udělejte metodu třídy.

1
ab

Konstanta libovolného typu může být deklarována vytvořením neměnné vlastnosti, která je ve třídě (to je členská proměnná s modifikátorem final). Obvykle jsou také k dispozici modifikátory static a public.

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

Existuje celá řada aplikací, kde hodnota konstanty označuje výběr z n-Tuple (např. výčet) možností. V našem příkladu se můžeme rozhodnout definovat enumerovaný typ, který omezí možné přiřazené hodnoty (tj. Vylepšené type-safety):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}
1
Ryan Delucchi

Nevolal bych třídu stejně (kromě pouzdra) jako konstanta ... měl bych alespoň jednu třídu „Nastavení“ nebo „Hodnoty“ nebo „Konstanty“, kde by všechny konstanty žily. Pokud jich mám velký počet, seskupil bych je do logických tříd konstant (UserSettings, AppSettings atd.)

0
Joel Martinez

static final je moje preference, enum bych použil jen tehdy, pokud byla položka skutečně vyčíslitelná.

0
wulfgarpro

Je BAD zvyk a strašně ZVYŠUJÍCÍ praxe citovat Joshua Blocha bez pochopení základního základního nulového fundamentalismu.

Nic jsem nečetl, Joshua Bloch, takže taky

  • on je hrozný programátor
  • nebo lidé, u kterých jsem zjistil, že ho cituji (Joshua je jméno chlapce, kterého předpokládám), jednoduše používají svůj materiál jako náboženské skripty, aby ospravedlnili své softwarové náboženské odpustky.

Stejně jako v biblickém fundamentalismu lze všechny biblické zákony shrnout

  • Milujte základní identitu celým svým srdcem a celou svou myslí
  • Milujte svého souseda jako sebe

a tak podobně lze shrnout fundamentalismus softwarového inženýrství

  • věnujte se základním nulovým základům se všemi svými programovacími silami a myslí
  • a věnovat se dokonalosti svých kolegů-programátorů, jako byste sami pro sebe.

Také mezi biblickými fundamentalistickými kruhy je nakreslen silný a rozumný důsledek

  • Nejprve se milujte. Protože pokud se nemilujete sami sebe, pak koncept „milujte svého souseda jako sebe“ nese velkou váhu, protože „jak moc se milujete sami sebe“ je počáteční linie, nad kterou byste milovali ostatní.

Podobně, pokud nerespektujete sebe sama jako programátora a pouze přijímáte prohlášení a proroctví některých programovacích guru-nath BEZ zpochybňování základů, vaše citace a spoléhání se na Joshua Bloch (a podobně) nemají význam. A proto byste ve skutečnosti neměli vůči svým spolu-programátorům žádnou úctu.

Základní zákony programování softwaru

  • lenost je ctnost dobrého programátora
  • musíte učinit svůj programový život co nejjednodušší, tak líný a tedy co nejefektivnější
  • musíte učinit důsledky a vnitřnosti svého programování tak snadným, líným a proto co nejefektivnějším pro vaše sousedské programátory, kteří s vámi pracují, a vyzvedněte si vaše programové vnitřnosti.

Konstanty rozhraní jsou špatným zvykem ???

Do jakých zákonů zásadně efektivního a odpovědného programování spadá toto náboženské nařízení?

Prostě si přečtěte článek wikipedie o konstantách vzorů rozhraní ( https://en.wikipedia.org/wiki/Constant_interface ) a hloupé výmluvy uvádí proti konstantám vzorů rozhraní.

  • Whatif-No IDE? Kdo na Zemi jako softwarový programátor by IDE nepoužíval? Většina z nás jsou programátoři, kteří dávají přednost tomu, aby nemuseli prokazovat machoesetický survivalismus, který by se vyhnul použití IDE.

    • Také - vyčkejte druhé zastánce mikrofunkčního programování jako prostředek nepotřebování IDE. Počkejte, až si přečtete moje vysvětlení normalizace datového modelu.
  • Znečišťuje obor názvů proměnnými, které nejsou použity v aktuálním rozsahu? Mohli by být zastánci tohoto názoru

    • nejsou si vědomi a není třeba normalizace datového modelu
  • Používání rozhraní pro vynucení konstant je zneužití rozhraní. Zastánci takových mají špatný zvyk

    • nevidí, že „konstanty“ musí být považovány za smlouvy. A rozhraní se používají k vynucení nebo projektování souladu se smlouvou.
  • V budoucnu je obtížné, ne-li nemožné převést rozhraní na implementované třídy. Hah .... hmmm ... ???

    • Proč byste se chtěli zapojit do takové struktury programování, jako je vaše trvalé živobytí? IOW, proč se věnovat tak AMBIVALENTU a špatnému programovacímu zvyku?

Ať jsou omluvy jakékoli omluvy, neexistuje PLATNÝ VÝSLEDEK, pokud jde o FUNDAMENTÁLNĚ EFEKTIVNÍ softwarové inženýrství, které delegitimizuje nebo obecně odrazuje od používání konstant rozhraní.

Nezáleží na tom, jaké byly původní záměry a duševní stavy zakladatelů, kteří vytvořili ústavu Spojených států. Mohli bychom diskutovat o původních záměrech zakladatelů, ale záleží mi jen na písemných prohlášeních o Ústavě USA. A je úkolem každého občana USA, aby využil písemného literárního fundamentalismu, nikoli nepsaných zakladatelských záměrů americké ústavy.

Podobně mi nezáleží na tom, co „původní“ záměry zakladatelů platformy Java a programovacího jazyka pro toto rozhraní měly. Zajímají mě efektivní funkce, které specifikace Java poskytuje, a tyto funkce chci plně využívat, aby mi pomohl splnit základní zákony zodpovědného programování softwaru. Je mi jedno, jestli jsem vnímán jako „porušující záměr rozhraní“. Je mi jedno, co Gosling nebo někdo Bloch říká o „správném způsobu používání Java“, pokud to, co říkají, neporušuje mou potřebu EFEKTIVNÍ plnění zásad.

Základem je normalizace datového modelu

Nezáleží na tom, jak je váš datový model hostován nebo přenášen. Ať už používáte rozhraní nebo výčty nebo cokoli, relační nebo ne-SQL, pokud nerozumíte potřebě a procesu normalizace datového modelu.

Nejprve musíme definovat a normalizovat datový model sady procesů. A když máme koherentní datový model, POUZE pak můžeme použít procesní tok jeho komponent k definování funkčního chování a proces blokuje pole nebo oblast aplikací. A teprve potom můžeme definovat API každého funkčního procesu.

Dokonce i aspekty normalizace dat, jak navrhuje EF Codd, jsou nyní vážně zpochybněny a vážně zpochybněny. např. jeho prohlášení o 1NF bylo kritizováno jako nejednoznačné, nevyrovnané a příliš zjednodušené, stejně jako zbytek jeho tvrzení, zejména při příchodu moderních datových služeb, repo technologie a přenosu. IMO, příkazy EF Codd by měly být zcela prohloubeny a měla by být navržena nová sada více matematicky věrohodných příkazů.

Do očí bijící vadu EF Codd a příčinu jejího vyrovnání k efektivnímu pochopení člověka je jeho přesvědčení, že lidsky vnímatelná vícerozměrná data s proměnlivou dimenzí mohou být účinně vnímána prostřednictvím sady dílčích dvojrozměrných mapování.

Základy normalizace dat

Co EF Codd nedokázal vyjádřit.

V každém koherentním datovém modelu se jedná o postupné odstupňované pořadí koherence datového modelu, které má být dosaženo.

  1. Jednota a identita datových instancí.
    • navrhnout granularitu každé datové komponenty, přičemž jejich granularita je na úrovni, kde lze každou instanci komponenty jedinečně identifikovat a načíst.
    • absence aliasu instance. tj. neexistují žádné prostředky, pomocí kterých by identifikace vytvořila více než jednu instanci komponenty.
  2. Nepřítomnost přeslechu. Neexistuje nutnost použít jednu nebo více jiných instancí komponenty k přispění k identifikaci instance komponenty.
  3. Jednota a identita datových složek/rozměrů.
    • Přítomnost odstraňování aliasu. Musí existovat jedna definice, pomocí které lze jednoznačně identifikovat komponentu/dimenzi. Což je primární definice komponenty;
    • kde primární definice nebude mít za následek odhalení dílčích rozměrů nebo dílčích součástí, které nejsou součástí zamýšlené součásti;
  4. Unikátní prostředky řešení obchodů s komponenty. Musí existovat jedna a pouze jedna taková definice de-aliasingu komponenty.
  5. Existuje jedno a pouze jedno rozhraní pro definici nebo smlouva k identifikaci nadřazené komponenty v hierarchickém vztahu komponent.
  6. Nepřítomnost přeslechů součástí. Neexistuje nutnost použít člena jiné komponenty k přispění ke konečné identifikaci komponenty.
    • V takovém vztahu mezi rodičem a dítětem nesmí identifikační definice rodiče záviset na části sady členských komponent dítěte. Členská komponenta totožnosti rodiče musí být úplnou dětskou identitou, aniž by se uchýlila k odkazu na kterékoli nebo všechny děti dítěte.
  7. Vyloučit bimodální nebo multimodální vzhled datového modelu.
    • Pokud existují dvě kandidátní definice komponenty, je zřejmé, že existují dva různé datové modely smíchané jako jeden. To znamená, že na úrovni datového modelu nebo na úrovni pole existuje nesoulad.
    • Pole aplikací musí koherentně používat jeden a pouze jeden datový model.
  8. Detekce a identifikace mutace komponenty. Pokud jste neprovedli statistickou analýzu obrovských dat, pravděpodobně nevidíte ani nevidíte potřebu léčit mutaci komponent.
    • Datový model může mít některé jeho komponenty cyklicky nebo postupně mutovat.
    • Režim může být rotace členů nebo transpozice rotace.
    • Mutace rotace členů by mohla být zřetelným zaměněním podřízených komponent mezi komponenty. Nebo kde by musely být definovány zcela nové komponenty.
    • Transpoziční mutace by se projevila jako dimenzionální člen mutující do atributu, naopak.
    • Každý mutační cyklus musí být identifikován jako odlišný datový modál.
  9. Aktualizujte každou mutaci. Tak, že můžete vytáhnout předchozí verzi datového modelu, když možná vyvstane potřeba léčit 8letou mutaci datového modelu.

V poli nebo mřížce aplikací mezi jednotlivými službami musí existovat jeden a pouze jeden koherentní datový model nebo musí existovat prostředek pro datový model/verzi pro jeho identifikaci.

Stále se ptáme, zda bychom mohli použít konstanty rozhraní? Opravdu?

V sázce jsou otázky normalizace dat, které jsou důslednější než tato světská otázka. Pokud tyto problémy nevyřešíte, zmatek, který si myslíte, že konstanty rozhraní způsobují, není nic. Zilch.

Z normalizace datového modelu pak určete komponenty jako proměnné, jako vlastnosti, jako konstanty rozhraní kontraktu.

Poté určíte, které vstupuje do vkládání hodnot, do umístění konfigurace objektů, rozhraní, finálních řetězců atd.

Pokud musíte použít omluvu, že je třeba lokalizovat komponentu, která je snadnější diktovat proti konstantám rozhraní, znamená to, že jste ve špatném zvyku nepraktizovat normalizaci datového modelu.

Možná budete chtít zkompilovat datový model do vydání vcs. Že můžete vytáhnout zřetelně identifikovatelnou verzi datového modelu.

Hodnoty definované v rozhraní jsou zcela zajištěny, že jsou nemutovatelné. A rozdělitelné. Proč načíst sadu konečných řetězců do své třídy z jiné třídy, když vše, co potřebujete, je ta sada konstant?

Proč tedy neveřejnit smlouvu o datovém modelu? Myslím, že pokud to dokážete spravovat a normalizovat jednotně, proč ne? ...

public interface CustomerService {
  public interface Label{
    char AssignmentCharacter = ':';
    public interface Address{
      String Street = "Street";
      String Unit= "Unit/Suite";
      String Municipal = "City";
      String County = "County";
      String Provincial = "State";
      String PostalCode = "Zip"
    }

    public interface Person {
      public interface NameParts{
        String Given = "First/Given name"
        String Auxiliary = "Middle initial"
        String Family = "Last name"
      }
    }
  }
}

Nyní mohu odkazovat na smluvní štítky svých aplikací, například

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family

To zaměňuje obsah souboru jar? Jako programátor Java se nestarám o strukturu nádoby.

To představuje složitost osgi-motivovaného běhového swapování? Osgi je mimořádně účinný prostředek, který programátorům umožňuje pokračovat ve špatných návycích. Jsou lepší alternativy než osgi.

Nebo proč ne? Do zveřejněné smlouvy nedochází k úniku soukromých Konstant. Všechny soukromé konstanty by měly být seskupeny do soukromého rozhraní s názvem „Konstanty“, protože nechci hledat konstanty a jsem příliš líný, abych opakovaně psal „soukromý finální řetězec“.

public class PurchaseRequest {
  private interface Constants{
    String INTERESTINGName = "Interesting Name";
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Možná i toto:

public interface PurchaseOrderConstants {
  public interface Properties{
    default String InterestingName(){
       return something();
    }
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Jediný problém s konstantami rozhraní, které stojí za zvážení, je, když je rozhraní implementováno.

Toto není „původní záměr“ rozhraní? Jako bych se staral o „původní úmysl“ zakladatelů při tvorbě americké ústavy, než o to, jak by nejvyšší soud interpretoval písemné dopisy americké ústavy ???

Koneckonců, bydlím v zemi svobodných, divočiny a domova statečných. Buďte stateční, buďte svobodní, buďte divočejší - použijte rozhraní. Pokud moji kolegové-programátoři odmítnou používat efektivní a líné prostředky programování, jsem povinen podle zlatého pravidla snížit účinnost programování tak, aby byla v souladu s jejich? Možná bych měl, ale to není ideální situace.

0
Blessed Geek

Abychom to udělali o krok dále, můžete umístit globálně používané konstanty do rozhraní, aby je bylo možné použít v celém systému. Např.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

Pak to ale neimplementujte. Prostě na ně odkazujte přímo v kódu pomocí plně kvalifikovaného názvu třídy.

0

K deklaraci konstant používám static final a používám notaci ALL_CAPS. Viděl jsem několik skutečných životních situací, kdy jsou všechny konstanty seskupeny do jednoho rozhraní. Několik příspěvků to správně označilo za špatný postup, hlavně proto, že to není to, pro co je rozhraní určeno. Rozhraní by mělo vynucovat smlouvu a nemělo by být místem, do kterého by mohly být umístěny nesouvisející konstanty. Pokud je konstantní sémantika nepatří do určité třídy (není možné ji konkretizovat (prostřednictvím soukromého konstruktéra)), dá se to dohromady. es). Vždy jsem ve třídě dal konstantu, s níž to nejvíce souvisí, protože to dává smysl a je také snadno udržovatelné.

Výčty jsou dobrou volbou pro reprezentaci celé řady hodnot, ale pokud ukládáte samostatné konstanty s důrazem na absolutní hodnotu (např. TIMEOUT = 100 ms), můžete jednoduše použít přístup static final.

0
bincob

Pro Constants je Enum lepší volbou IMHO. Zde je příklad

public class myClass {

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}
0
mmansoor

Souhlasím s tím, co většina říká, že je nejlepší používat výčty při jednání se sbírkou konstant. Pokud však programujete v systému Android, existuje lepší řešení: IntDef Annotation .

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

Anotace IntDef je lepší než výčty jednoduchým způsobem, zabírá podstatně méně místa, protože je to jednoduše značka kompilace. Nejedná se o třídu, ani o vlastnost automatického převodu řetězců.

0
Quinn Turner

Jedním ze způsobů, jak to dělám, je vytvoření „globální“ třídy s konstantními hodnotami a statický import ve třídách, které potřebují přístup ke konstantě.

0
Javamann