C++软件开发模块化的研究(2)

camelyi 2005-05-23 02:35:33
<2> 实际中的模块分工


接上一文的模块论,这里举一个实际的例子。某公司承接了一个软件项目的开发。其内容是开发一个在Windows下使用的ftp客户端。要求提供窗口界面和控制台下执行两种版本。现在考虑分工合作的问题。如果按上文“1.以可执行程序作为分工基本单位”,马上应将人员分为两组,一组负责开发ftp客户端窗口应用程序,另一组开发ftp控制台应用。

这样的问题现而易见。因为控制台程序和窗口程序有大量代码可以重用。那么如果分为两组人员立刻开始开发,则其结果是两组人员会重复大量工作。

实际工作中更加常用的方法,是先组织开发控制台下的ftp客户端程序。开发基本完毕后,部分代码被拷贝到新的工程中,继续建立窗口客户端应用。

应该说面对较小的工程,这种方法是简单有效的,而且管理成本最低。同时管理工作轻松愉快(因为基本不需要管理)。

但是我认为一些简单的工作,就可以把模块化初步建立起来,而不增加昂贵的管理成本。可以以后再在这个基础上追求更高级的管理流程(或者不追求维持现状)。使我们避免投入巨大的成本进入管理而耽误开发的时间。

为此假设我们把程序划分为以下的模块:

模块:

模块名 描述 库 头文件

tcp tcp通信模块 tcp.lib tcp.h
ftp ftp通信模块 ftp.lib ftp.h
win_controls Windows窗口控件模块 win_controls.lib win_controls.h
ftp_win_controls ftpWindows窗口控件模块 ftp_win_controls.lib ftp_win_controls.h


首先每个模块都应该有一个模块名,而且应该唯一.这样便于确定其接口的类名和变量名使用的前缀,从而最大程度避免库之间的冲突.

模块tcp的目的是想提供一个tcp协议的开发接口.实际上这是一个已经被大量研究的主题.开发一个好的tcp库是非常困难的(尤其是用于要求高性能的服务器上的时候),但是我们仅仅用于客户端建立tcp连接,那么是比较简单的.假设我们开发了这个库,可以想像tcp.h的内容:

#ifndef HEADHER_GD_TCP
#define HEADHER_GD_TCP

#ifdef _DEBUG
#pragma comment(lib,"tcp_d.lib")
#else
#pragma comment(lib,"tcp.lib")
#endif

class tcp_socket
{
public:
bool connect(...);
int receive(...);
int send(...);
...
protected:
virtual void on_connect(...);
virtual void on_receive(...);
virtual void on_send(...);
...
};

#endif

可以看出这个头文件非常的简单,不包含其他多余的东西,由于使用模块前缀,尽量避免了使用者的类名冲突(也可以使用名字空间,更好的办法是两者一起使用).确定该接口后,同事A将接受任务,开始开发模块tcp.同时同事B可以在这个接口的基础上,开发模块ftp.(虽然测试还不是很方便,但是确实可以开始开发了).

已经有人为socket提供了非常多的类.MFC中的CAsynSocket我个人用得比较多(仅仅用做客户端的话,性能问题并不大),以上tcp_socket类的实现,完全可以使用CAsynSocket.但是既然已经有CAsynSocket了,何必还要提供自己定义的接口tcp_socket呢?

我认为,即使MFC已经提供了非常好的部件,还是不时宜在模块之间的接口直接使用它们.假设现在直接用了CAsynSocket在接口中,那么从此这个模块和这个模块所有的使用者都被绑定到MFC上了.无论如何他们都必须使用MFC.如果不是这样,那么在其他的情况下,你完全可以用其他的网络通讯方法重新实现这个接口,而不用改动使用这个模块的程序.甚至你换到了其他操作系统下,你都可以顺利使用以前的代码.

那么ftp这个模块应该提供以下这样的接口:

...

class ftp_connect
{
public:
bool put(...);
bool get(...);
bool cd(...);
...
};

...

以上两个模块的接口都和操作系统无关.开发的难度比直接开发应用程序的难度仅仅大了一点点,但是可重用性比直接开发应用程序所产生的巨大头文件和互相交织的类要好得多.而且很方便移植.

涉及到窗口控件后和操作系统的相关性就大了很多.但是现在已经有很多和操作系统无关的窗口类库.我很少使用他们,不太好应用作为示例.但是我觉得使用MFC类库之前,做简单的封装,将对以后的改进和移植有巨大的帮助:

...

class wctls_dialog
{
protected:
virtual bool on_init();
virtual bool on_size(int cx,int cy);
...
};

...

把MFC中多如牛毛的控件做完全的重新封装有难度,但是至少可以简单封装我们常用的东西,比如CDialog,CButton,而不要直接使用它们.确定接口后由专人实现这个任务不会太耗时间,而且可以和这个软件的其他模块并行开发.而且,在以后再次开发windows应用程序的时候,这些工作就不用重复了.这是模块win_controls的意义.

ftp_win_control的意思是提供一组在ftp客户端中经常使用的窗口控件.比如说用来浏览ftp站点的目录树,用来拖动文件上传下载窗口,显示下载进度时间估计的小窗口等等.这些控件的特点是自身已经具备了网络连接的功能,放到任何程序里都能直接发挥ftp客户端的功能.这个模块在window_controls和ftp两个模块的基础上完成.

...

class ftp_connect;

// 一个树控件,用来显示ftp服务器上的目录和文件
class fwc_ftp_tree
{
public:
void set_connect(ftp_connect *con); // 指定一个ftp连接后,就能自动显示ftp服务器上的目录和文件
...
protected:
virtual void on_drag(...); // 可以捕获拖拽的动作用来上传或下载文件
...
};

...

这些控件做好后,一个窗口的ftp客户端就只是堆积木的工作了.应该有以下几个产品:

产品:

产品名 描述 可执行文件

ftp_win_client ftp客户端窗口应用 ftp_win_client.exe
ftp_con_client ftp控制台应用 ftp_con_client.exe

这些模块产生后,并不仅仅能用于此工程.以后其他的工程中需要这些功能时,也能很方便的应用它们.
...全文
154 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
mis98ZB 2005-05-24
  • 打赏
  • 举报
回复
我觉得,常见的方法不是文中所说的
“是先组织开发控制台下的ftp客户端程序。开发基本完毕后,部分代码被拷贝到新的工程中,继续建立窗口客户端应用。”
而是先开发控制台下的ftp客户端程序,然后再为它开发一个图形化Shell。
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质?你是否想成为一名资深开发人员,想开发别人做不了的高性能程序?你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? 那么C++就是你个人能力提升,职业之路进阶的不二之选。【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署;2.吊打一切关于C++的笔试面试题;3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块基础篇本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。进阶篇本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。提升篇:本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧