代码复用是必要的,做开发的过程中自然而然感到代码复用的好处,现在感觉复用是必须的。代码复用可以大大提高软件开发的效率。
一、代码复用的历史
代码复用的出现时自然而然产生的,在程序开始变得复杂时,模块化的思想产生了,模块化可以降低耦合性。在函数式编程风行时,把经常使用的功能封装到一个函数中,方便程序维护,方便阅读,更方便以后使用。我想c runtime libary 应经使用了多年,可作为一个例子,还用其他的库。
进而到oop编程的时代,把常用的功能放到一个类中,出现了对象重用,扩大了重用的规模和范围,出现了STL为代表的库。具体重用的 技术有oop的特性之一多态,一个可以指向各种类型的指针(指针的深奥和强大令人惊讶),泛型编程(模板)。可以说从具体的编程技术过渡发展到一种编程框架,一种编程方法,我想有可能会出现一种泛型的IDE。hh. 我想mfc,vcl从某种意义上说也是这方面重用的体现,当然还有其他很多。在组件化时代,com组件大行其道,标志重用技术已经很成熟。com屏蔽了编程语言之间的差异,按照com规范编写的组件
可以在被各种语言环境所使用。activex在网页中应用很多,winform无需安装就可以在网页中运行,这些也模糊了cs和bs的界限。一个个的应用层的组件(....)在也成了公司的核心技术。dcom的出现使com可以在应用在网络(*)中也许系统真的可以通过组件重用通过程序员的组装就可以完成。有点像拉里.埃里森说的“你们都不用做软件了,。。。”. 这些都是开发一个好的系统的利器。写到这里有个想法,要大胆使用现存的各种库,各种可以重用的技术来达到自己的目的。
二 一个com代码重用的例子
1.类重用
一个vc中访问一卡通(java web service)数据的纯虚类 BaseWebCard.h
#pragma once
#include <vector>
using namespace std;
class CBaseWebCard
{
public:
CBaseWebCard(void);
public:
virtual ~CBaseWebCard(void);
//得到卡的余额
virtual BOOL GetBalance(CString strCardNo,CString strCardID,struct_echo_get_balance& s) = 0;
//扣款
virtual BOOL DeductMoney(struct_deduct_money stdm,struct_echo_deduct_money& s) = 0;
//扣掉本地的所有费用
virtual BOOL DeductAllMoney(void) = 0;
//插入所有的数据
virtual BOOL ImportAllCardData(CString arrData) = 0;
//导入所有的卡数据
virtual BOOL GetAllCardData(void) = 0;
//控制段验证卡的有效性
virtual BOOL AutherCard(CString strCardNo,CString strCardID) = 0;
//查询出卡的ID
virtual CString GetCardID(CString strCard) = 0;
virtual BOOL Init(CString strXML) = 0;
virtual BOOL InvokeMethod(const int nFunType,vector<CString> vecValue,CString& strResult,CString& strMethod) =0;
};
纯虚类的实现webcard.h
#pragma once
#include "BaseWebCard.h"
#include "WebCard2.h"
class CWebCard:public CBaseWebCard
{
public:
CWebCard();
virtual ~CWebCard();
//property
//method
public:
//初始化webservice
virtual BOOL Init(CString strXML);
//业务接口
public:
//得到卡的余额
virtual BOOL GetBalance(CString strCardNo,CString strCardID,struct_echo_get_balance& s);
//扣款
virtual BOOL DeductMoney(struct_deduct_money stdm,struct_echo_deduct_money& s);
//扣掉本地的所有费用
virtual BOOL DeductAllMoney(void);
//插入所有的数据
virtual BOOL ImportAllCardData(CString arrData);
//导入所有的卡数据
virtual BOOL GetAllCardData(void);
//控制段验证卡的有效性
virtual BOOL AutherCard(CString strCardNo,CString strCardID);
//查询出卡的ID
virtual CString GetCardID(CString strCard);
virtual BOOL InvokeMethod(const int nFunType,vector<CString> vecValue,CString& strResult,CString& strMethod);
CWebCard2 m_wc2;
};
类重用方式只要在使用的地方创建一个对象即可。
#include "webcard.h"
CWebCard m_wc;
.............
2.dll方式重用
dll方式重用可以只修改纯虚类而无需更改主程序的代码,也不需要重新编译主程序。有利于升级,分工维护
在规则dll中添加创建和销毁接口对象的函数
#include "webcard.h"
......
extern "C" _declspec(dllexport) CWebCard * CreateInstance()
{
m_pWC = new CWebCard();
if(!m_pWC)
{
return NULL;
}
return m_pWC;
}
extern "C" _declspec(dllexport) void ReleaseInstance()
{
if(m_pWC)
{
delete m_pWC;
m_pWC = NULL;
}
}
3.com方式
com方式可以是接口让其他语言调用,甚至在网页中调用,具有dll的所有优点。
comWebCard.idl文件
// comWebCard.idl : comWebCard 的 IDL 源
//
// 此文件将由 MIDL 工具处理以
// 产生类型库(comWebCard.tlb)和封送处理代码。
import "oaidl.idl";
import "ocidl.idl";
#include "Protocol.h"
[
object,
uuid(782A8D8D-C861-4254-A1B8-5478C3F16166),
helpstring("ICWebCard 接口"),
pointer_default(unique)
]
interface ICWebCard : IUnknown{
[, helpstring("方法GetBalance"), helpcontext(1)] HRESULT GetBalance([in] BSTR strNo, [in] BSTR strID, [in, out] struct_echo_get_balance* s, [out,retval] VARIANT_BOOL* bResult);
[, helpstring("方法DeductMondy")] HRESULT DeductMoney([in] struct_deduct_money stdm, [in,out] struct_echo_deduct_money* s, [out,retval] VARIANT_BOOL* bResult);
[, helpstring("方法DeductAllMoney")] HRESULT DeductAllMoney([out,retval] VARIANT_BOOL* bResult);
[, helpstring("方法ImportAllCardData")] HRESULT ImportAllCardData([in] BSTR arrData, [out,retval] VARIANT_BOOL* bResult);
[, helpstring("方法GetAllCardData")] HRESULT GetAllCardData([out,retval] VARIANT_BOOL* bResult);
[, helpstring("方法AutherCard")] HRESULT AutherCard([in] BSTR strCardNo, [in] BSTR strCardID, [out,retval] VARIANT_BOOL* bResult);
[, helpstring("方法GetCardID")] HRESULT GetCardID([in] BSTR strCardNo, [out,retval] BSTR* strResult);
[, helpstring("方法Init")] HRESULT Init([in] BSTR strXML,[out,retval] VARIANT_BOOL* bResult);
[, helpstring("方法InvokeMethod")] HRESULT InvokeMethod([in] SHORT nFunType, [in] SAFEARRAY(LONG) vecValue, [out,retval] BSTR* strResult);
};
[
uuid(84375B68-751C-4093-9051-C4898C6AE090),
version(1.0),
helpstring("comWebCard 1.0 类型库")
]
library comWebCardLib
{
importlib("stdole2.tlb");
[
uuid(8C19F1C6-BE62-4703-BD19-C55E0A24DD64),
helpstring("CWebCard Class")
]
coclass CWebCard
{
[default] interface ICWebCard;
};
};
com接口的使用
引入comWebCard.h,comWebCard_i.c文件
#include "comWebCard.h"
::CoInitialize(NULL);
CComPtr<ICWebCard> spWC;
HRESULT hr;
try
{
hr = spWC.CoCreateInstance(CLSID_CWebCard);
if(SUCCED(hr))
{
spWC->Init();
............}
spWC.Release();
}
}
catch(_com_error& e)
{
AfxMessageBox("com error");
}
::CoUninitialize();
结论: 代码重用从长眼角度讲可以大大提高系统的开发效率,可以有利于分工,可以形成公司的技术积累。