一:区分组建与对象
组件(Component)是系统中一种物理的、可代替的部件、它封装了实现并提供了一系列可用的接口。一个组件代表一个系统中实现的物理部分,包括软件代码(源代码,二进制代码,可执行代码)或者一些类似内容,如脚本或者命令文件。简而言之,组件就是对象,是对数据和方法的简单封装。
对象(Object)是指现实世界中客观存在的事物。
组件基于对象,同时又是对象的一种,可插入系统中的对象。
组件可以在另一个称为容器(有时也称为承载者或宿主)的应用程序中使用,也可以作为独立过程使用;
组件可以由一个类构成,也可以由多个类组成,或者是一个完整的应用程序;
组件为模块重用,而对象为代码重用。
我的理解:组件相对于对象来说,更加复杂化,更加整合,它可以被当作一个独立的主体拿来用,在不同的系统中实现组件的替换,组件的粒度大于对象,组件是对对象的一种装饰,将简单的对象根据不同的需求加以封装成单一功能的组件,使用起来更加方便灵活,组件的粒度大于对象,组件之间是通过接口实现交互,接口内含有多个信息,而对象之间交互是单个信息,用信件传送信息时,对象需要一封一封的传送,而组件则是将所有信息一次性传送完,再举一个生活化的例子:盖房子的时候需要用到水泥、沙土、石子等原材料,而有一种材料叫做混凝土,它是用水泥作胶凝材料,砂、石作集料,加上一定比例的水制成的一种材料,前者可以看做是对象,后者可以看做是组件,而不同的粒度也因此显现出来。
有两个问题:关于组件和对象的关系有没有更为精准的描述词语?面向组件技术优于面向对象技术吗?
关于面向组件和面向对象技术的知识还有许多,期待大家继续去探索……
二、区分组建与对象
1. 用户一般希望能够定制所用的应用程序,而组件技术从本质上讲就是可被定制的,因而用户可以用更能满足他们需要的某个组件来替换原来的那个。
2.由于组件是相对应用程序独立的部件,我们可以在不同的程序中使用同一个组件而不会产生任何问题,软件的可重用性将大大的得到增强。 3.随着网络带宽及其重要性的提高,分布式网络应用程序毫无疑问的成为软件市场上越来越重要的买点。组件价构可以使得开发这类应用程序的过程得以简化。
1.首先我们先为动态库的加载以及接口的获取做准备工作
1、
#ifndef MODULE_HEAD_FILE
#define MODULE_HEAD_FILE
#pragma once
#include <AfxWin.h>
//查询接口
#define QUERYINTERFACE(Interface,Guid) \
if(IID_##Interface==Guid) \
return static_cast<Interface *>(this);
//查询接口
#define QUERYINTERFACE_IUNKNOWNEX(BaseInterface,Guid) \
if(Guid==IID_IUnknownEx) \
return static_cast<IUnknownEx *>(static_cast<BaseInterface *>(this));
//查询接口
#define QUERY_ME_INTERFACE(Interface) \
((Interface *)QueryInterface(IID_##Interface))
//查询接口
#define QUERY_OBJECT_INTERFACE(Object,Interface) \
((Interface *)Object.QueryInterface(IID_##Interface))
//查询接口
#define QUERY_OBJECT_PTR_INTERFACE(pObject,Interface) \
((pObject==NULL)?NULL:((Interface *)pObject->QueryInterface(IID_##Interface)))
//基础接口
static const GUID IID_IUnknownEx = { 0x5feec21e,0xdbf3,0x46f0,0x9f,0x57,0xd1,0xcd,0x71,0x1c,0x46,0xde };
struct IUnknownEx
{
//释放对象
virtual void Release() = NULL;
//接口查询
virtual void * QueryInterface(REFGUID Guid) = NULL;
};
//组件创建函数
typedef VOID * (ModuleCreateProc)(REFGUID Gudi);
//组件辅助类模板
template <typename IModeluInterface>
class CTempldateHelper
{
//接口属性
public:
REFGUID m_Guid; //接口标识
//组件属性
public:
char m_szCreateProc[32]; //创建函数
wchar_t m_szModuleDllName[MAX_PATH]; //组件名字
//内核变量
public:
HINSTANCE m_hDllInstance; //DLL 句柄
IModeluInterface * m_pIModeluInterface; //模块接口
//辅助变量
public:
wchar_t m_szDescribe[128]; //错误描述
//函数定义
public:
//构造函数
CTempldateHelper(REFGUID Guid);
//构造函数
CTempldateHelper(REFGUID Guid, wchar_t* pszModuleDll, char* pszCreateProc);
//析构函数
virtual ~CTempldateHelper();
//管理函数
public:
//释放组件
bool CloseInstance();
//创建组件
bool CreateInstance();
//配置函数
public:
//创建信息
void SetModuleCreateInfo(wchar_t* pszModuleDllName, char * pszCreateProc);
//辅助函数
public:
//获取错误
inline wchar_t* GetErrorDescribe() const;
//指针重载
inline IModeluInterface * operator->() const;
//获取接口
inline IModeluInterface * GetInterface() const;
};
//构造函数
template <typename IModeluInterface>
CTempldateHelper<IModeluInterface>::CTempldateHelper(REFGUID Guid):m_Guid(Guid)
{
//辅助变量
m_szDescribe[0] = 0;
//内核信息
m_hDllInstance = NULL;
m_pIModeluInterface = NULL;
//组件属性
memset(&m_szCreateProc, 0,sizeof(m_szCreateProc));
memset(&m_szModuleDllName,0, sizeof(m_szModuleDllName));
return;
}
//构造函数
template <typename IModeluInterface>
CTempldateHelper<IModeluInterface>::CTempldateHelper(REFGUID Guid, wchar_t* pszModuleDll, char* pszCreateProc) :m_Guid(Guid)
{
//辅助变量
m_szDescribe[0] = 0;
//内核信息
m_hDllInstance = NULL;
m_pIModeluInterface = NULL;
//组件属性
strcpy(m_szCreateProc, pszCreateProc);
lstrcpy(m_szModuleDllName, pszModuleDll);
return;
}
//析构函数
template <typename IModeluInterface>
CTempldateHelper<IModeluInterface>::~CTempldateHelper()
{
//辅助变量
m_szDescribe[0] = 0;
//内核信息
m_hDllInstance = NULL;
m_pIModeluInterface = NULL;
//组件属性
memset(m_szCreateProc, 0, sizeof(m_szCreateProc));
memset(m_szModuleDllName, 0, sizeof(m_szModuleDllName));
return;
}
//释放组件
template <typename IModeluInterface>
bool CTempldateHelper<IModeluInterface>::CloseInstance()
{
//设置变量
m_szDescribe[0] = 0;
//销毁对象
if (m_pIModeluInterface != NULL)
{
m_pIModeluInterface->Release();
m_pIModeluInterface = NULL;
}
//释放 DLL
if (m_hDllInstance != NULL)
{
AfxFreeLibrary(m_hDllInstance);
m_hDllInstance = NULL;
}
return true;
}
//创建组件
template <typename IModeluInterface>
bool CTempldateHelper<IModeluInterface>::CreateInstance()
{
//释放组件
CloseInstance();
//创建组件
try
{
//效验参数
ASSERT(m_szCreateProc[0] != 0);
ASSERT(m_szModuleDllName[0] != 0);
//加载模块
m_hDllInstance = AfxLoadLibrary(m_szModuleDllName);
if (m_hDllInstance == NULL)
{
_sntprintf(m_szDescribe, 128, TEXT("“%s”模块加载失败"), m_szModuleDllName);
return false;
}
//寻找函数
ModuleCreateProc * CreateProc = (ModuleCreateProc *)GetProcAddress(m_hDllInstance, m_szCreateProc);
if (CreateProc == NULL)
{
_sntprintf(m_szDescribe, 128, TEXT("找不到组件创建函数“%s”"), m_szCreateProc);
return false;
}
//创建组件
m_pIModeluInterface = (IModeluInterface *)CreateProc(m_Guid);
if (m_pIModeluInterface == NULL)
{
_sntprintf(m_szDescribe, 128, TEXT("调用函数“%s”生成对象失败"), m_szCreateProc);
return false;
}
}
catch (LPCTSTR pszError)
{
_sntprintf(m_szDescribe, 128, TEXT("由于“%s”,组件创建失败"), pszError);
return false;
}
catch (...)
{
_sntprintf(m_szDescribe, 128, TEXT("组件创建函数“%s”产生未知异常错误,组件创建失败"), m_szCreateProc);
return false;
}
return true;
}
//创建信息
template <typename IModeluInterface>
void CTempldateHelper<IModeluInterface>::SetModuleCreateInfo(wchar_t* pszModuleDllName, char* pszCreateProc)
{
//组件属性
strcpy(m_szCreateProc, pszCreateProc);
lstrcpy(m_szModuleDllName, pszModuleDllName);
return;
}
//获取错误
template <typename IModeluInterface>
inline wchar_t* CTempldateHelper<IModeluInterface>::GetErrorDescribe()const
{
return m_szDescribe;
}
//指针重载
template <typename IModeluInterface>
inline IModeluInterface * CTempldateHelper<IModeluInterface>::operator->() const
{
return GetInterface();
}
//获取接口
template <typename IModeluInterface>
inline IModeluInterface * CTempldateHelper<IModeluInterface>::GetInterface() const
{
return m_pIModeluInterface;
}
//
//组件辅助宏
//组件创建函数
#define DECLARE_CREATE_MODULE(OBJECT_NAME) \
extern "C" __declspec(dllexport) VOID * Create##OBJECT_NAME(REFGUID Guid) \
{ \
C##OBJECT_NAME * p##OBJECT_NAME=NULL; \
try \
{ \
p##OBJECT_NAME=new C##OBJECT_NAME(); \
if (p##OBJECT_NAME==NULL) throw TEXT("创建失败"); \
VOID * pObject=p##OBJECT_NAME->QueryInterface(Guid); \
if (pObject==NULL) throw TEXT("接口查询失败"); \
return pObject; \
} \
catch (...) {} \
delete p##OBJECT_NAME; \
return NULL; \
}
//组件辅助类宏
#define DECLARE_MODULE_DYNAMIC(OBJECT_NAME) \
class C##OBJECT_NAME##Helper : public CTempldateHelper<I##OBJECT_NAME> \
{ \
public: \
C##OBJECT_NAME##Helper() : CTempldateHelper<I##OBJECT_NAME>(IID_I##OBJECT_NAME) { } \
};
//组件辅助类宏
#define DECLARE_MODULE_HELPER(OBJECT_NAME,MODULE_DLL_NAME,CREATE_FUNCTION_NAME) \
class C##OBJECT_NAME##Helper : public CTempldateHelper<I##OBJECT_NAME> \
{ \
public: \
C##OBJECT_NAME##Helper() : CTempldateHelper<I##OBJECT_NAME>(IID_I##OBJECT_NAME, \
MODULE_DLL_NAME,CREATE_FUNCTION_NAME) { } \
};
//
#endif
2、我们写一个动态库来进行测试一下
1、接口文件:Isort.h
#pragma once
#include"Module.h"
//模块定义
#define PROCESS_CONTROL_DLL_NAME TEXT("Sort.dll") //组件名字
//冒泡排序
static const GUID IID_IBubbleSort = { 0x5feec22e,0xdbf3,0x46f0,0x9f,0x57,0xd1,0xcd,0x71,0x1c,0x46,0xde };
struct IBubbleSort:public IUnknownEx
{
virtual void BubbleSort(char* ptr, int len)=NULL;
};
//快速排序
static const GUID IID_IQuickSort = { 0x5feec23e,0xdbf3,0x46f0,0x9f,0x57,0xd1,0xcd,0x71,0x1c,0x46,0xde };
struct IQuickSort:public IUnknownEx
{
virtual void QuickSort(char* ptr, int Low, int High) = NULL;
};
//一个循环
static const GUID IID_IOneWhileSort = { 0x5feec24e,0xdbf3,0x46f0,0x9f,0x57,0xd1,0xcd,0x71,0x1c,0x46,0xde };
struct IOneWhileSort:public IUnknownEx
{
virtual void OneWhileSort(char* Array, int len) = NULL;
};
//
//组件创建
DECLARE_MODULE_HELPER(BubbleSort, PROCESS_CONTROL_DLL_NAME, "CreateSort")
DECLARE_MODULE_HELPER(QuickSort, PROCESS_CONTROL_DLL_NAME, "CreateSort")
DECLARE_MODULE_HELPER(OneWhileSort, PROCESS_CONTROL_DLL_NAME, "CreateSort")
//
2.算法头文件:Sort.h
#pragma once
#include "ISort.h"
class CSort : public IBubbleSort, public IQuickSort, public IOneWhileSort
{
public:
//释放对象
virtual void Release() {};
//接口查询
virtual void * QueryInterface(REFGUID Guid);
//冒泡排序
virtual void BubbleSort(char* ptr, int len);
//快速排序
virtual void QuickSort(char* ptr, int Low, int High);
//一个循环
virtual void OneWhileSort(char* Array, int len);
};
3、算法源文件:Sort.cpp
#include "stdafx.h"
#include "Sort.h"
void* CSort::QueryInterface(REFGUID Guid)
{
QUERYINTERFACE(IBubbleSort, Guid)
QUERYINTERFACE(IQuickSort, Guid)
QUERYINTERFACE(IOneWhileSort, Guid)
QUERYINTERFACE_IUNKNOWNEX(IBubbleSort, Guid)
}
//冒泡排序
void CSort::BubbleSort(char* ptr, int len)
{
for (int i = 0; i<len - 1; i++)
{
for (int j = i + 1; j<len; j++)
{
if (ptr[i]>ptr[j])
{
ptr[i] += ptr[j];
ptr[j] = ptr[i] - ptr[j];
ptr[i] = ptr[i] - ptr[j];
}
}
}
return;
}
//快速排序
void CSort::QuickSort(char* ptr, int Low, int High)
{
if (Low>High)
return;
char temp = ptr[Low];
int tempLow = Low;
int tempHigh = High;
while (tempLow<tempHigh)
{
while (tempLow<tempHigh&&temp <= ptr[tempHigh])
{
tempHigh--;
}
char tempData = ptr[tempHigh];
ptr[tempHigh] = ptr[tempLow];
ptr[tempLow] = tempData;
while (tempLow<tempHigh&&temp>ptr[tempLow])
{
tempLow++;
}
tempData = ptr[tempHigh];
ptr[tempHigh] = ptr[tempLow];
ptr[tempLow] = tempData;
}
QuickSort(ptr, Low, tempLow - 1);
QuickSort(ptr, tempLow + 1, High);
return;
}
//一个循坏排序
void CSort::OneWhileSort(char* Array, int len)
{
int temp = 0;
int i = 0;
while (i < len)
{
temp++;
if (i == 0 || Array[i - 1] <= Array[i])
{
i += temp;
temp = 0;
}
else
{
int t = Array[i];
Array[i] = Array[i - 1];
Array[i - 1] = t;
i--;
}
}
return;
}
DECLARE_CREATE_MODULE(Sort)
3.mian函数的调用
#include "stdafx.h"
#include "Array.h"
#include "Module.h"
#include "ISort.h"
int main()
{
//冒泡排序
CBubbleSortHelper BubbleSort;
BubbleSort.CreateInstance();
IBubbleSort* pBubbleSort = BubbleSort.GetInterface();
char data1[10] = { 15,5,8,20,5,4,10,5,6,25 };
pBubbleSort->BubbleSort(data1, 10);
for (int i = 0; i < 10; i++)
printf("%d\n", data1[i]);
//快速排序
CQuickSortHelper QuickSort;
QuickSort.CreateInstance();
IQuickSort *pQuickSort = QuickSort.GetInterface();
char data2[10] = { 15,5,8,20,5,4,10,5,6,25 };
pQuickSort->QuickSort(data2, 0,9);
for (int i = 0; i < 10; i++)
printf("%d\n", data2[i]);
return 0;
}