Daudzas Java lietojumprogrammas, kas sāktas no komandrindas, prasa argumentus, lai kontrolētu viņu uzvedību. Šie argumenti ir pieejami virknes masīva argumentā, kas tiek ievadīts lietojumprogrammas statikā galvenais ()
metodi. Parasti ir divu veidu argumenti: opcijas (vai slēdži) un faktisko datu argumenti. Java lietojumprogrammai ir jāapstrādā šie argumenti un jāveic divi pamatuzdevumi:
- Pārbaudiet, vai izmantotā sintakse ir derīga un atbalstīta
- Iegūstiet faktiskos datus, kas nepieciešami lietojumprogrammas darbību veikšanai
Bieži vien kods, kas veic šos uzdevumus, tiek pielāgots katrai lietojumprogrammai, un tāpēc tā izveide un uzturēšana prasa ievērojamas pūles, it īpaši, ja prasības pārsniedz vienkāršus gadījumus tikai ar vienu vai divām iespējām. The Iespējas
Šajā rakstā aprakstītā klase īsteno vispārēju pieeju, lai viegli tiktu galā ar vissarežģītākajām situācijām. Klase ļauj vienkārši definēt nepieciešamās opcijas un datu argumentus, kā arī nodrošina rūpīgas sintakses pārbaudes un ērtu piekļuvi šo pārbaužu rezultātiem. Šajā projektā tika izmantotas arī jaunas Java 5 funkcijas, piemēram, ģenerikas un tipogrāfijas.
Komandrindas argumentu veidi
Gadu gaitā esmu uzrakstījis vairākus Java rīkus, kas izmanto komandrindas argumentus, lai kontrolētu viņu uzvedību. Sākumā es uzskatu, ka ir nepatīkami manuāli izveidot un uzturēt kodu dažādu iespēju apstrādei. Tas noveda pie prototipa klases izstrādes, lai atvieglotu šo uzdevumu, taču šai klasei, protams, bija ierobežojumi, jo, rūpīgi pārbaudot, iespējamo dažādu variantu skaits komandrindas argumentiem izrādījās ievērojams. Galu galā es nolēmu izstrādāt vispārēju šīs problēmas risinājumu.
Izstrādājot šo risinājumu, man bija jāatrisina divas galvenās problēmas:
- Norādiet visas šķirnes, kurās var parādīties komandrindas opcijas
- Atrodiet vienkāršu veidu, kā ļaut lietotājiem izteikt šīs šķirnes, izmantojot vēl izstrādājamo klasi
Analizējot 1. problēmu, tika iegūti šādi novērojumi:
- Komandrindas opcijas pretēji komandrindas datu argumentiem - sāciet ar prefiksu, kas tos unikāli identificē. Prefiksu piemēri ietver domuzīmi (
-
) Unix platformās tādām opcijām kā-a
vai slīpsvītru (/
) Windows platformās. Opcijas var būt vai nu vienkārši slēdži (t.i.,
-a
var būt klāt vai nē) vai ņemt vērtību. Piemērs ir:java MyTool -a -b logfile.inp
Opcijām, kas ņem vērtību, faktiskajam izvēles taustiņam un vērtībai var būt dažādi atdalītāji. Šādi atdalītāji var būt tukša vieta, kols (
:
) vai vienādības zīme (=
):java MyTool -a -b logfile.inp java MyTool -a -b: logfile.inp java MyTool -a -b = logfile.inp
Opcijas, kurām ir vērtība, var pievienot vēl vienu sarežģītības pakāpi. Apsveriet, kā Java atbalsta vides īpašību definīciju kā piemēru:
java -Djava.library.path = / usr / lib ...
- Tātad, ārpus faktiskās opcijas taustiņa (
D
), atdalītājs (=
) un opcijas faktiskā vērtība (/ usr / lib
), papildu parametrs (java.library.path
) var iegūt jebkuru vērtību skaitu (iepriekš minētajā piemērā, izmantojot šo sintaksi, var norādīt daudzas vides īpašības). Šajā rakstā šo parametru sauc par "detaļu". - Opcijām ir arī daudzkārtības īpašība: tās var būt obligātas vai neobligātas, un atļauto reižu skaits var arī atšķirties (piemēram, tieši vienu, vienu vai vairākas reizes vai citas iespējas).
Datu argumenti ir visi komandrindas argumenti, kas nesākas ar prefiksu. Šeit pieņemamais šādu datu argumentu skaits var atšķirties starp minimālo un maksimālo skaitu (kas ne vienmēr ir vienādi). Turklāt parasti lietojumprogramma prasa, lai šie datu argumenti komandrindā būtu pēdējie, taču tam ne vienmēr jābūt. Piemēram:
java MyTool -a -b = logfile.inp data1 data2 data3 // Visi dati beigās
vai
java MyTool -a data1 data2 -b = logfile.inp data3 // Var būt lietojumprogrammai pieņemams
Sarežģītākas lietojumprogrammas var atbalstīt vairākas opciju kopas:
java MyTool -a -b datafile.inp java MyTool -k [-verbose] foo bar duh java MyTool -check -verify logfile.out
- Visbeidzot, lietojumprogramma var izvēlēties ignorēt nezināmas opcijas vai uzskatīt šādas iespējas par kļūdām.
Tātad, izstrādājot veidu, kā ļaut lietotājiem izteikt visas šīs šķirnes, es nāca klajā ar šādu vispārīgo iespēju veidlapu, kas tiek izmantota kā pamats šim rakstam:
[[]]
Šī forma jāapvieno ar daudzkārtības īpašību, kā aprakstīts iepriekš.
Ievērojot iepriekš aprakstītās iespējas vispārīgās formas ierobežojumus, Iespējas
Šajā rakstā aprakstītā klase ir izstrādāta kā vispārējs risinājums visām komandrindas apstrādes vajadzībām, kas varētu būt Java lietojumprogrammai.
Palīgu klases
The Iespējas
klase, kas ir šajā rakstā aprakstītā risinājuma galvenā klase, ir aprīkota ar divām palīgu klasēm:
OptionData
: Šajā klasē ir visa informācija par vienu konkrētu iespējuOptionSet
: Šajā klasē ir vairākas iespējas.Iespējas
pati var turēt jebkuru šādu kopu skaitu
Pirms aprakstīt sīkāku informāciju par šīm nodarbībām, jāņem vērā arī citi svarīgi Iespējas
klase jāievieš.
Typesafe enums
Prefiksu, atdalītāju un īpašību daudzkārtība ir uztvērusi enums, šo funkciju pirmo reizi nodrošina Java 5:
public enum prefikss {DASH ('-'), SLASH ('/'); privāta char; privāts prefikss (char c) {this.c = c; } char getName () {return c; }} public enum Separator {COLON (':'), EQUALS ('='), BLANK (''), NONE ('D'); privāta char; privātais atdalītājs (char c) {this.c = c; } char getName () {return c; }} public enum Daudzkārtīgums {ONCE, ONCE_OR_MORE, ZERO_OR_ONE, ZERO_OR_MORE; }
Enumu lietošanai ir dažas priekšrocības: paaugstināta tipa drošība un stingra, bez piepūles kontrolējama pieļaujamo vērtību kopa. Enumus var ērti izmantot arī ar ģenerētām kolekcijām.
Ņemiet vērā, ka Priedēklis
un Atdalītājs
enumiem ir savi konstruktori, ļaujot definēt faktisko raksturs kas pārstāv šo uzskaites gadījumu (pret nosaukums lieto, lai atsauktos uz konkrēto uzskaites gadījumu). Šīs rakstzīmes var iegūt, izmantojot šos enums ' getName ()
metodes, un rakstzīmes tiek izmantotas java.util.regex
paketes raksta sintakse. Šo pakotni izmanto, lai veiktu dažas sintakses pārbaudes Iespējas
klase, kuras detaļas sekos.
The Daudzveidība
enum šobrīd atbalsta četras dažādas vērtības:
VIENREIZ
: Opcijai ir jānotiek tieši vienu reiziONCE_OR_MORE
: Opcijai ir jānotiek vismaz vienu reiziZERO_OR_ONCE
: Iespējas var būt vai nu nav, vai arī tā ir pieejama tieši vienu reiziZERO_OR_MORE
: Opcija var nebūt vai arī tā var būt redzama tik reižu, cik reižu
Ja rodas vajadzība, var viegli pievienot vairāk definīciju.
OptionData klase
The OptionData
klase būtībā ir datu konteiners: pirmkārt, datiem, kas apraksta pašu opciju, un, otrkārt, faktiskajiem datiem, kas atrodami šīs opcijas komandrindā. Šis dizains jau ir atspoguļots konstruktorā:
OptionData (Opcijas. Prefiksa prefikss, virknes atslēga, Būla informācija, Opcijas. Atdalītāja atdalītājs, Būla vērtība, Opcijas. Daudzkārtības daudzkārtība)
Atslēga tiek izmantota kā šīs opcijas unikālais identifikators. Ņemiet vērā, ka šie argumenti tieši atspoguļo iepriekš aprakstītos secinājumus: pilnā opcijas aprakstā jābūt vismaz prefiksam, atslēgai un daudzveidībai. Opcijām, kurās ņemta vērtība, ir atdalītājs, un tās var pieņemt detalizētu informāciju. Ņemiet vērā arī to, ka šim konstruktoram ir piekļuve pakotnei, tāpēc lietojumprogrammas to nevar tieši izmantot. Klase OptionSet
's addOption ()
metode pievieno opcijas. Šim dizaina principam ir tā priekšrocība, ka mēs daudz labāk kontrolējam faktiskās iespējamās argumentu kombinācijas, kas tiek izmantotas, lai izveidotu OptionData
gadījumi. Piemēram, ja šis konstruktors būtu publisks, jūs varētu izveidot instanci ar detalizētu iestatījumu uz taisnība
un vērtība ir iestatīta uz nepatiesa
, kas, protams, ir absurds. Tā vietā, lai man būtu sarežģītas pārbaudes pašā konstruktorā, es nolēmu nodrošināt kontrolētu komplektu addOption ()
metodes.
Konstruktors arī izveido instanci java.util.regex.Pattern
, kas tiek izmantots šīs opcijas modeļu saskaņošanas procesā. Viens piemērs būtu tādas opcijas paraugs, kurā tiek ņemta vērtība, bez detaļām un atdalītājs bez tukša:
modelis = java.util.regex.Pattern.compile (prefikss.getName () + atslēga + separator.getName () + "(. +) $");
The OptionData
klasē, kā jau minēts, glabājas arī Iespējas
klasē. Tas nodrošina šādas publiskas metodes, lai piekļūtu šiem rezultātiem:
int getResultCount () virkne getResultValue (int indekss) virkne getResultDetail (int indekss)
Pirmā metode, getResultCount ()
, atgriež opciju atrašanas reižu skaitu. Šis metodes dizains ir tieši saistīts ar opcijai noteikto daudzveidību. Opcijām, kurām ir vērtība, šo vērtību var iegūt, izmantojot getResultValue (int indekss)
metodi, kur indekss var svārstīties starp 0
un getResultCount () - 1
. Vērtību opcijām, kas arī pieņem detalizētu informāciju, tām var līdzīgi piekļūt, izmantojot getResultDetail (int indekss)
metodi.
OptionSet klase
The OptionSet
klase būtībā ir konteiners kopai OptionData
gadījumi un arī komandrindā atrodamie datu argumenti.
Konstruktoram ir šāda forma:
OptionSet (Opcijas. Prefiksa prefikss, Opcijas. Daudzkārtības noklusējums. Daudzkārtība, String setName, int minData, int maxData)
Arī šim konstruktoram ir piekļuve pakotnei. Opciju kopas var izveidot tikai caur Iespējas
klase ir atšķirīga addSet ()
metodes. Šeit norādīto opciju noklusējuma daudzveidību var ignorēt, pievienojot opciju kopai. Šeit norādītais kopas nosaukums ir unikāls identifikators, ko izmanto, lai atsauktos uz kopu. minData
un maxData
ir minimālais un maksimālais pieļaujamo datu argumentu skaits šai kopai.
Vietnes API publiskā API OptionSet
satur šādas metodes:
Vispārējās piekļuves metodes:
Virkne getSetName () int getMinData () int getMaxData ()
Opciju pievienošanas metodes:
OptionSet addOption (virknes atslēga) OptionSet addOption (virknes atslēga, daudzkārtība) OptionSet addOption (virknes atslēga, atdalītāja atdalītājs) OptionSet addOption (virknes atslēga, atdalītāja atdalītājs, daudzkārtības daudzkārtība) OptionSet addOption (virknes atslēga, Būla informācija, atdalītāja atdalītājs) (Virknes atslēga, būla informācija, atdalītāja atdalītājs, daudzkārtības daudzkārtība)
Metodes, kā piekļūt pārbaudes rezultātu datiem:
java.util.ArrayList getOptionData () OptionData getOption (virknes atslēga) Boolean isSet (virknes atslēga) java.util.ArrayList getData () java.util.ArrayList getUnmatched ()
Ņemiet vērā, ka metožu pievienošana opcijām, kas prasa Atdalītājs
arguments izveidot OptionData
piemēram, pieņemot vērtību. The addOption ()
metodes atgriež pašu iestatīto gadījumu, kas ļauj piesaistīt ķēdi:
Opciju opcijas = new Opcijas (argumenti); options.addSet ("MySet"). addOption ("a"). addOption ("b");
Pēc pārbaužu veikšanas to rezultāti ir pieejami, izmantojot pārējās metodes. getOptionData ()
atgriež visu sarakstu OptionData
gadījumi, kamēr getOption ()
ļauj tieši piekļūt noteiktai opcijai. isSet (virknes atslēga)
ir ērtības metode, kas pārbauda, vai komandrindā opcijas tika atrastas vismaz vienu reizi. getData ()
nodrošina piekļuvi atrastajiem datu argumentiem, savukārt getUnmatched ()
uzskaita visas komandrindā atrastās opcijas, kurām nav atbilstības OptionData
gadījumi tika atrasti.
Opciju klase
Iespējas
ir galvenā klase, ar kuru lietojumprogrammas mijiedarbosies. Tas nodrošina vairākus konstruktorus, kuri visi ņem komandrindas argumentu virknes masīvu, kas galvenais ()
metode kā pirmo argumentu nodrošina:
Opcijas (String args []) Opcijas (String args [], int dati) Opcijas (String args [], int defMinData, int defMaxData) Opcijas (String args [], Multiplicity defaultMultiplicity) Opcijas (String args [], Multiplicity defaultMultiplicity, int dati) Opcijas (String args [], Multiplicity defaultMultiplicity, int defMinData, int defMaxData) Opcijas (String args [], Prefix prefix) Opcijas (String args [], Prefix prefix, int data) Opcijas (String args [], Prefix prefikss, int defMinData, int defMaxData) Opcijas (String args [], Prefix prefix, Multiplicity defaultMultiplicity) Opcijas (String args [], Prefix prefix, Multiplicity defaultMultiplicity, int data) Opcijas (String args [], Prefix prefix, Multiplicity defaultMultiplicity, int defMinData, int defMaxData)
Pirmais konstruktors šajā sarakstā ir vienkāršākais, izmantojot visas noklusējuma vērtības, bet pēdējais ir visizplatītākais.
1. tabula. Opciju () konstruktoru argumenti un to nozīme
|