it-swarm-eu.dev

Je někdy dobré vložit hodnoty do našich aplikací?

Je někdy dobré vložit hodnoty do našich aplikací? Nebo je vždy správné říkat tyto typy hodnot dynamicky v případě, že se potřebují změnit?

45
Edward

Ano, ale udělejte to zřejmé.

Dělat:

  • použijte konstanty
  • použijte název proměnné popisné

Ne:

64
J.K.

Co se mi zatím na těchto otázkách a otázkách jeví jako zvláštní, je to, že se nikdo ve skutečnosti nepokusil jasně definovat „pevný kód“ nebo, co je důležitější, alternativy.

tl; dr: Ano, je někdy dobrý nápad na hodnoty v pevném kódu, ale neexistuje jednoduché pravidlo, jak kdy ; zcela záleží na kontextu.

Otázka ji zúží dolů na hodnoty , které považuji za magická čísla , ale odpověď na to, zda jsou dobrý nápad, je vzhledem k k čemu jsou ve skutečnosti používány!

Několik příkladů „pevně zakódovaných“ hodnot je:

  • Konfigurační hodnoty

    Kroužím, kdykoli vidím tvrzení jako command.Timeout = 600. Proč 600? Kdo to rozhodl? Dočasně to vypršelo a někdo namísto vyřešení problému s výkonem zvýšil časový limit jako hack? Nebo je to vlastně nějaká známá a zdokumentovaná očekávání pro dobu zpracování?

    Neměla by to být magická čísla nebo konstanty, měla by být externalizována v konfiguračním souboru nebo databázi někde s smysluplným názvem, protože jejich optimální hodnota je určována převážně nebo zcela prostředím že aplikace běží.

  • Matematické vzorce

    Vzorce obvykle bývají docela statické, takže povaha konstantních hodnot uvnitř není opravdu důležitá. Objem pyramidy je (1/3) b * h. Záleží nám na tom, odkud 1 nebo 3 pocházejí? Spíš ne. Předchozí komentátor správně poukázal na to, že diameter = radius * 2 Je pravděpodobně lepší než diameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR - ale je to falešná dichotomie.

    Co byste měli udělat pro tento typ scénáře, je vytvoření funkce . Nepotřebuji vědět, jak jste přišli se vzorcem, ale stále potřebuji vědět k čemu slouží . Pokud místo kteréhokoli z výše uvedených nesmyslů píšu volume = GetVolumeOfPyramid(base, height), najednou se všechno stane mnohem jasnějším a je naprosto v pořádku mít magická čísla uvnitř (return base * height / 3), protože je zřejmé, že jsou jen součástí vzorce.

    Klíčem je samozřejmě mít krátké a jednoduché funkce . Toto nefunguje pro funkce s 10 argumenty a 30 řádky výpočtů. V takovém případě použijte funkci složení nebo konstanty.

  • Doménová/obchodní pravidla

    Toto je vždy šedá oblast, protože záleží na tom, co přesně je hodnota. Většinu času jsou to právě tato magická čísla, která jsou kandidáty na proměnu v konstanty, protože to usnadňuje pochopení programu bez komplikací logiky programu. Zvažte test if Age < 19 Vs. if Age < LegalDrinkingAge; pravděpodobně můžete zjistit, co se děje, bez konstanty, ale je to jednodušší s popisným názvem.

    Tito mohou také se stát kandidáty na abstrakci funkce, například function isLegalDrinkingAge(age) { return age >= 19 }. Jediná věc je, že vaše obchodní logika je často mnohem spletitější a že by nemělo smysl začít psát desítky funkcí s 20 až 30 parametry. Pokud neexistuje jasná abstrakce založená na objektech a/nebo funkcích, je uchycení ke konstantám v pořádku.

    Výzva je, že pokud pracujete pro daňové oddělení, stává se opravdu opravdu (---) náročným a upřímně zbytečným psát AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR). Nebudete to dělat, jdete na AttachForm("B-46"), protože každý vývojář, který kdy pracoval nebo kdy bude pracovat, bude vědět, že "B-46" je kód formuláře pro jediný daňový poplatník podávající bla bla bla - kódy formulářů jsou součástí samotné domény, nikdy se nemění, takže to nejsou opravdu magická čísla.

    Takže v obchodní logice musíte konstantně používat konstanty; v podstatě musíte pochopit, zda je „magické číslo“ vlastně magické číslo, nebo zda je to známý aspekt domény. Pokud je to doména, pak ji nezměkčíte, pokud není opravdu dobrá šance, že se změní.

  • Chybové kódy a stavové příznaky

    Tito jsou nikdy v pořádku tvrdě kódující, jak vám může říct každý chudý bastard, kterého kdy zasáhl Previous action failed due to error code 46. Pokud to váš jazyk podporuje, měli byste použít typ výčtu. V opačném případě budete mít obvykle celý soubor/modul plný konstant určující platné hodnoty pro konkrétní typ chyby.

    Nenechte mě nikdy vidět return 42 V obslužném programu pro chyby, capiche? Žádné výmluvy.

Asi jsem vynechal několik scénářů, ale myslím, že to pokrývá většinu z nich.

Takže ano, někdy je přijatelnou praxí dělat věci s pevným kódem. Prostě to nebuďte líní; mělo by to být vědomé rozhodnutí spíše než obyčejný starý nedbalý kód.

27
Aaronaught

Existuje několik důvodů pro přiřazení identifikátoru k číslu.

  • Pokud se číslo může změnit, mělo by mít identifikátor. Je mnohem snazší najít NUMBER_OF_PLANETS, než hledat každou instanci 9 a zvážit, zda by se mělo změnit na 8. (Všimněte si, že uživatelsky viditelné řetězce možná by se muselo změnit, pokud by měl být software někdy používán v jiném jazyce, a to je těžké předvídat předem.)
  • Pokud je číslo obtížné nějakým způsobem zadat. Pro konstanty, jako je pi, je lepší zadat jednu definici s maximální přesností, než ji přepsat na několika místech, případně nepřesně.
  • Pokud se číslo vyskytuje na různých místech. Neměli byste se dívat na dvě použití 45 v sousedních funkcích a ptát se, zda znamenají to samé.
  • Pokud význam není okamžitě rozpoznatelný. Je bezpečné předpokládat, že každý ví, co je 3.14159265 .... Není bezpečné předpokládat, že každý rozpozná gravitační konstantu nebo dokonce pí/2. ("Každý" zde záleží na povaze softwaru. Od systémových programátorů se dá očekávat, že budou znát osmičkové znázornění unixových povolení bitů apod. V softwaru námořní/mořské architektury zkontroluje Froudeovo číslo navrhovaného trupu a rychlost do podívejte se, jestli je to 1.1 nebo vyšší, může být zcela samozřejmým pro kohokoli, kdo by na tom měl pracovat.)
  • Pokud kontext není rozpoznatelný. Každý ví, že je 60 minut za hodinu, ale vynásobení nebo dělení 60 může být nejasné, pokud neexistují žádné bezprostřední náznaky, že množství je časová hodnota nebo hodnota kurzu .

To nám dává kritéria pro literály s pevným kódováním. Měly by být neměnné, neměly by se těžko psát, vyskytovaly se pouze na jednom místě nebo v kontextu a měly by mít rozpoznatelný význam. Nemá smysl definovat například 0 jako ARRAY_BEGINNING nebo 1 jako ARRAY_INCREMENT.

7
David Thornley

Jako doplněk k dalším odpovědím. Pokud je to možné, použijte pro řetězce řetězce konstanty. Samozřejmě nechcete mít

const string server_var="server_var";

ale měli byste

const string MySelectQuery="select * from mytable;";

(za předpokladu, že skutečně máte dotaz, kde chcete získat všechny výsledky z konkrétní tabulky, vždy)

Kromě toho použijte konstanty pro libovolné číslo jiné než 0 (obvykle). Pokud potřebujete bitovou masku oprávnění 255, nepoužívejte ji

const int 8th_bit=255; //or some other obscure naming scheme that equates to 255.

místo toho použijte

const int AllowGlobalRead=255;

Samozřejmě, spolu s konstantami, vědět, kdy používat enumerátory. Výše uvedený případ by do jednoho pravděpodobně zapadl.

5
Earlz

Je někdy dobré vložit hodnoty do našich aplikací?

Hodnoty pevného kódu pouze, pokud jsou hodnoty ve specifikaci specifikovány (v závěrečném vydání specifikace), např. Odpověď HTTP OK bude vždy 200 (pokud se to nezmění v RFC), takže uvidíte (v některých mých kódech) konstanty jako:

public static final int HTTP_OK = 200;

Jinak uložím konstanty do souboru vlastností.

Důvodem, proč jsem specifikoval specifikace, je to, že měnící se konstanty v specifikacích vyžadují řízení změn, ve kterém zúčastněné strany tuto změnu přezkoumají a schválí/neschválí. Nikdy se tak nestane přes noc a schválení trvá několik měsíců/let. Nezapomeňte, že mnoho vývojářů používá specifikace (např. HTTP), takže změna znamená rozbití milionů systémů.

4
Buhake Sindi

Záleží na tom, co považujete za hardcoding. Pokud se pokusíte vyhnout všem pevně zakódovaným věcem, skončíte na softcoding teritoriu a vytvoříte systém, který dokáže spravovat pouze tvůrce (a to je konečný pevný kód)

Spousta věcí je v jakémkoli rozumném rámci pevně zakódována a fungují. tj. neexistuje žádný technický důvod, proč bych neměl být schopen změnit vstupní bod aplikace C # (statická prázdnota Main), ale pevný kód, který pro žádného uživatele nevytváří žádné problémy (kromě občasných otázka SO) =)

Pravidlo, které používám, je, že cokoli, co se může a bude měnit, aniž by to ovlivnilo stav celého systému, by mělo být možné vyměnit.

Takže, IMHO, je hloupé nesmějí tvrdě kódovat věci, které se nikdy nemění (pi, gravitační konstanta, konstanta v matematickém vzorci - přemýšlejte o objemu koule).

Rovněž je hloupé nepatřit do věcí nebo procesů, které budou mít dopad na váš systém, což bude vyžadovat programování v každém případě, tj. Je zbytečné umožnit uživateli přidat dynamická pole do formuláře, pokud by jakékoli přidané pole vyžadovalo, aby vývojář údržby jít a napsat nějaký skript, který zajistí, aby tato věc fungovala. Je také hloupé (a viděl jsem to několikrát v podnikových prostředích) vytvořit nějaký konfigurační nástroj, takže nic není pevně zakódováno, přesto ho mohou použít pouze vývojáři v IT oddělení a je jen lehce snazší ho používat než to v aplikaci Visual Studio.

Sečteno podtrženo, zda má být věc pevně zakódována, je funkcí dvou proměnných:

  • změní se hodnota
  • jak ovlivní změna hodnoty systém
4
SWeko
  • pokud se hodnota může změnit a skutečně by se mohla změnit, pak ji kdykoli je to možné změňte, pokud vynaložené úsilí nepřesáhne očekávaný výnos
  • některé hodnoty nelze mohou být soft-kódovány; v těchto (vzácných) případech postupujte podle Jonathanových pokynů
3
Steven A. Lowe

Všiml jsem si, že kdykoli můžete extrahovat data z vašeho kódu, zlepšuje to, co zbývá. Začnete si všímat nových refaktorů a vylepšujete celé sekce kódu.

Je to jen dobrý nápad usilovat o extrakci konstant, nepovažujte to za nějaké hloupé pravidlo, přemýšlejte o tom jako o možnosti lépe kódovat.

Největší výhodou by byl způsob, jak byste mohli najít podobné konstanty jako jediný rozdíl ve skupinách kódu - jejich abstrahování do polí mi pomohlo snížit některé soubory o 90% jejich velikosti a mezitím opravit několik kopií a vložit chyby. .

Ještě jsem neviděl jedinou výhodu v tom, že nevytahoval data.

3
Bill K

Nedávno jsem kódoval funkci MySQL, abych správně vypočítal vzdálenost mezi dvěma páry lat/long. Nemůžete udělat jen pythagorus; čáry zeměpisné délky se přibližují, jak se zeměpisná šířka zvyšuje směrem k pólům, takže se jedná o nějaký chlupatý trig. Jde o to, že jsem byl docela roztrhaný, jestli tvrdě kódovat hodnotu představující poloměr Země v mílích.

Nakonec jsem to udělal, i když je pravda, že čáry lat/lng jsou mnohem blíže k sobě, řekněme, na Měsíci. A moje funkce by drasticky podhodnotila vzdálenosti mezi body na Jupiteru. Předpokládal jsem, že šance na tom, že buduji web s mimozemským umístěním, jsou docela štíhlé.

2
Dan Ray

Záleží na tom, zda je váš jazyk kompilován. Pokud není kompilován, není to velký problém, stačí upravit zdrojový kód, i když pro neprogramátora bude mírně křehký.

Pokud programujete se zkompilovaným jazykem, není to zjevně dobrý nápad, protože pokud se proměnné změní, musíte překompilovat, což je velká ztráta času, pokud chcete tuto proměnnou upravit.

Pro dynamické změny jeho proměnné nemusíte dělat nějaký posuvník nebo rozhraní, ale nejméně byste mohli udělat textový soubor.

Například u svého projektu ogre vždy používám třídu ConfigFile k načtení proměnné, kterou jsem zapsal do konfiguračního souboru.

1
jokoon

Ve dvou případech, kdy jsou konstanty (podle mého názoru) OK:

  1. Konstanty, které se netýkají nic jiného; tyto konstanty můžete kdykoli změnit, aniž byste museli měnit nic jiného. Příklad: Výchozí šířka sloupce mřížky.

  2. Absolutně neměnné, přesné, zřejmé konstanty, jako je „počet dní v týdnu“. days = weeks * 7 Nahrazuje 7 s konstantou DAYS_PER_WEEK téměř neposkytuje žádnou hodnotu.

1
user281377

Úplně souhlasím s Jonathanem, ale protože všechna pravidla existují výjimky ...

"Magické číslo ve specifikaci: Magické číslo v kódu"

V zásadě se uvádí, že jakákoli magická čísla, která zůstávají ve specifikaci po rozumných pokusech o jejich získání popisného kontextu, by se měla v kódu jako taková odrážet. Pokud v kódu zůstanou magická čísla, mělo by se vyvinout veškeré úsilí, aby byla izolována a jasně propojena s místem jejich původu.

Provedl jsem několik smluv o propojení, kde je třeba naplnit zprávy hodnotami mapovanými z databáze. Ve většině případů je mapování poměrně přímé a zapadá do Jonathanových obecných vodicích linií, ale narazil jsem na případy, kdy struktura cílové zprávy byla prostě hrozná. Více než 80% hodnot, které musely být předávány ve struktuře, byly konstanty vynucené specifikací vzdáleného systému. to ve spojení se skutečností, že struktura zprávy byla gargantuan, způsobila, že bylo třeba naplnit mnoho takových konstant. Ve většině případů neposkytly význam ani důvod, jen řekli „vložte M sem“ nebo „uveďte 4.10.53.10100.889450.4452“. Nepokusil jsem se ani vložit komentář ke všem z nich, protože by výsledný kód byl nečitelný. Ujistil jsem se však, že oddíly kódu, ve kterých se tyto magické hodnoty objevují, jsou řádně izolované a že jejich kontejnery (třídy, balíčky) jsou pojmenovány vhodně, aby odkazovaly přímo na specifikaci, která je vynucuje.

To znamená, že když o tom přemýšlíte ... je to skoro všechno o tom, aby bylo zřejmé ...

0
Newtopian

Pokud tvrdě zakódujete hodnotu zemské gravitační konstanty, nikdo se nebude starat. Pokud pevně zakódujete IP adresu vašeho proxy serveru, máte potíže.

0
jwenting

Většinou ne, ale myslím, že stojí za zmínku, že budete mít největší problémy, když začnete duplikovat pevně kódovanou hodnotu. Pokud jej nekopírujete (např. Použijte pouze jednou při implementaci třídy), pak nepoužívání konstanty může být v pořádku.

0
user22908