Problems with applying Strategy Pattern in C++
Hi I am applying Strategy pattern in C++. Please ingnore some classes
here which are MFC(Microsoft Foundation Class) specific.
Following is my class:
class CChart {
public:
CChart(CRenderingPropertyPage *pPage, CGraphPropertySheet
*pGraphPropertySheet, CString csTitle, CString csXAxisTitle,
CString csYAxisTitle, CStrategy *pStrategy, int
nChartCounter, int
nArrayIndex);
virtual ~CChart();
void DrawChart(CDC *pDC, CRect & rectClip);
private:
int m_ChartHorzSize;
int m_ChartVertSize;
public:
CString m_csTitle;
private:
CString m_csXAxisTitle;
CString m_csYAxisTitle;
CGraphPropertySheet *m_pGraphPropertySheet;
CStrategy *m_pStrategy;
CBitmap m_NormalBitmap;
CRenderingPropertyPage *m_pParent;
CRect m_BoundingRect;
int m_ChartCounter;
int m_ArrayIndex;
public:
//Accessors
int GetChartWidth() const
{
return m_ChartHorzSize;
}
void SetChartWidth(int size)
{
m_ChartHorzSize = size;
}
int GetChartHeight() const
{
return m_ChartVertSize;
}
void SetChartHeight(int size)
{
m_ChartVertSize = size;
}
const CString & GetTitle() const
{
return m_csTitle;
}
const CString & GetXAxisTitle() const
{
return m_csXAxisTitle;
}
const CString & GetYAxisTitle() const
{
return m_csYAxisTitle;
}
const CGraphPropertySheet & GetGraphPropertySheet() const
{
return *m_pGraphPropertySheet;
}
CStrategy * GetStrategy()
{
return m_pStrategy;
}
CBitmap * GetNormalBitmap()
{
return &m_NormalBitmap;
}
const CRenderingPropertyPage & GetParentPage() const
{
return *m_pParent;
}
const CRect & GetBoundingRect() const
{
return m_BoundingRect;
}
int GetChartCounter() const
{
return m_ChartCounter;
}
int GetArrayIndex() const
{
return m_ArrayIndex;
}
};
class CStrategy
{
protected:
double NonVirCalculateMax(const CArray<double, double> & pData);
double NonVirCalculateMin(const CArray<double, double> & pData);
void BaseDraw(CDC *pDC);
void BlitToScreen(CDC *pDCSrc, CDC *pDCDest, CRect *rectClip);
protected:
double scaleX;
double scaleY;
double max;
double min;
double XOrigin;
double YOrigin;
double m_BiggerMaxMin;
double m_YPointsArray[11];
CStringList m_YValuesList;
double *m_pXPointsArray;
CStringList m_XValuesList;
public:
virtual void CalculateScales() = 0;
virtual void CalculateMax() = 0;
virtual void CalculateMin() = 0;
friend class CChart;
public:
CStrategy(void);
virtual void OnDraw(CDC *pDC, CRect & rectClip) = 0;
public:
virtual ~CStrategy(void);
void CleanUp();
protected:
CChart *m_pChart;
};
//One of the strategies implemented
class CAccResponseLogSpectraStrategy :
public CStrategy
{
public:
CAccResponseLogSpectraStrategy(void);
public:
~CAccResponseLogSpectraStrategy(void);
public:
virtual void CalculateScales();
virtual void CalculateMax();
virtual void CalculateMin();
virtual void OnDraw(CDC *pDC, CRect & rectClip);
private:
CArray<double, double> m_LogPsuAccArray;
CArray<double, double> m_LogPeriodArray;
};
I have a CChart class. The charts differ from each other only in how
they are drawn. So I thought Strategy Pattern would hold good here.
Only the drawing algorithm differs.
I use the member variables of the CChart class in the OnDraw function.
I need quite a few members so I thought if the base strategy class
(CStrategy) should hold a pointer (m_pChart) to the CChart object it
would be easier than passing a lot of variables to the OnDraw
function.
Some how I don't feel right. I feel like I have made the chart class
naked. I feel providing the access to the member variables of the
Chart class through the Get/Set function is not better than providing
public variables.
To avoid the above, I thought of using private variables and making
the CStrategy class a friend of CChart class. But this doesn't work.
Only the base strategy class (CStrategy) will become a friend but not
the derived classes like CAccResponseLogSpectraStrategy.
I had posted the exact problem in one of the forums I visit. Luckily
one of my forum colleagues proposed a nice solution.
To apply another abstraction.
class IFriendlyChartInterface
{
public:
virtual int GetChartWidth() = 0;
virtual void SetChartWidth(int) = 0;
};
Now I derive my CChart class from IFriendlyChartInterface class:
class CChart : public IFriendlyChartInterface
{
..........
..........
private:
virtual int GetChartWidth();
virtual void SetChartWidth(int);
};
Note this way I am able to make implementation of GetChartWidth() and
SetChartWidth(int) private in the CChart class. I think this is a
better design but still not sure. So here I am asking you how can I
improve my design or if there are other alternatives. Using templates
with policies (compile time polymorphism) isn't my option since I
require run-time polymorphism.
One deep fear that I have is whether this is a case to apply Strategy
at all.
Any suggestions and comments, example code snippets are welcome.
Thankyou.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]