nic*_*ick 2 c# command-line parsing design-patterns
我们使用特定的软件来执行我的控制台应用程序有很多参数(现在它是25(!),可能会越来越多).当然,不同的类需要不同的论点.我用NDesk.Options解析它.但是,我一次又一次地为所有班级做过.
class A {
A (IEnumerable<String> args){
new OptionSet {
{ "arg1=", value => foo1 = value },
{ "arg2=", value => foo2 = value },
...
}.Parse(args);
}
}
class B {
B (IEnumerable<String> args){
new OptionSet {
{ "arg10=", value => foo10 = value },
{ "arg11=", value => foo11 = value },
...
}.Parse(args);
}
}
Run Code Online (Sandbox Code Playgroud)
如何做好设计呢?解析静态类中的所有参数并使用它或其他东西?
由于您要求设计模式,这听起来像是Interpreter模式的工作.
否则,根据我的经验,命令行参数'解析'是模式匹配的一个很好的例子,不幸的是,C#没有,但F#没有.在ZeroToNine中,参数匹配当前如下所示:
let Parse argv =
match argv |> Seq.toList with
| ["-l"] -> ListVersions
| ["-a"; IsProperVersionString version] -> Assign version
| ["-i"; "major"] -> Increment Rank.Major
| ["-i"; "minor"] -> Increment Rank.Minor
| ["-i"; "build"] -> Increment Rank.Build
| ["-i"; "patch"] -> Increment Rank.Build
| ["-i"; "revision"] -> Increment Rank.Revision
| ["-a"; "major"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Major, rankValue)
| ["-a"; "minor"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Minor, rankValue)
| ["-a"; "build"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Build, rankValue)
| ["-a"; "patch"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Build, rankValue)
| ["-a"; "revision"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Revision, rankValue)
| ["-?"] -> ShowHelp
| ["-h"] -> ShowHelp
| [] -> ShowHelp
| x -> Unknown(x)
|> Seq.singleton
Run Code Online (Sandbox Code Playgroud)
当然,我们没有25个不同的参数,但上面的例子仍然可以让你很好地理解处理各种情况是多么容易.
即使你有一个C#代码库,你也可以在F#中编写一个解析器库.
稍微不同的说明:如果您的控制台应用程序需要25个不同的参数,将它分成几个较小的控制台应用程序是否有意义?听起来它做得很多.