• 控制台程序小工具:输入密码、指令指派、自动补全与帮助集成


        一、简介

        控制台程序小巧、便捷,开发起来简单。一般,我写项目时习惯在原定客户端之外,写一个控制台的客户端。这样有几个好处:

    (1)       开发量较WebGUI少得多。

    (2)       运行起来简单,占有资源很少。

    (3)       便于跟踪程序的运行。比如,用 log4net 记录日志的话,将appender-ref设置成ConsoleAppender,可以清楚看清系统运行轨迹,在使用nhibernate/activerecord开发时尤其方便。

    (4)       当为同一个系统开发两种不同的UI时,会自觉的做好分层,这样可以使系统的层次结构更清晰,便于维护。

    然而,虽然控制台程序的开发量少,也还是有一些常用功能实现起来较繁琐。比如,以下几个问题:

    (1)       输入密码。用户输入密码时,控制台显示****而不是密码明文;

    (2)       指令的解析与分派。控制台中,经常需要向程序输入纯字符串格式的指令,解析指令,解析参数的个数,调用相应的方法。

    (3)       指令的帮助系统。显示全部指令及其介绍。

    (4)       指令的自动补全。

    这几个问题在写控制台程序上经常会碰到,为此我写了两个类 ConsoleUtil CmdDispatcher,实现了上述功能,以供复用。于此下载代码

    代码是C#3.0 写的,若要用在其它C#版本,需要做一定的改动。

    二、使用方式:

    (1)       输入密码

    调用静态方法String ConsoleUtil.ReadPassword(String msg, String errMsgOnNull) 获取输入的密码。

    (2)       指令的解析、分派、自动补全与帮助系统

    (a)创建一个 CmdDispatcher 对象。

    (b)使用CmdDispatcher对象的AddCmdFunc方法,加入指令委托。这里定义了五种委托:

        delegate void Func0();
        
    delegate void Func1(String s1);
        
    delegate void Func2(String s1, String s2);
        
    delegate void Func3(String s1, String s2, String s3);
        
    delegate void Func4(String s1, String s2, String s3, String s4);

    AddCmdFunc方法有两种使用方式。

    AddCmdFunc(String cmd, Func0|Func1|Func2|Func3|Func4 func)

    AddCmdFunc(String cmd, String argsString, String introduce, Func0|Func1|Func2|Func3|Func4 func)

    后一种方式中 argsString 是该指令的参数字符串,introduce 是对这个指令的介绍。这两个变量的唯一意义是显示在该指令的help信息之中。如果使用前一种方式,该指令的help信息便是光秃秃的。

      比如,

                CmdDispatcher cd = new CmdDispatcher();
                cd.AddCmdFunc(
    "help""无参数""查询帮助.",
                    () 
    => { cd.PrintHelp(); });
                cd.AddCmdFunc(
    "cmd1""无参数""指令cmd1.",
                    () 
    => { Console.WriteLine(String.Format("Invoke cmd1.")); });
                cd.AddCmdFunc(
    "cmd2""arg0 arg1""指令cmd1.",
                    (arg0, arg1) 
    => { Console.WriteLine(String.Format("Invoke cmd1({0},{1}).", arg0, arg1)); });
                cd.AddCmdFunc(
    "cmd3",
                    (arg0, arg1, arg2) 
    => { Console.WriteLine(String.Format("Invoke cmd1({0},{1},{2}).", arg0, arg1, arg2)); });

    显示出来的 help 信息为:

    help    无参数
            查询帮助.

    cmd2    arg0 arg1
            指令cmd1.

    cmd3    无参数

        (3)CmdDispatcher对象的String ReadlineWithIntelliSence()方法获取控制台输入的指令.通过CmdDispatcher对象的Handle(String input)方法便可解析指令,分派给相应的委托完成。

        举例:

                while (true)
                
    {
                    Console.Write(cd.Prefix);    
    // 在控制台上输出提示符 >>。
                    String input = cd.ReadlineWithIntelliSence();
                    cd.Handle(input);
                }


         (4)不匹配的指令的处理方法
         CmdDispatcher有一个属性,public Func0 DefaultFunc { get; set; } 。CmdDispatcher 找不到匹配的委托时,便调用这个delegate。你可以自行设置 DefaultFunc,否则则用默认的内置 delegate。

    三、一个完整的例子

        下面是一个完整的例子:

     1using System;
     2using System.Collections.Generic;
     3using System.Linq;
     4using System.Text;
     5
     6namespace ConsoleTest
     7{
     8    class Program
     9    {
    10        static Boolean EXIT = false;
    11        static void Main(string[] args)
    12        {
    13            String id = ConsoleUtil.Readline("请输入帐号:","帐号不能为空.");
    14            String pwd = ConsoleUtil.ReadPassword("请输入密码:","密码不能为空.");
    15            Console.WriteLine("欢迎你,"+ id + "!");
    16            CmdDispatcher cd = CreateDispatcher();
    17            while (true)
    18            {
    19                Console.Write(cd.Prefix);
    20                String input = cd.ReadlineWithIntelliSence();
    21                cd.Handle(input);
    22                if (EXIT) return;
    23            }

    24        }

    25
    26        static CmdDispatcher CreateDispatcher()
    27        {
    28            CmdDispatcher cd = new CmdDispatcher();
    29            cd.AddCmdFunc("help""无参数""查询帮助.",
    30                () => { cd.PrintHelp(); });
    31            cd.AddCmdFunc("help""cmd""查询指定指令的帮助.",
    32                (cmd) => { cd.PrintHelp(cmd); });
    33            cd.AddCmdFunc("exit","无参数","退出程序.",
    34                () => { EXIT = true; });
    35            cd.AddCmdFunc("cmd1""无参数""指令cmd1.",
    36                () => { Console.WriteLine(String.Format("Invoke cmd1.")); });
    37            cd.AddCmdFunc("cmd1""arg0""指令cmd1.",
    38                (arg0) => { Console.WriteLine(String.Format("Invoke cmd1({0}).", arg0)); });
    39            cd.AddCmdFunc("cmd2""arg0 arg1""指令cmd1.",
    40                (arg0, arg1) => { Console.WriteLine(String.Format("Invoke cmd1({0},{1}).", arg0, arg1)); });
    41            cd.AddCmdFunc("cmd3",
    42                (arg0, arg1, arg2) => { Console.WriteLine(String.Format("Invoke cmd1({0},{1},{2}).", arg0, arg1, arg2)); });
    43            return cd;
    44        }

    45    }

    46}

    47

        运行结果:



    下载代码

    版权所有,欢迎转载
  • 相关阅读:
    Java之JDK的下载与安装,java环境变量的配置,Editplus的下载与使用
    JAVA基础语法
    数据库设计
    数据库练习题
    连接查询,子查询,联合查询
    Java内存管理-掌握虚拟机类加载器(五)
    Java内存管理-掌握虚拟机类加载机制(四)
    Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)
    Java内存管理-初始JVM和JVM启动流程(二)
    Java内存管理-程序运行过程(一)
  • 原文地址:https://www.cnblogs.com/xiaotie/p/1204445.html
Copyright © 2020-2023  润新知