可扩展的SockBase设计和实现(3)
2006-08-05 11:19
295 查看
目录
摘要
嵌入式消息带来的问题
自定义消息命令类的设计实现
自定义消息命令类的使用
摘要
在前面的文章中,我们对于所有通过SockBase发送的消息都是直接通过嵌入式的字符串来完成的.比如”login”,”logout”,这样带来的一个问题就是如果不小心,写错一个字,在编译期是不能检查出来的.而且由于是直接内嵌在代码中的,和逻辑代码混在一起,不便于增加/修改消息.所以我们提出了使用自定义的消息命令类.
嵌入式消息带来的问题
由于这是一个基于Sockets的网络编程,所以我们通过Sockets输任何消息命令以及数据信息.在SockBase的实现中,我们通过Send(string)函数直接发送消息.在具体的使用SockBase的Send函数的时候,我们写的代码类似这样的:
private void GetFileHandler(string cmdText)
{
//检查文件是否存在
if((new FileManager()).CheckFileExist(cmdTxt))
{
Send(“OK”);
}
else
{
Send(“Failure”);
}
}
在这个里面,我们可以看到我们发送的消息就是直接写在代码中的”OK”,”Failure”等字符串.当然了,我们这个Send函数只能发送字符串..在这个程序中,这样是没问题的.
如果,后面的版本中,我们修改了消息命令体,把”OK”换成了”OKEY”,”Failure”换成了”Fail”,这时我们就得通过VS.NET IDE的搜索功能或是自己去手动的把原来的字符串替换成现在的.如果这个程序代码不多,就100多行,那很简单.一会儿就搞定了.但是如果这个程序比较大呢?有上千行代码?有很多地方使用到了这些个字符串呢?
这时,修改程序就成了一个恶梦,在修改的过程中就得异常小心,稍有不慎,程序就出现Bugs.这种情况出现的原因是因为消息是具有不确定性的,而我们在代码中是直接内嵌消息体(以字符串的形式),和逻辑代码直接混合在一起,影响程序的修改,扩展性.
自定义消息命令类的设计实现
基于上面分析的原因,我们不使用以字符串的形式的直接内嵌的消息命令.取而代之,我们使用我们自定义的消息命令类.
我们的消息命令有两部分,一部分就是消息体,另一部分就是此消息对应的参数.所以,我们定义消息命令类CommandBuilder如下:
public class CommandBuilder
{
private string m_Command;
private string m_CommandText;
private string m_AllCmdText;
//命令前缀,即命令
public string Command
{
get{return m_Command;}
set{m_Command=value;}
}
//命令内容
public string CommandText
{
get{return m_CommandText;}
set{m_CommandText=value;}
}
}
通过构造函数对其进行初始化:
//外部消息发送
public CommandBuilder(string commandPrefix,string commandText)
{
m_Command=commandPrefix;
m_CommandText=commandText;
}
//构造函数为已经完整的命令
public CommandBuilder(string AllcommandText)
{
m_AllCmdText=AllcommandText;
}
由于我们通过SockBase发送的是整个消息,包括消息体和参数,即我们得把消息体和参数连接起来.为了方便进行消息体和参数的解析,我们还得在消息体和参数中加入一个分隔符.基于上面所说的同样的原因.我们也不使用直接内嵌的字符串,使用CommandBuilder内部的一个成员变量来存放分隔符.
private string m_SpliteChars = “;”;
这样,如果我们要修改,只要直接修改这一个成员的值就行了.而且我们还可以把分隔符存储在配置文件中,使用的时候直接从配置文件进行读取.这样更加灵活.但是在这里,我们就使用上述方式.
好了,消息命令类基本的数据成员完成了.
现在提供一个函数,直接把最终的可以直接通过SockBase的Send函数发的送的字符串输出:
public string SenderMsg
{
get
{
if( m_AllCmdText!=null && m_AllCmdText!=String.Empty )
return m_AllCmdText;
else
{
return m_Command+ m_SpliteChars +m_CommandText;
}
}
}
现在消息命令类已基本完成了,现在就差对命令进行包装了.我们可以直接写成一个类的静态成员,所有对消息的引用都直接使用这个类中的静态成员.同样的,我们也可以直接写到一个配置文件中.这里,为了简单,我们就直接使用类的静态成员.定义CommandList定义如下:
public class CommandList
{
//命令字符串
public static string GETFILE = "GetFile";
public static string OK = “OK”;
public static string FAILURE = “FAILURE”;
}
好,现在就可以开始使用CommandBuilder和CommandList代替内嵌字符串了.
自定义消息命令类的使用
这里,我们就没必要去修改SockBase了,只要修改前面文章中的Client_ListenThread类即可.修改后的代码如下:
private void GetFileHandler(string cmdText)
{
CommandBuilder cmdBuilder ;
//检查文件是否存在
if((new FileManager()).CheckFileExist(cmdTxt))
{
cmdBuilder = new CommandBuilder(CommandList.GETFILE,CommandList.OK);
}
else
{
cmdBuilder = new CommandBuilder(CommandList.GETFILE,CommandList. FAILURE);
}
Send(cmdBuilder.SenderMsg);
}
总结
将程序中的字符串等封装成类的(静态)变量是一个很好的习惯,特别是在变化比较大的程序开发中.这样有利于代码的复用,以及代码的修改的维护.
摘要
嵌入式消息带来的问题
自定义消息命令类的设计实现
自定义消息命令类的使用
摘要
在前面的文章中,我们对于所有通过SockBase发送的消息都是直接通过嵌入式的字符串来完成的.比如”login”,”logout”,这样带来的一个问题就是如果不小心,写错一个字,在编译期是不能检查出来的.而且由于是直接内嵌在代码中的,和逻辑代码混在一起,不便于增加/修改消息.所以我们提出了使用自定义的消息命令类.
嵌入式消息带来的问题
由于这是一个基于Sockets的网络编程,所以我们通过Sockets输任何消息命令以及数据信息.在SockBase的实现中,我们通过Send(string)函数直接发送消息.在具体的使用SockBase的Send函数的时候,我们写的代码类似这样的:
private void GetFileHandler(string cmdText)
{
//检查文件是否存在
if((new FileManager()).CheckFileExist(cmdTxt))
{
Send(“OK”);
}
else
{
Send(“Failure”);
}
}
在这个里面,我们可以看到我们发送的消息就是直接写在代码中的”OK”,”Failure”等字符串.当然了,我们这个Send函数只能发送字符串..在这个程序中,这样是没问题的.
如果,后面的版本中,我们修改了消息命令体,把”OK”换成了”OKEY”,”Failure”换成了”Fail”,这时我们就得通过VS.NET IDE的搜索功能或是自己去手动的把原来的字符串替换成现在的.如果这个程序代码不多,就100多行,那很简单.一会儿就搞定了.但是如果这个程序比较大呢?有上千行代码?有很多地方使用到了这些个字符串呢?
这时,修改程序就成了一个恶梦,在修改的过程中就得异常小心,稍有不慎,程序就出现Bugs.这种情况出现的原因是因为消息是具有不确定性的,而我们在代码中是直接内嵌消息体(以字符串的形式),和逻辑代码直接混合在一起,影响程序的修改,扩展性.
自定义消息命令类的设计实现
基于上面分析的原因,我们不使用以字符串的形式的直接内嵌的消息命令.取而代之,我们使用我们自定义的消息命令类.
我们的消息命令有两部分,一部分就是消息体,另一部分就是此消息对应的参数.所以,我们定义消息命令类CommandBuilder如下:
public class CommandBuilder
{
private string m_Command;
private string m_CommandText;
private string m_AllCmdText;
//命令前缀,即命令
public string Command
{
get{return m_Command;}
set{m_Command=value;}
}
//命令内容
public string CommandText
{
get{return m_CommandText;}
set{m_CommandText=value;}
}
}
通过构造函数对其进行初始化:
//外部消息发送
public CommandBuilder(string commandPrefix,string commandText)
{
m_Command=commandPrefix;
m_CommandText=commandText;
}
//构造函数为已经完整的命令
public CommandBuilder(string AllcommandText)
{
m_AllCmdText=AllcommandText;
}
由于我们通过SockBase发送的是整个消息,包括消息体和参数,即我们得把消息体和参数连接起来.为了方便进行消息体和参数的解析,我们还得在消息体和参数中加入一个分隔符.基于上面所说的同样的原因.我们也不使用直接内嵌的字符串,使用CommandBuilder内部的一个成员变量来存放分隔符.
private string m_SpliteChars = “;”;
这样,如果我们要修改,只要直接修改这一个成员的值就行了.而且我们还可以把分隔符存储在配置文件中,使用的时候直接从配置文件进行读取.这样更加灵活.但是在这里,我们就使用上述方式.
好了,消息命令类基本的数据成员完成了.
现在提供一个函数,直接把最终的可以直接通过SockBase的Send函数发的送的字符串输出:
public string SenderMsg
{
get
{
if( m_AllCmdText!=null && m_AllCmdText!=String.Empty )
return m_AllCmdText;
else
{
return m_Command+ m_SpliteChars +m_CommandText;
}
}
}
现在消息命令类已基本完成了,现在就差对命令进行包装了.我们可以直接写成一个类的静态成员,所有对消息的引用都直接使用这个类中的静态成员.同样的,我们也可以直接写到一个配置文件中.这里,为了简单,我们就直接使用类的静态成员.定义CommandList定义如下:
public class CommandList
{
//命令字符串
public static string GETFILE = "GetFile";
public static string OK = “OK”;
public static string FAILURE = “FAILURE”;
}
好,现在就可以开始使用CommandBuilder和CommandList代替内嵌字符串了.
自定义消息命令类的使用
这里,我们就没必要去修改SockBase了,只要修改前面文章中的Client_ListenThread类即可.修改后的代码如下:
private void GetFileHandler(string cmdText)
{
CommandBuilder cmdBuilder ;
//检查文件是否存在
if((new FileManager()).CheckFileExist(cmdTxt))
{
cmdBuilder = new CommandBuilder(CommandList.GETFILE,CommandList.OK);
}
else
{
cmdBuilder = new CommandBuilder(CommandList.GETFILE,CommandList. FAILURE);
}
Send(cmdBuilder.SenderMsg);
}
总结
将程序中的字符串等封装成类的(静态)变量是一个很好的习惯,特别是在变化比较大的程序开发中.这样有利于代码的复用,以及代码的修改的维护.
相关文章推荐
- 可扩展的SockBase设计和实现(2)
- 可扩展的SockBase设计和实现
- 可扩展的SockBase设计和实现(1)
- 数据库高可用:SQL Server横向扩展:设计,实现与维护(2)- 分布式分区视图(上)
- 高考中国网高可用、负载均衡、可扩展设计与实现
- 设计技巧8:Abstract server 在客户端和实现类之间添加一个接口,以符合OCP,DIP原则,方便扩展
- 《设计模式--基于C#的工程化实现及扩展》补充 Security Design Pattern 系列 1 公钥体系与分布式环境要求
- 《模式——工程化实现及扩展》(设计模式C# 版)《原型模式 Prototype》——“自我检验"
- SQL Server横向扩展:设计,实现与维护(3)- 分布式分区视图的实现
- 《设计模式--基于C#的工程化实现及扩展》 Security Design Pattern 系列 4 角色模式(Role Pattern) 【转】
- 与王翔面对面——《设计模式——基于C#的工程化实现及扩展》作者访谈录
- 设计模式基于C#的工程化实现及扩展
- 《模式——工程化实现及扩展》(设计模式C# 版)《访问者模式 Visitor》——“自我检验"
- 基于FPGA的以太网MII接口扩展设计与实现
- 《模式——工程化实现及扩展》(设计模式C# 版)《解释器模式 Interpreter》——“自我检验" 参考答案
- 使用高阶函数实现类的扩展设计
- 实现类似“添加扩展程序…”的设计时支持
- 高考中国网高可用、负载均衡、可扩展设计与实现
- 基于RBAC扩展模型的实验室综合管理系统设计与实现
- 按"利用C++语言设计可扩展线程池"文章实现代码,但是有问题,希望大家来讨论,指出问题,谢谢