In the terminolgy of the Bridge Pattern (see its Structure on p. 153), the CArchive class represents the Abstraction while the Implementor and its sub-classes are represented by CFile, CSocketFile, CMemFile, COleStreamFile, etc.
In Programming with MFC and Win32, we read "A CArchive object provides a type-safe bufferring mechanism for writing or reading serializable objects to or from a CFile object. Usually the CFile object represents a disk file; however, it can also be a memory file (CMemFile object), perhaps representing the Clipboard".
CSocketFile, which is the most recent descendent of CFile, cleary shows how the domain for the serialization of objects (using the abstract CArchive) is expanding due to the Bridge Pattern.
If you look at the constructor call (below) of the CArchive object, you will see that it expects a pointer to a CFile (CFile*). Since CFile owns a polymorphic interface, any CFile or CFile descendant (such as CSocketFile, CStdioFile, CMemFile, COleStreamFile) can be passed as a valid argument to CArchive's constructor. Through the CFile interface, a request to WRITE to, READ from or FLUSH (for instance) the archive will be routed to the correct CFile or CFile descendent object.
CArchive Constructor
CArchive::CArchive(CFile* pFile, UINT nMode, int nBufSize, void* lpBuf) { // initialize members not dependent on allocated buffer m_nMode = nMode; m_pFile = pFile; // DESIGN PATTERNS NOTE: Here is our Implementor Object // ... more member variables and methods declared below } UINT CArchive::Read(void* lpBuf, UINT nMax) { // ... (Lots of code here taken out for the sake of brevity do { // DESIGN PATTERNS NOTE: represents call to OperationImp() in the Bridge's Implementor nBytes = m_pFile->Read(lpBuf, nLeft); // ... (Lots of code here taken out for the sake of brevity } while ((nBytes > 0) && (nLeft > 0)); // ... (Lots of code here taken out for the sake of brevity } void CArchive::Write(const void* lpBuf, UINT nMax) { // ... (Lots of code here taken out for the sake of brevity if (nMax > 0) { Flush(); // flush the full buffer // write rest of buffer size chunks nTemp = nMax - (nMax % m_nBufSize); // DESIGN PATTERNS NOTE: represents call to OperationImp() in the Bridge's Implementor m_pFile->Write(lpBuf, nTemp); lpBuf = (BYTE*)lpBuf + nTemp; nMax -= nTemp; // ... (Lots of code here taken out for the sake of brevity } // ... (Lots of code here taken out for the sake of brevity } void CArchive::Flush() { // ... (Lots of code here taken out for the sake of brevity if (!m_bDirectBuffer) { // write out the current buffer to file // DESIGN PATTERNS NOTE: represents call to OperationImp() in the Bridge's Implementor m_pFile->Write(m_lpBufStart, m_lpBufCur - m_lpBufStart); // ... (Lots of code here taken out for the sake of brevity } else { // commit current buffer // DESIGN PATTERNS NOTE: represents call to OperationImp() in the Bridge's Implementor m_pFile->GetBufferPtr(CFile::bufferCommit, m_lpBufCur - m_lpBufStart); // ... (Lots of code here taken out for the sake of brevity } // ... (Lots of code here taken out for the sake of brevity }Commentary on the MFC Bridge Example
Be careful mistaking Strategy for Bridge. The two are similar in structure but quite different in purpose. Strategy is concerned with algorithms while Bridge deals with abstract interfaces and implementations which allow for varying behavior. -Joshua Kerievsky