470 likes | 592 Views
Practices of Good Component Design. Microsoft Research Asia Advanced Technology. Introduction. Barn-Wan Li Born in Toronto, Canada B.A., University of California, Berkeley Microsoft Silicon Valley Campus Microsoft Research Asia, Beijing. Software Components. Conceptualized in the 60s
E N D
Practices of Good Component Design Microsoft Research Asia Advanced Technology
Introduction • Barn-Wan Li • Born in Toronto, Canada • B.A., University of California, Berkeley • Microsoft Silicon Valley Campus • Microsoft Research Asia, Beijing
Software Components • Conceptualized in the 60s • Improve encapsulation and reuse
Software Components • Conceptualized in the 60s • Improve encapsulation and reuse
Software Components • Conceptualized in the 60s • Improve encapsulation and reuse PowerPoint Word Excel OfficeArt Drawing
How is a Component different than an Object? • Object-oriented Programming History • created in the 60s • real-world modeling and metaphors • microcosm of objects with messages
How is a Component different than an Object? • Object-oriented Programming History • created in the 60s • real-world modeling and metaphors • microcosm of objects with messages • the promise of the 80s • combining the concept of components for abstraction and reuse
How is a Component different than an Object? • Object-oriented Programming History • created in the 60s • real-world modeling and metaphors • microcosm of objects with messages • the promise of the 80s • combining the concept of components for abstraction and reuse • fear in the 90s • fragile software reuse with objects
Inheritance for Reuse • class Car • { • };
Inheritance for Reuse • class Car • { • };
Inheritance for Reuse • class Car • { • }; • class Racecar : public Car • { • }; • class Truck : public Car • { • }; • class Taxi : public Car • { • };
Inheritance for Reuse • class Truck • { • };
Inheritance for Reuse • class Truck • { • }; • class FireHydrant • { • }; • class FireTruck : • public Truck, • public FireHydrant • { • };
Inheritance for Reuse X • class Truck • { • }; • class FireHydrant • { • }; • class FireTruck : • public Truck, • public FireHydrant • { • };
Inheritance for Reuse • polymorphism • incremental behavior changes • self-recursive down-calls
Inheritance for Reuse • polymorphism • incremental behavior changes • self-recursive down-calls class Car { void Stop() { SayMessage(); } virtual void SayMessage() { cout << “Bye!” << endl; } }; class Taxi : public Car { virtual void SayMessage() { cout << “50 RMB please” << endl; } };
Inheritance for Reuse • breaks encapsulation • breaks data hiding • breaks implementation hiding • compile-time and run-time dependencies • syntactic and semantic fragility
class LinkList { … }; class MyObjList : public LinkList { … }; Reuse and Sharing - Templates
template <class T> class LinkList { … T *operator -> () { return &m_t; } T m_t; }; class MyObj { … }; typedef LinkList<MyObj> MyObjList; class LinkList { … }; class MyObjList : public LinkList { … }; Reuse and Sharing - Templates
class LinkList { … }; class MyObjList : public LinkList { … }; class MyObjTree : public BinTree { … }; template <class T> class LinkList { … T *operator -> () { return &m_t; } T m_t; }; class MyObj { … }; typedef LinkList<MyObj> MyObjList; typedef BinTree<MyObj> MyObjTree; Reuse and Sharing - Templates
class LinkList { }; class MyObjList : public LinkList { }; class MyObjTree : public BinTree { }; class MyObjList : public MyObj, public LinkList { }; template <class T> class LinkList { … T *operator -> () { return &m_t; } T m_t; }; class MyObj { … }; typedef LinkList<MyObj> MyObjList; typedef BinTree<MyObj> MyObjTree; Reuse and Sharing - Templates
class LinkList { }; class MyObjList : public LinkList { }; class MyObjTree : public BinTree { }; class MyObjList : public MyObj, public LinkList { }; template <class T> class LinkList { … T *operator -> () { return &m_t; } T m_t; }; class MyObj { … }; typedef LinkList<MyObj> MyObjList; typedef BinTree<MyObj> MyObjTree; Reuse and Sharing - Templates X
Reuse and Sharing - Containment • class LinkList • { • … • void Set(Object *pobj) { m_pObject = pobj; } • Object *Get() { return m_pObject; } • Object *m_pObject; • }; • class Object • { • … • Object() { m_linklist.Set(pobj); } • Object *Next() { return m_linklist.Next().Get(); } • … • LinkList m_listlist; • };
What is a Component • different layers • within a single system • sharable library • crossing application boundaries • crossing system boundaries • encapsulation and abstraction
How is a Component Design “Good”? • the component’s interface upholds a clear “contract”. • changes to the implementation of the component do not require changes in the code that uses it. • the component has reuse value when the time required to understand and integrate for a new user is faster and easier than to rewrite it.
Life-time of a Component • conception of an abstract layer, a sharable service, or a piece of code that has reuse value • understanding the requirements and limitations • designing the interfaces • implementation • creating the user of the component that wraps and tests the implementation
Example – Face Detection • BOOL DetectFace(HBITMAP image, CArray<RECT> &faces, CArray<long> &angles);
Example – Face Detection • BOOL DetectFace(HBITMAP image, CArray<RECT> &faces, CArray<long> &angles); • BOOL DetectFace(HBITMAP image, int &facenum, RECT *faces[], long *angles[]);
Example – Face Detection • BOOL DetectFace(HBITMAP image, CArray<RECT> &faces, CArray<long> &angles); • BOOL DetectFace(HBITMAP image, int &facenum, RECT *faces[], long *angles[]); • ULONG DetectFaceNumber(HBITMAP image); • BOOL DetectFace(HBITMAP image, int index, RECT *face, long *angle);
Example – Face Detection • BOOL DetectFace(HBITMAP image, CArray<RECT> &faces, CArray<long> &angles); • BOOL DetectFace(HBITMAP image, int &facenum, RECT *faces[], long *angles[]); • ULONG DetectFaceNumber(HBITMAP image); • BOOL DetectFace(HBITMAP image, int index, RECT *face, long *angle); • BOOL DetectFace(HDC image, int width, int height, int index, RECT *face, long *angle); • BOOL DetectFace(void pvBits, int width, int height, int bitsperpixel, int index, RECT *face, long *angle);
Introducing COM • Component Object Model • interface == pure virtual class • may be more than one object • language independent interface IUnknown { ULONG AddRef(); // reference counting ULONG Release(); HRESULT QueryInterface(); // dynamic casting }
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; Face Detection Interface
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; interface IFDImage { HRESULT SetHBitmap(HBITMAP bitmap); HRESULT SetHDC(HDC image, int width, int height); HRESULT SetBits(void pvBits, int width, int height, int bitsperpixel); }; Face Detection Interface
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; interface IFDImage { HRESULT SetHBitmap(HBITMAP bitmap); HRESULT SetHDC(HDC image, int width, int height); HRESULT SetBits(void pvBits, int width, int height, int bitsperpixel); }; interface IFDFaceEnum { HRESULT GetNum(ULONG *pNum); HRESULT GetFace(int index, IFDFace **pFace); }; Face Detection Interface
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; interface IFDImage { HRESULT SetHBitmap(HBITMAP bitmap); HRESULT SetHDC(HDC image, int width, int height); HRESULT SetBits(void pvBits, int width, int height, int bitsperpixel); }; interface IFDFaceEnum { HRESULT GetNum(ULONG *pNum); HRESULT GetFace(int index, IFDFace **pFace); }; interface IFDFace { HRESULT GetRect(RECT *pRect); HRESULT GetAngle(long *pAngle); }; Face Detection Interface
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; interface IFDImage { HRESULT SetHBitmap(HBITMAP bitmap); HRESULT SetHDC(HDC image, int width, int height); HRESULT SetBits(void pvBits, int width, int height, int bitsperpixel); }; interface IFDFaceEnum { HRESULT GetNum(ULONG *pNum); HRESULT GetFace(int index, IFDFace **pFace); }; interface IFDFace { HRESULT GetRect(RECT *pRect); HRESULT GetAngle(long *pAngle); HRESULT GetLeftEye(RECT *pRect); HRESULT GetRightEye(RECT *pRect); HRESULT GetAccuracy(long *pPercent); }; Face Detection Interface
Face Detection Interface Application Face Detection Component
Face Detection Interface Application IFDImage IFaceDetector IFDFaceEnum IFDFace Face Detection Component
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; Face Detection Implementation
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; class CFaceDetector : public IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; Face Detection Implementation
interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; class CFaceDetector : public IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; Face Detection Implementation HRESULT CFaceDetector::Detect(IFDImage *pImage, IFDFaceEnum **ppFaces) { if (pImage == NULL || ppResult == NULL) return E_INVALIDARG; : * ppFaces = new CFDFaceEnum; return E_SUCCESS; }
void main() { CComPtr<IFaceDetector> pDetector; pDetector.CreateInstance( CLSID_FaceDetector); : CComPtr<IFDFaceEnum> pResult; pDetector->Detect(pImage, pResult); : } interface IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; class CFaceDetector : public IFaceDetector { HRESULT Detect(IFDImage *pImage, IFDFaceEnum **ppFaces); }; Face Detection Usage
Face Detection Interface Application IFDImage IFaceDetector IFDFaceEnum IFDFace CFaceDetector CFDFaceEnum CFDFace Face Detection Component
Tips for Authoring a Component • know your callers • check for parameter errors at external APIs , assert for internal • avoid allocating memory that the caller must free • use existing types-- or create your own abstract interfaces • aggregate types for reuse or to hide complexity