Érdemes valaha is hardveresen kódolni az értékeket az alkalmazásainkba? Vagy mindig helyes, ha dinamikusan hívjuk az ilyen típusú értékeket, ha változtatni kell?
Megjegyzések
Válasz
Igen, de tegye ezt nyilvánvaló .
Csináljon:
- használjon konstansokat
- használjon leíró változó neve
Ne használja:
- bármilyen varázsszámot lebeg a kód körül
Megjegyzések
- Melyik tisztább,
diameter = 2 * radius
vagydiameter = RADIUS_TO_DIAMETER_FACTOR * radius
? Valóban vannak olyan sarok esetek, amikor a mágikus szám jobb megoldás lehet. - Nem tudok ‘ egyetérteni ez a válasz elég. Hajlamos vagyok olyan programozásra gondolni, mint regényírónak lenni. A kódodon keresztül meséled el a történetedet, és ha az emberek nem értik a logikát, az véleményem szerint értéktelenné teszi a kódodat. Ez > s miért a jól átgondolt elnevezési szokások lényegében az olvashatóságot szolgálják. Emellett nincs jó ok a mágikus számok használatára. A mágikus számok használatával eltávolítja a 51c9003c17 “>
az egyenletből, és megnehezíti az alávetéseket tand. Például: ” átmérő = 2 * sugár ” Mire szolgál a kettő? Ez az ” átmérő = RADIUS_TO_DIAMETER_FACTOR * sugár ” sokkal értelmesebb.
diameter = radius << 1
? Feltételezem, hogy ez diameter = radius << RADIUS_TO_DIAMETER_BITS_TO_SHIFT
is lehet. Válasz
Amit furcsának találok ebben a Q & A eddig az, hogy senki sem próbálta meg egyértelműen meghatározni a “hard-kódot”, vagy ami még fontosabb, az alternatívákat.
tl; dr : Igen, néha jó az értékek kemény kódolása, de nincs egyszerű szabály arra, hogy mikor ; ez teljesen a kontextustól függ.
A kérdés leszűkíti értékekre , amelyek szerintem varázsszámokat értek , de a válasz arra, hogy “jó ötlet-e vagy sem, ahhoz képest, hogy mire használják valójában!
Több példa a” keményen kódolt ” “az értékek:
-
Konfigurációs értékek
Megráncolok, amikor nyilatkozatokat látok mint
command.Timeout = 600
. Miért 600? Ki döntött így? Korábban volt időzítés, és valaki az időkorlátot hackként emelte fel az alapul szolgáló teljesítményprobléma kijavítása helyett? Vagy valójában valamilyen ismert és dokumentált elvárás a feldolgozási idővel kapcsolatban?Ezeknek nem lehetnek mágikus számok vagy konstansok, hanem egy konfigurációs fájlban vagy adatbázisban kell őket kívülre vinni valahol egy értelmes név, mert optimális értéküket nagyrészt vagy teljes egészében az a környezet határozza meg, amelyben az alkalmazás fut.
-
Matematikai képletek
A képletek általában elég statikusak, így a belső állandó értékek jellege nem igazán fontos. A piramis térfogata (1/3) b * h. Nem érdekel, honnan jött az 1 vagy 3? Nem igazán. Egy korábbi hozzászóló helyesen mutatott rá arra, hogy a
diameter = radius * 2
valószínűleg jobb, mint adiameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR
– de ez hamis kettősség.Mit kell tennie az ilyen típusú forgatókönyvek esetében, létrehoz egy függvény t. Nem kell tudnom, hogy hogyan találtad ki a képletet, de még mindig tudnom kell, hogy mire való . Ha a fent írt hülyeségek helyett a következőt írom:
volume = GetVolumeOfPyramid(base, height)
, akkor hirtelen minden sokkal világosabbá válik, és teljesen rendben van, ha mágikus számok vannak bent a függvény (return base * height / 3
), mert nyilvánvaló, hogy csak a képlet részét képezik.A kulcs itt természetesen az, hogy rövid és egyszerű függvények. Ez nem működik 10 argumentummal és 30 soros számítással rendelkező függvényeknél. Ebben az esetben használjon függvényösszetételt vagy konstansokat.
-
Domain / üzleti szabályok
Ez mindig a szürke terület, mert attól függ, hogy pontosan mi az érték. Az esetek többségében ezek a varázslatos számok jelennek meg az állandókká történő átalakításban, mert ez megkönnyíti a program megértését anélkül, hogy megnehezítené a program logikáját. Tekintsük a vs.
if Age < LegalDrinkingAge
; valószínűleg megtudhatja , hogy mi folyik az állandó nélkül, de a leíróval könnyebb cím.Ezek szintén jelöltekké válhatnak a funkciók absztrakciójához, például
function isLegalDrinkingAge(age) { return age >= 19 }
. Az egyetlen dolog az, hogy gyakran az üzleti logikája ennél sokkal tekervényesebb, és lehet, hogy nincs értelme függvények tucatjainak kiírását kezdeni, mindegyik 20-30 paraméterrel. Ha objektumok és / vagy függvények alapján nincs tiszta absztrakció, akkor az állandók igénybevétele rendben van.A figyelmeztetés az, hogy ha az adóügyi osztálynál dolgozik, akkor valóban nagyon megterhelő és őszintén értelmetlen lesz
AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR)
megírása. Nem fogsz ilyet csinálni t, akkor megyAttachForm("B-46")
, mert minden egyes fejlesztő, aki valaha dolgozott vagy dolgozni fog ott, tudni fogja, hogy a “B-46” az egyetlen adózó űrlapkódja iktatás bla bla bla – az űrlapkódok maguk a domain részét képezik, soha nem változnak, ezért nem igazán varázslatos számok.Tehát az üzleti logikában takarékosan kell használnia az állandókat; alapvetően meg kell értenie, hogy ez a “mágikus szám” valójában mágikus szám-e, vagy nem a domain jól ismert aspektusa. Ha ez a domain, akkor nem szabad soft-kódolni, hacsak nincs “sa” nagyon jó eséllyel megváltozik.
-
Hibakódok és állapotjelzők
Ezeket soha nem szabad a hardveres kódoláshoz használni, ahogyan azt minden szegény gazember elmondhatja neked, akit valaha is eltaláltak a
Previous action failed due to error code 46
vel. Ha az Ön nyelve támogatja, akkor felsorolási típust kell használnia. Ellenkező esetben általában egy teljes fájl / modul áll konstansokkal, amelyek megadják az adott hibatípus érvényes értékeit.Soha ne engedje, hogy lássam
return 42
hibakezelőben, capiche? Nincs mentség.
Valószínűleg több forgatókönyvet is kihagytam, de úgy gondolom, hogy ezek többségét lefedi.
Tehát, igen, ez néha elfogadható gyakorlat kemény kóddal. Csak ne lusta! tudatos döntésnek kell lennie, nem pedig egyszerű régi hanyag kódnak.
Megjegyzések
- Köszönöm a jó bontást! – a legtöbb ember nem gondolja át az összes lehetőséget, amelyet hozzáadnék ” Környezet konfigurálása ” – úgy gondolom, hogy ezeket kerülni kell (nem kemény kódolással), mivel a legtöbb adatot egy konfigurációs fájlba vagy adatbázisba kell tenni. Ez követi az ” elv és az adatok és a logika elkülönítésének ” elvét, amely az MVC vagy az MVVM alappillére. string TestServerVar = ” foo “; karakterlánc ProdServerVal = ” sáv “;
válasz
Különféle okok vannak az azonosító hozzárendeléséhez egy számhoz.
- Ha a szám változhat, azonosítóval kell rendelkeznie. Sokkal könnyebb megtalálni a NUMBER_OF_PLANETS-t, mint megkeresni minden 9-es példányt, és megfontolni, hogy kell-e módosítani 8-ra. (Vegye figyelembe, hogy a felhasználó számára látható a karakterláncoknak meg kell változniuk, ha a szoftvert valaha más nyelven kell használni, és ezt “nehéz előre megjósolni.”
- Ha a számot bármilyen módon nehéz begépelni. Az olyan konstansokhoz, mint a pi, jobb, ha egy maximális pontosságú definíciót adunk meg, mint több helyre, esetleg pontatlanul. / li>
- Ha a szám különböző helyeken fordul elő. Nem kell megvizsgálnia a 45-ös két felhasználását a szomszédos függvényekben, és azon gondolkodni, vajon ugyanazt jelentik-e. >
Ha a jelentés nem “azonnal felismerhető. Biztonságos feltételezni, hogy mindenki tudja, mi a 3.14159265 … mindenki felismeri a gravitációs állandót, vagy akár a pi / 2-t. (A “mindenki” itt a szoftver jellegétől függ. A rendszerek programozóitól elvárható, hogy ismerjék a Unix engedélybitek vagy hasonló oktaális ábrázolását. A haditengerészeti / tengeri építészeti szoftverekben ellenőrizze a javasolt hajótest Froude számát és sebességét hátha annak 1.1-es vagy újabb verziója tökéletesen magától értetődő lehet bárkinek, akinek dolgoznia kellene rajta.)
Ez megadja nekünk a szigorúan kódoló literálok kritériumait. Ezeknek változhatatlannak kell lenniük, nem nehéz őket begépelni, csak egy helyen vagy kontextusban fordulnak elő, és felismerhető jelentéssel bírnak. Nincs értelme. például a 0 ARRAY_BEGINNING vagy az 1 ARRAY_INCREMENT meghatározásakor.
Válasz
Más válaszok kiegészítéseként. Ha lehetséges, használjon konstansokat a karakterláncokhoz. Természetesen nem akarja, hogy
const string server_var="server_var";
legyen, de
const string MySelectQuery="select * from mytable;";
(feltételezve, hogy valóban van egy lekérdezése, ahová mindig egy adott táblázat összes eredményét be akarja szerezni)
Ettől eltekintve használjon konstansokat a 0-tól eltérő számokhoz (általában). Ha szükséges 255-ös engedély bitmaszk, ne használja
const int 8th_bit=255; //or some other obscure naming scheme that equates to 255.
ehelyett használja
const int AllowGlobalRead=255;
Természetesen az állandókkal együtt tudja, mikor kell használni a felsorolókat. A fenti eset valószínűleg jól illene egybe.
Megjegyzések
- typedef enum {state_0 = 0, state_1 = 1, state_2 = 2, .. .} … Ne ‘ ne nevessen, láttam ‘. Csapja be a fejét nedves halakkal!
- @gyorsan, természetesen ‘ szeretne még valami hasonlót:
typedef enum {init_state=0, parse_state=1, evaluation_state=2, ... }
- THIS_NAMING_CONVENTION_IS_RECOMMENDED_FOR_CONSTANTS
- Karakterláncokhoz nem ‘ nem csak konstansokat akar. A felhasználó számára látható karakterláncokat valamilyen erőforrásfájlba szeretné helyezni (a részletek a platformjától függenek), így könnyen átválthat más nyelvre.
- Érdemes ragasztania az üzleti logikával kapcsolatosakat is karakterláncok (például SQL lekérdezések) egy erőforrás fájlban, valamilyen titkosítással vagy elfedéssel. Ez megakadályozza a ” kíváncsi ” felhasználókat abban, hogy a logikádat (vagy az adatbázis-sémát) visszafejelezzék.
Válasz
Attól függ, hogy mit tart hardkódolásnak. Ha megpróbál elkerülni minden keményen kódolt dolgot, akkor softkódolás területre kerül, és létrehoz egy rendszert, amelyet csak az alkotó kezelhet (és ez a végső hardverkód)
Rengeteg dolgot hardkódolnak bármilyen ésszerű keretrendszerben, és működnek. Vagyis nincs technikai oka annak, hogy ne tudjam megváltoztatni egy C # alkalmazás belépési pontját (static void Main ), de kemény kódolás, amely nem okoz problémát egyetlen felhasználó számára sem (kivéve az alkalmi SO kérdést )
Az általam használt ökölszabály hogy bármi, ami megváltoztatható és változni fog, anélkül, hogy befolyásolná az egész rendszer állapotát, konfigurálhatónak kell lennie. állandó egy matematikai képletben – gondolj egy gömb térfogatára).
Az is butaság, ha nem kódolsz olyan dolgokat vagy folyamatokat, amelyek hatással lesznek a rendszeredre, és amelyek bármilyen esetben programozást igényelnek, .e. pazarló lehetõvé teszi a felhasználó számára, hogy dinamikus mezõket adjon hozzá egy űrlaphoz, ha bármelyik hozzáadott mező megköveteli, hogy a karbantartás fejlesztője belépjen, és írjon néhány szkriptet, amely működni fogja ezt a dolgot. Szintén hülyeség (és már láttam néhányszor vállalati környezetben) valamilyen konfigurációs eszközt létrehozni, tehát semmi nincs hardcode-ban, mégis csak az informatikai részleg fejlesztői használhatják, és csak könnyebben használni, mint a Visual Studio-ban.
Tehát, az a lényeg, hogy egy dolgot kemény kódolni kell-e, két változó függvénye:
- megváltozik-e az érték
- hogyan befolyásolja az érték változása a rendszert?
Válasz
Érdemes valaha is hardveresen kódolni az értékeket az alkalmazásainkba?
I hardcode értékek csak ha az értékek meg vannak adva a Specifikációban (a specifikáció végleges kiadásakor), pl. A HTTP OK válasz mindig 200
lesz (hacsak nem változik az RFC-ben), tehát (néhány kódomban) olyan konstansokat fog látni, mint:
public static final int HTTP_OK = 200;
Ellenkező esetben konstansokat tárolok a tulajdonságfájlban.
Azért adtam meg a specifikációkat, hogy a specifikációkban szereplő konstansok megváltoztatásához változáskezelésre van szükség, amelyben a az érdekelt felek felülvizsgálják a változást és jóváhagyják / elutasítják. Ez soha nem történik egyik napról a másikra, és hónapokig / évig tart a jóváhagyás. Ne felejtsük el, hogy sok fejlesztő specifikációkat (pl. HTTP) használ, ezért annak megváltoztatása a rendszerek millióinak megszakítását jelenti.
Válasz
- ha az érték megváltozhat, sőt változhat, akkor lehetőség szerint kódolja, amíg az ezzel járó erőfeszítés nem haladja meg a várt megtérülést
- egyes értékeket nem lehet soft-kódolt; kövesse Jonathan útmutatásait ezekben a (ritka) esetekben
Válasz
Észrevettem hogy bármikor kivonhat adatokat a kódjából, javítja a maradékot. Kezd észrevenni új átalakításokat és javítani a kód teljes szakaszait.
Csak jó ötlet az állandók kinyerése érdekében dolgozni, ne tekintsd hülye szabálynak, gondolj rá a kódolás lehetőségére jobb.
A legnagyobb előny az lenne, ha hasonló állandókat találna az egyetlen különbség a kódcsoportokban – tömbökké válásuk segített abban, hogy egyes fájlokat a méretük 90% -ával csökkentsem, és a javításuk időközben néhány másolat & hibákat beilleszt.
Még nem láttam egyetlen előnyt az adatok kibontásának hiányában.
Válasz
Nemrég kódoltam egy MySQL függvényt, hogy megfelelően kiszámítsam a két lat / hosszú pár közötti távolságot. Nem lehet csak pitagorust csinálni; a hosszúsági vonalak egyre közelebb kerülnek egymáshoz, amikor a szélesség a pólusok felé növekszik, ezért valamiféle szőrös triggellel jár. A lényeg az, hogy eléggé elszakadtam attól, hogy a föld sugarát reprezentáló értéket mérföldben kell-e keményen kódolni.
Végül megcsináltam, pedig tény, hogy a lat / lng vonalak sokkal közelebb vannak egymáshoz, mondjuk a holdon. És a funkcióm drasztikusan alulírja a Jupiter pontjai közötti távolságokat. Úgy gondoltam, hogy a földön kívüli helyet megépítő webhely esélyei meglehetősen csekélyek.
Megjegyzések
- Igen, valószínűleg, de mi van a google.com/hoon
válasz
Nos, ez attól függ, hogy fordítják-e a nyelvet. Ha nem fordítják le, akkor nem nagy probléma, csak szerkeszti a forráskódot, még akkor is, ha egy nem programozó számára kissé kényes lesz.
Ha lefordított nyelvvel programozol, akkor ez egyértelműen nem jó ötlet, mert ha a változók megváltoznak, újra össze kell fordítanod, ami nagy időpazarlás, ha módosítani akarod ezt a változót.
A változó dinamikus megváltoztatásához nem kell valami csúszkát vagy felületet létrehozni, de a legkevesebb, amit tehetne, egy szöveges fájl.
Például az ogre projektemnél mindig használom a ConfigFile osztály az általam írt változó betöltésére egy config fájlba.
Válasz
Két olyan eset, amikor az állandók (legalábbis véleményem szerint) rendben vannak:
-
Semmi máshoz nem kapcsolódó konstansok; bármikor megváltoztathatja ezeket az állandókat anélkül, hogy bármi mást kellene megváltoztatnia. Példa: A rács oszlopának alapértelmezett szélessége.
-
Teljesen megváltoztathatatlan, pontos, nyilvánvaló konstansok, például “heti napok száma”.
days = weeks * 7
A7
konstansDAYS_PER_WEEK
cseréje alig ad értéket.
Válasz
Teljesen egyetértek Jonathannel, de mivel minden szabálynál vannak kivételek …
“Mágikus szám a specifikációban: Mágikus szám a”
kódban minden olyan mágikus szám, amely megmarad a specifikációban, miután ésszerű kísérleteket tettek arra, hogy leíró kontextust kapjon számukra, önmagában tükröződnie kell a kódban. Ha a mágikus számok megmaradnak a kódban, minden erőfeszítést meg kell tenni annak elkülönítésére és egyértelmű összekapcsolására a származási helyükhöz.
Végeztem néhány összekapcsolódó szerződést, ahol az üzeneteket feltérképezett értékekkel kell feltölteni. az adatbázisból. A legtöbb esetben a leképezés meglehetősen egyenes és előre illeszkedik Jonathan általános útmutatásaihoz, de találkoztam olyan esetekkel, amikor a célüzenet szerkezete egyszerűen borzasztó volt.A struktúrában átadandó értékek több mint 80% -a konstans, amelyet a távoli rendszer specifikációja kényszerített ki. ez azzal a ténnyel párosulva, hogy az üzenetszerkezet óriási, azt eredményezte, hogy SOK ilyen állandót kell benépesíteni. A legtöbb esetben nem adtak jelentést vagy okot, csak annyit mondtak, hogy “tedd ide M” vagy “tedd ide 4.10.53.10100.889450.4452”. Meg sem próbáltam megjegyzést tenni mindegyik mellé, ez olvashatatlanná tette volna a kapott kódot. Gondoskodtam azonban arról, hogy a kód részek, ahol ezek a varázsértékek megjelennek, megfelelően el vannak különítve, és hogy a tárolóik (osztályok, csomagok) megfelelően vannak elnevezve, hogy közvetlenül az őket érvényesítő specifikációra mutassanak. ez … nagyjából annyit tesz, hogy nyilvánvalóvá …
Válasz
Ha “újra kódolja a föld gravitációs állandójának értékét, senki sem fog érdekelni. Ha hardveresen kódolja a proxykiszolgáló IP-címét, bajba kerülhet.
Megjegyzések
- Nagyobb pontosságra lehet szüksége a earth ‘ s gravitációs állandója, így annak többszöri átkódolása problémákat okozhat.
- Peter Noone? Hermannól ‘ s Remetek ?
- A gravitációs gyorsulás a Földön nagyjából 9,81 m / s ^ 2 a legtöbb szélességi fokon és magasságon (természetesen ha ‘ olajat keres földalatti, vagy az Északi-sark felett lövöldöző ICBM-eket, a gravitáció változásának ismerete sokkal több tizedesjegyig nagyon fontos), más bolygókon a gravitációs gyorsulás más számú, de ha jól tudom, a gravitációs állandó állandó az univerzum körül. Nagyon sok olyan fizika van, amelynek meg kellene változnia, ha g változó lenne.
Válasz
Többnyire nem, de szerintem érdemes megjegyezni, hogy ti Akkor lesz a legtöbb probléma, amikor elkezdi másolni a keményen kódolt értéket. Ha nem másolja (pl. Csak egyszer használja egy osztály megvalósításakor), akkor a konstans használata nem megfelelő.
pi
értéke mikor változhat …