A component is usually a complicated software entity running on a framework
(component framework) to provide complex services. For example, a component
can draw graphics for user. The component framework is a host for the
components, it creates / manages / destroys the components. There may be
several components on the framework. The component framework usually manages
the components in a consistent way, even though the functionalities or
behaviors of the components on it may be quite different.
Because a component must provide functionality for its user, so we usually
have a functionality interface in the component.
It is usually represented as:
+------------+
InterfaceName1 O---|MyComponent | where O--- means interface
InterfaceName2 O---| |
+------------+
So we have:
class IFunctionalityInterface_A
{
public: virtual void DrawGraph( ) = 0 ; //Interface have pure virtual method
//only
};
A component may provide different functionalities, so we have:
class IFunctionalityInterface_B
{
public: virtual void DoOtherStuff( ) = 0 ;
};
So for MyComponent, we have:
class MyComponent : public IFunctionalityInterface_A,
IFunctionalityInterface_B,
{
public: MyComponent( ) { .... }
public: virtual void DrawGraph( ) { cout << "I am drawing" ; ....}
public: virtual void DoOtherStuff( ) { .... }
};
Component developer provides this function for compoennt framework:
MyComponent * CreateACompoennt( ) { return new MyComponent( ) ; }
The component framework usually provides a GetComponentObject ( int
MyComponentID, void **ptrCom ) for user to get the compoent object.
void GetComponentObject ( int MyComponentID,
void **ptrCom )
{
// Component developer needs to register MyComponentID with the component
// framework which will store the ID in memory or in registries, this can be
// done during component installation time
//component framework loads the component module into memory,
//find the symbol and then execute createAComponent
//component framework may choose to internally maintain a
//map data structure for the compoennts to keep track
//whether the component has been loaded into memory,
//whether an instance of the component already exists.
*ptrCom = CreateAComponent ( ) ;
}
Now if a user just wants to use your MyComponent's DrawGraph( ), he can do:
int main ( void ) //one user
{
IFunctionalityInterface_A * ptrIA = 0 ;
GetComponentObject ( 1234, &ptrIA ) ;
( MyComponent * ) ptrIA->DrawGraph ( ) ;
delete ptrIA ;
return 0 ;
}
If another user just wants to use your MyComponent's DoOtherStuff( ), he can do:
int main ( void ) //another user
{
IFunctionalityInterface_B * ptrIB = 0 ;
GetComponentObject ( 1234, &ptrIB ) ;
( MyComponent * )ptrIB->DoOtherStuff ( ) ;
delete ptrIB ;
return 0 ;
}
Normally as a compoennt developer, you will never change the interfaces that
you already published. Instead you add new interface to your component.
Comments are welcome, please send to [email protected] Thank you!