需求:設計一個繪製引擎,可以繪製不同的圖形(比如:Rectangle、Circle、Polygon等)。
目標:繪製引擎具有拓展性,易維護等特點。
思路:繪製不同的圖形的基本流程是一樣的,首先需要將圖形數據複製到特定的容器內,每個圖形類提供了一個繪製器,調用每個類型的繪製方法,傳入數據。繪製後的數據在特定的容器內,並且顯示的方法都是一樣(調用顯卡的驅動程序,把數據複製進去即可)
RectangleTraits.h
#include <iostream>
class RectangleType
{
public:
RectangleType()
{
}
static void GetDrawingType()
{
std::cout << "This a Renctangle!\n";
}
static RectangleType Clone()
{
return RectangleType();
}
static void PrepareData(char* ch )
{
std::cout << "Prepare Data for Rectangle Done!" << ch << "\n";
}
};
class RectangleDrawer
{
public:
static int Drawing()
{
std::cout << "Drawing a Renctangle!\n";
return 1;
}
};
class RectangleTraits
{
public:
typedef RectangleType shape_type;
typedef RectangleDrawer shape_drawer;
};
CircleTraits.h
#include <iostream>
class CircleType
{
public:
CircleType()
{
}
static void GetDrawingType()
{
std::cout << "This a Circle!\n";
}
static CircleType Clone()
{
return CircleType();
}
static void PrepareData(char* ch)
{
std::cout << "Prepare Data for Circle Done!"<< ch << "\n";
}
};
class CircleDrawer
{
public:
static int Drawing()
{
std::cout << "Drawing a Circle!\n";
return 2;
}
};
class CircleTraits
{
public:
typedef CircleType shape_type;
typedef CircleDrawer shape_drawer;
};
PolygonTraits.h
#include <iostream>
class PolygonType
{
public:
PolygonType()
{
}
static void GetDrawingType()
{
std::cout << "This a Polygon!\n";
}
static PolygonType Clone()
{
return PolygonType();
}
static void PrepareData(char* ch)
{
std::cout << "Prepare Data for Polygon Done!" << ch << "\n";
}
};
class PolygonDrawer
{
public:
static int Drawing()
{
std::cout << "Drawing a Polygon!\n";
return 0;
}
};
class PolygonTraits
{
public:
typedef PolygonType shape_type;
typedef PolygonDrawer shape_drawer;
};
main.cpp
#include <iostream>
#include "RectangleTraits.h"
#include "CircleTraits.h"
#include "PolygonTraits.h"
template <class ShapeTraits>
class DrawShape
{
public:
typedef typename ShapeTraits::shape_type ShapeType;//算法器提取的對應類型
typedef typename ShapeTraits::shape_drawer ShapeDrawer;//算法器提取的對應類型
static void Drawing()
{
// pearperData
char ch[] = "Yes";
ShapeType::PrepareData(ch);
// drawing
int ret = ShapeDrawer::Drawing();
// sucessful
std::cout << ret << "\n";
// display
}
};
class Shape
{
public:
void Draw()
{
OnDraw();
}
protected:
virtual void OnDraw() = 0;
};
class RenctangleShape : public Shape
{
protected:
void OnDraw()
{
DrawShape<RectangleTraits>::Drawing();
}
};
class CircleShape : public Shape
{
protected:
void OnDraw()
{
DrawShape<CircleTraits>::Drawing();
}
};
class PolygonShape : public Shape
{
protected:
void OnDraw()
{
DrawShape<PolygonTraits>::Drawing();
}
};
enum ShapeType
{
ShapeType_Rectangle = 0,
ShapeType_Circle = 1,
ShapeType_Polygon = 2,
ShapeType_Count = ShapeType_Polygon + 1,
};
int main()
{
Shape* sh[ShapeType_Count - 1];
sh[ShapeType_Rectangle] = new RenctangleShape();
sh[ShapeType_Circle] = new CircleShape();
sh[ShapeType_Polygon] = new PolygonShape();
for (int i = 0; i < ShapeType_Count; ++i)
{
sh[i]->Draw();
}
return 0;
}