Programavimas

Apdorojamas komandinės eilutės argumentas „Java“: Byla baigta

Daugelis „Java“ programų, paleistų iš komandinės eilutės, priima argumentus, kad valdytų jų elgesį. Šie argumentai yra eilutės masyvo argumente, perduodamame į programos statiką pagrindinis () metodas. Paprastai yra dviejų tipų argumentai: parinktys (arba jungikliai) ir faktiniai duomenų argumentai. „Java“ programa turi apdoroti šiuos argumentus ir atlikti dvi pagrindines užduotis:

  1. Patikrinkite, ar naudojama sintaksė yra tinkama ir palaikoma
  2. Gaukite faktinius duomenis, reikalingus programai atlikti operacijas

Dažnai kodas, atliekantis šias užduotis, yra sukurtas kiekvienai programai pagal individualų užsakymą, todėl sukurti ir išlaikyti reikia didelių pastangų, ypač jei reikalavimai viršija paprastus atvejus, kai yra tik viena ar dvi parinktys. Galimybės šiame straipsnyje aprašyta klasė įgyvendina bendrą požiūrį, kad būtų galima lengvai įveikti sudėtingiausias situacijas. Klasė leidžia paprastai apibrėžti reikiamas parinktis ir duomenų argumentus, taip pat suteikia išsamų sintaksės patikrinimą ir lengvą prieigą prie šių patikrinimų rezultatų. Šiam projektui taip pat buvo naudojamos naujos „Java 5“ funkcijos, tokios kaip generiniai ir tipiniai seifai.

Komandinės eilutės argumentų tipai

Per daugelį metų aš parašiau keletą „Java“ įrankių, kurie, norėdami kontroliuoti savo elgesį, naudoja komandos argumentus. Anksti man pasirodė nemalonu rankiniu būdu sukurti ir prižiūrėti kodą įvairioms parinktims apdoroti. Tai paskatino sukurti prototipo klasę, kad būtų lengviau atlikti šią užduotį, tačiau ši klasė, be abejo, turėjo savo apribojimų, nes atidžiai patikrinus galimų skirtingų variantų skaičius komandinės eilutės argumentams pasirodė reikšmingas. Galų gale nusprendžiau sukurti bendrą šios problemos sprendimą.

Kurdamas šį sprendimą turėjau išspręsti dvi pagrindines problemas:

  1. Nurodykite visas atmainas, kuriose gali būti komandų eilutės parinkčių
  2. Raskite paprastą būdą, kaip leisti vartotojams išreikšti šias veisles, kai jie naudojasi dar nesukurta klase

Išanalizavus 1 problemą, buvo padaryta šios pastabos:

  • Komandų eilutės parinktys prieštarauja komandinės eilutės duomenų argumentams - pradėkite nuo priešdėlio, kuris juos unikaliai identifikuoja. Prefiksų pavyzdžiuose yra brūkšnys (-) „Unix“ platformose, pavyzdžiui, -a arba pasvirasis brūkšnys (/) „Windows“ platformose.
  • Parinktys gali būti paprasti jungikliai (t. Y. -a gali būti arba nėra) arba įgyti vertę. Pavyzdys:

    java „MyTool“ -a -b logfile.inp 
  • Vertę gaunančios parinktys gali skirtis nuo faktinio pasirinkimo rakto ir vertės. Tokie separatoriai gali būti tuščia vieta, dvitaškis (:) arba lygybės ženklą (=):

    java MyTool -a -b logfile.inp java MyTool -a -b: logfile.inp java MyTool -a -b = logfile.inp 
  • Vertę gaunantys variantai gali suteikti dar vieną sudėtingumo lygį. Apsvarstykite, kaip „Java“ palaiko aplinkos ypatybių apibrėžimą kaip pavyzdį:

    java -Djava.library.path = / usr / lib ... 
  • Taigi, be faktinio pasirinkimo klavišo (D), separatorius (=) ir faktinę pasirinkimo sandorio vertę (/ usr / lib), papildomas parametras (java.library.path) gali įgyti bet kokį skaičių verčių (aukščiau pateiktame pavyzdyje naudojant šią sintaksę galima nurodyti daugybę aplinkos ypatybių). Šiame straipsnyje šis parametras vadinamas „detale“.
  • Pasirinktys taip pat turi daugybės savybę: jie gali būti reikalingi arba neprivalomi, o jų leidžiamų kartų skaičius taip pat gali skirtis (pavyzdžiui, tiksliai vieną, vieną ar kelis kartus ar kitos galimybės).
  • Duomenų argumentai yra visi komandinės eilutės argumentai, prasidedantys ne priešdėliu. Čia priimtinas tokių duomenų argumentų skaičius gali skirtis nuo mažiausio iki didžiausio (kurie nebūtinai yra vienodi). Be to, paprastai programa reikalauja, kad šie duomenų argumentai būtų paskutiniai komandinėje eilutėje, tačiau taip turi būti ne visada. Pavyzdžiui:

    java MyTool -a -b = logfile.inp data1 data2 data3 // Visi duomenys pabaigoje 

    arba

    java „MyTool“ -a data1 data2 -b = logfile.inp data3 // Gali būti priimtina programai 
  • Sudėtingesnės programos gali palaikyti daugiau nei vieną parinkčių rinkinį:

    java MyTool -a -b datafile.inp java MyTool -k [-verbose] foo bar duh java MyTool -check -verify logfile.out 
  • Galiausiai, programa gali pasirinkti ignoruoti nežinomas parinktis arba laikyti tokias klaidomis.

Taigi, sugalvodamas būdą, kaip leisti vartotojams išreikšti visas šias veisles, aš sugalvojau šią bendrą variantų formą, kuri naudojama kaip šio straipsnio pagrindas:

[[]] 

Ši forma turi būti derinama su aukščiau aprašyta daugybės savybe.

Atsižvelgiant į pirmiau aprašytos galimybės bendros formos apribojimus, Galimybės Šiame straipsnyje aprašyta klasė sukurta kaip bendras sprendimas bet kokiems komandų eilutės apdorojimo poreikiams, kurių gali turėti „Java“ programa.

Pagalbininkų klasės

Galimybės klasė, kuri yra pagrindinė šiame straipsnyje aprašyto sprendimo klasė, turi dvi pagalbininkų klases:

  1. „OptionData“: Ši klasė talpina visą informaciją apie vieną konkretų variantą
  2. „OptionSet“: Ši klasė turi daugybę galimybių. Galimybės pati gali turėti bet kokį skaičių tokių rinkinių

Prieš aprašant šių klasių detales, pateikiamos kitos svarbios Galimybės klasė turi būti įvesta.

Tipasafe enums

Priešdėlį, atskyriklį ir ypatybę „daugybė“ užfiksavo „enums“, kurią pirmą kartą pateikė „Java 5“:

public enum priešdėlis {DASH ('-'), SLASH ('/'); privati ​​char; privatus priešdėlis (char c) {this.c = c; } char getName () {return c; }} public enum Separator {COLON (':'), EQUALS ('='), BLANK (''), NONE ('D'); privati ​​char; privatus separatorius (char c) {this.c = c; } char getName () {return c; }} public enum Daugybė {ONCE, ONCE_OR_MORE, ZERO_OR_ONE, ZERO_OR_MORE; } 

„Enums“ naudojimas turi keletą privalumų: padidintas tipo saugumas ir griežtas, be jokių pastangų kontroliuojamas leistinų verčių rinkinys. Enumus taip pat galima patogiai naudoti su sugeneruotomis kolekcijomis.

Atkreipkite dėmesį, kad Priešdėlis ir Separatorius enums turi savo konstruktorius, leidžiančius apibrėžti faktinį charakteris atstovaujantis šiai enum instancijai (palyginti su vardas naudojamas nurodant konkretų sąrašą). Šiuos simbolius galima gauti naudojant šias apžvalgas getName () metodai, o simboliai naudojami java.util.regex paketo modelio sintaksė. Šis paketas naudojamas atlikti kai kuriuos sintaksės patikrinimus Galimybės klasė, kurios duomenys bus pateikti vėliau.

Daugybė „enum“ šiuo metu palaiko keturias skirtingas vertybes:

  1. KARTĄ: Pasirinkimas turi atsirasti tiksliai vieną kartą
  2. ONCE_OR_MORE: Pasirinkimas turi būti bent kartą
  3. ZERO_OR_ONCE: Pasirinkimo gali nebūti arba jis gali būti pateiktas tiksliai vieną kartą
  4. ZERO_OR_MORE: Pasirinkimo gali nebūti arba jis gali būti rodomas tiek kartų

Jei reikia, galima lengvai pridėti daugiau apibrėžimų.

„OptionData“ klasė

„OptionData“ klasė iš esmės yra duomenų konteineris: pirma, duomenims, apibūdinantiems pačią parinktį, ir, antra, faktiniams duomenims, rastiems šios parinkties komandinėje eilutėje. Šis dizainas jau atsispindi konstruktoriuje:

„OptionData“ (Parinktys. Priešdėlio priešdėlis, Eilutės raktas, loginė informacija, Parinktys. Skyriklio separatorius, loginė vertė, Parinktys. Daugybinis daugybė) 

Raktas naudojamas kaip unikalus šios parinkties identifikatorius. Atkreipkite dėmesį, kad šie argumentai tiesiogiai atspindi anksčiau aprašytas išvadas: visame pasirinkimo aprašyme turi būti bent priešdėlis, raktas ir daugybė. Vertę gaunančios parinktys taip pat turi skyriklį ir gali priimti išsamią informaciją. Taip pat atkreipkite dėmesį, kad šis konstruktorius turi paketo prieigą, todėl programos negali jo tiesiogiai naudoti. Klasė „OptionSet“'s addOption () metodas prideda parinktis. Šis dizaino principas turi pranašumą, kad mes daug geriau kontroliuojame faktinius galimus argumentų derinius, naudojamus kuriant „OptionData“ atvejų. Pvz., Jei šis konstruktorius būtų viešas, galite sukurti egzempliorių, kurio išsami informacija nustatyta kaip tiesa ir nustatyta vertė melagingas, kas, žinoma, yra nesąmonė. Užuot atlikęs sudėtingus tikrinimus pačiame konstruktoriuje, nusprendžiau pateikti kontroliuojamą rinkinį addOption () metodai.

Konstruktorius taip pat sukuria java.util.regex.Pattern, kuris naudojamas šios parinkties modelių suderinimo procesui. Vienas iš pavyzdžių būtų parinkties modelis, kurio vertė, be išsamios informacijos ir tuščio skyriklio:

modelis = java.util.regex.Pattern.compile (priešdėlis.getName () + raktas + separator.getName () + "(. +) $"); 

„OptionData“ klasėje, kaip jau minėta, taip pat saugomi Galimybės klasė. Jame pateikiami šie viešieji metodai, kaip pasiekti šiuos rezultatus:

int getResultCount () eilutė getResultValue (int indeksas) eilutė getResultDetail (int indeksas) 

Pirmasis metodas, getResultCount (), pateikia skaičių, kiek kartų buvo rasta parinktis. Šis metodo dizainas tiesiogiai susijęs su pasirinktimi apibrėžtu daugybe. Pasirinkus vertę, šią vertę galima gauti naudojant getResultValue (int indeksas) metodas, kai indeksas gali svyruoti tarp 0 ir getResultCount () - 1. Vertės parinktims, kurios taip pat priima išsamią informaciją, jas galima panašiai pasiekti naudojant getResultDetail (int indeksas) metodas.

„OptionSet“ klasė

„OptionSet“ klasė iš esmės yra rinkinys „OptionData“ egzempliorius ir komandų eilutėje esančius duomenų argumentus.

Konstruktorius turi formą:

„OptionSet“ (Parinktys. Priešdėlio priešdėlis, Parinktys. Numatytasis daugialypiškumas. Daugialypiškumas, Styginių rinkinio pavadinimas, int minData, int maxData) 

Vėlgi, šis konstruktorius turi paketo prieigą. Parinkčių rinkinius galima sukurti tik naudojant Galimybės klasės skiriasi addSet () metodai. Pridedant parinktį prie rinkinio, galima pakeisti numatytąjį čia nurodytų parinkčių daugybę. Čia nurodytas rinkinio pavadinimas yra unikalus identifikatorius, naudojamas rinkiniui nurodyti. „minData“ ir „maxData“ yra mažiausias ir didžiausias priimtinų duomenų rinkinio argumentų skaičius šiam rinkiniui.

Viešoji API „OptionSet“ yra šie metodai:

Bendrieji prieigos būdai:

String getSetName () int getMinData () int getMaxData () 

Parinkčių pridėjimo būdai:

OptionSet addOption (String key) OptionSet addOption (String key, Multiplicity multiplicity) OptionSet addOption (String key, Separator separator) OptionSet addOption (String key, Separator separator, Multiplicity multiplicity) OptionSet addOption (String key, Boolean details, Separet separator) (Styginių klavišas, loginė informacija, separatoriaus skyriklis, daugybės daugybė) 

Patikros rezultatų duomenų prieigos metodai:

java.util.ArrayList getOptionData () OptionData getOption (String key) Boolean isSet (String key) java.util.ArrayList getData () java.util.ArrayList getUnmatched () 

Atkreipkite dėmesį, kad metodų, kaip pridėti parinktis, kurioms reikia a Separatorius argumentas sukurti „OptionData“ egzempliorius, priimantis vertę. addOption () metodai grąžina patį nustatytą egzempliorių, kuris leidžia sukviesti grandines:

Parinkčių parinktys = new Parinktys (argumentai); options.addSet ("MySet"). addOption ("a"). addOption ("b"); 

Atlikus patikrinimus, jų rezultatus galima rasti likusiais metodais. getOptionData () pateikia visų sąrašą „OptionData“ atvejų „getOption“ () leidžia tiesiogiai pasiekti konkrečią parinktį. isSet (eilutės raktas) yra patogumo metodas, kuris patikrina, ar parinktys buvo bent kartą rastos komandinėje eilutėje. „getData“ () suteikia prieigą prie rastų duomenų argumentų, o getUnmatched () pateikia visas komandų eilutėje esančias parinktis, kurių neatitinka „OptionData“ atvejų buvo rasta.

„Options“ klasė

Galimybės yra pagrindinė klasė, su kuria programos sąveikaus. Jis pateikia kelis konstruktorius, kurie visi naudoja komandinės eilutės argumentų eilutės masyvą, kurį pagrindinis () metodas pateikia pirmąjį argumentą:

Parinktys (String args []) Parinktys (String args [], int duomenys) Parinktys (String args [], int defMinData, int defMaxData) Parinktys (String args [], Multiplicity defaultMultiplicity) Parinktys (String args [], Multiplicity defaultMultiplicity, int duomenys) Parinktys (String args [], Multiplicity defaultMultiplicity, int defMinData, int defMaxData) Parinktys (String args [], Prefix prefix) Parinktys (String args [], Prefix prefix, int data) Options (String args [], Prefix prefiksas, int defMinData, int defMaxData) Parinktys (String args [], Prefix prefix, Multiplicity defaultMultiplicity) Options (String args [], Prefix prefix, Multiplicity defaultMultiplicity, int data) Options (String args [], Prefix prefix, Multiplicity defaultMultiplicity, int defMinData, int defMaxData) 

Pirmasis konstruktorius šiame sąraše yra paprasčiausias, naudojant visas numatytąsias reikšmes, o paskutinis - bendriausias.

1 lentelė: „Options“ () konstruktorių argumentai ir jų reikšmė

Vertė apibūdinimas Numatytas
priešdėlisŠis konstruktoriaus argumentas yra vienintelė vieta, kur galima nurodyti priešdėlį. Ši vertė perduodama bet kuriam pasirinkimo rinkiniui ir bet kuriai vėliau sukurtai parinkčiai. Šio požiūrio idėja yra ta, kad tam tikroje programoje mažai tikėtina, kad reikės naudoti skirtingus priešdėlius.Priešdėlis.DASH
numatytasis DaugybinisŠis numatytasis daugybė perduodama kiekvienam parinkčių rinkiniui ir naudojama kaip numatytoji parinktims, pridėtoms prie rinkinio, nenurodant daugybės. Žinoma, šį daugybę galima nepaisyti kiekvienos pridėtos parinkties atveju.Daugybė.KARTĄ
defMinDatadefMinData yra numatytasis mažiausias palaikomų duomenų argumentų, perduotų kiekvienam parinkčių rinkiniui, skaičius, tačiau, žinoma, jį galima nepaisyti pridedant rinkinį.0
defMaxDatadefMaxData yra numatytasis maksimalus palaikomų duomenų argumentų, perduotų kiekvienam parinkčių rinkiniui, skaičius, tačiau, žinoma, jį galima nepaisyti pridedant rinkinį.0
$config[zx-auto] not found$config[zx-overlay] not found