为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
设计一个使用空格和星号绘制图形的工厂,该工厂可以根据用户选择绘制不同的图形(如矩形、三角形、菱形、平行四边形、梯形等)。
具体要求:
(1)至少能够绘制6种以上的图形。
(2)可以绘制的图形名称保存在文本文件中。
(3)根据用户选择设置图形参数绘制图形,并记录绘制了的图形的个数。
(4)显示已经绘制的图形的总数。
(1)WINDOWS2000/XP系统
(2)Visual C++ 6.0编译环境或DEV C++ 5.0编译环境
C++语言
系统要求设计一个使用空格和星号绘制图形的工厂,该工厂可以根据用户选择绘制至少6种以上不同的图形(如矩形、三角形、菱形、平行四边形、梯形等)。把可以绘制的图形名称保存在文本文件中,并实现根据用户选择设置图形参数绘制图形,并记录和显示绘制了的图形的个数。
利用文件流的打开、关闭及使用方法实现:把可以绘制的图形名称保存在文本文件中并显示在运行屏幕上。定义文件类infile类读取保存可以绘制的图形名称在文本文件shapeFactory.txt。
利用工厂模式的设计模式定义ShapeFactory工厂类,并定义抽象基类BaseShape类和7个具体图形派生类:直线Line(),梯形Echelon(),直角三角形RightTriangle(),等边三角形EquilateralTriangle(),矩形Rectangle(),正方形Square(),菱形Diamond(),构造绘制图形函数DrawShape()并调用,实现根据用户选择绘制图形。
源程序代码如下: // BaseShape.h文件 #include <iostream> using namespace std; class BaseShape { public: BaseShape() {}; virtual ~BaseShape() {}; virtual void DrawShape() = 0; }; //********************************* //ShapeFactory.h文件 #include <fstream> #include <string> #include "Point.h" #include "Line.h" #include "EquilateralTriangle.h" #include "RightTriangle.h" #include "Rectangle.h" #include "Square.h" #include "Diamond.h" #include "BaseShape.h" //定义工厂类 class ShapeFactory { public: ShapeFactory(); ~ShapeFactory(); //BaseShape* SelectShape(string); BaseShape* SelectShape(string shape) { if(shape=="Point" ||shape=="点") return new Point(); if(shape=="Line" || shape=="线") return new Line(); if(shape=="RightTriangle" || shape=="直角三角形") return new RightTriangle(); if(shape=="EquilateralTriangle" || shape=="等边三角形") return new EquilateralTriangle(); if(shape=="Rectangle" || shape=="矩形") return new Rectangle(); if(shape=="Square" || shape=="正方形") return new Square(); if(shape=="Diamond" || shape=="菱形") return new Diamond(); else cout<< "输入的图形名称错误!" <<endl; } }; // ShapeFactory.cpp文件 #include "ShapeFactory.h" ShapeFactory::ShapeFactory(void) { } ShapeFactory::~ShapeFactory(void) { } //******************************************** ///////////////////点Point///////////////////// // Point.h文件 #include "BaseShape.h" class Point : public BaseShape { private: int n; static int P; public: Point() {}; virtual ~Point() {}; virtual void DrawShape(); }; // Point.cpp文件 #include "Point.h" //绘制点 void Point::DrawShape() { static int P; cout<< "*"<<endl; P++; cout<<endl<< "^_^ 您已经绘制"<< P << "个点^_^ "<<endl; } //******************************************** // Line.h文件 ///////////////////直线Line///////////////////// #include "BaseShape.h" class Line : public BaseShape { private: int n; static int L; public: Line() {}; virtual ~Line() {}; //构造函数成员初始化列表,构造函数之后,函数体之前。 Line ( int n) : n(n) { } //覆盖抽象类的纯虚函数 virtual void DrawShape(); }; // Line.cpp文件 #include "Line.h" //绘制直线 void Line ::DrawShape() { int n; static int L; cout<< "请选择直线长度: " <<endl; cin>> n; for(int i=0; i<n; i++) { cout<< "*" ; } L++; cout<<endl<< "^_^ 您已经绘制"<< L << "条直线^_^ "<<endl; } //********************************************* // Diamond.h文件 ///////////////////菱形Diamond///////////////////// #include "BaseShape.h" class Diamond :public BaseShape { private: int n; static int D; public: Diamond(){}; virtual ~Diamond() {}; //构造函数成员初始化列表,构造函数之后,函数体之前。 Diamond ( int n) : n(n) { } //覆盖抽象类的纯虚函数 virtual void DrawShape(); }; // Diamond.cpp文件 #include "Diamond.h" //绘制菱形 void Diamond::DrawShape () { int n; static int D; cout<<"要得到的菱形的边长大小:"<<endl; cin>> n; ////////////上三角////////// for(int i=1;i<=n;++i) { for(int j=1;j<=n-i;++j) cout<<" "; for(j=1;j<=i;++j) cout<<"* "; cout<<endl; } //////////下三角/////////// for( i=n;i>=1;--i) { for(int j=1;j<=n-i;++j) cout<<" "; for(j=1;j<=i;++j) cout<<"* "; cout<<endl; } D++; cout<<endl<< "^_^ 您已经绘制"<< D << "个菱形^_^ "<<endl; } //********************************************* // EquilateralTriangle.h文件 ////////////////等边三角形EquilateralTriangle////////////////// #include "BaseShape.h" class EquilateralTriangle : public BaseShape { private: int n; static int ET; public: EquilateralTriangle() {}; virtual ~EquilateralTriangle() {}; //构造函数成员初始化列表,构造函数之后,函数体之前。 EquilateralTriangle ( int n) : n(n) { } //覆盖抽象类的纯虚函数 virtual void DrawShape(); }; // EquilateralTriangle.cpp文件. #include "EquilateralTriangle.h" //绘制等边三角形 void EquilateralTriangle::DrawShape() { int n; static int ET; cout<< "请选择输入要组成等边三角形的行数n(n>2):"; cin>>n; for(int i=1; i<n+1; i++) { //控制行数 //控制每行星号个数 for(int j=n-i; j>=0; j--) { cout<< " "; } for(int k=1; k<=2*i-1; k++) { cout<< "* "; } cout<<endl; } ET++; cout<<endl<< "^_^ 您已经绘制"<< ET << "个等边三角形^_^ "<<endl; } //********************************************* // Rectangle.h文件 ///////////////////矩形Rectangle///////////////////// #include "BaseShape.h" class Rectangle:public BaseShape { private: int width, height; static int R; public: Rectangle() {}; virtual ~Rectangle() {}; Rectangle( int width, int height) : width(width), height(height){ } virtual void DrawShape(); }; // Rectangle.cpp文件 #include "Rectangle.h" //绘制矩形 void Rectangle::DrawShape() { int width, height; static int R; cout<< "请选择输入矩形的长和宽: "; cin>> width >> height; cout<<endl; for (int i=1; i<=height; i++) { if (i==1 || i==height) {//输出长,即第一行和最后一行星号 for(int j=1; j<=width; j++) cout<< "* "; cout<<endl; } else { cout<< "*"; for(int j=2; j<=2*(width-2)+2; j++)//其中2*(side-2)+2为宽除星号外的空格数 cout<< " "; cout<< "*" <<endl; } } R++; cout<<endl<< "^_^ 您已经绘制"<< R << "个矩形^_^ "<<endl; } //********************************************* // RightTriangle.h文件 ///////////////////直角三角形RightTriangle ///////////////////// #include "BaseShape.h" class RightTriangle : public BaseShape { private: int n; static int RT; public: RightTriangle() {}; virtual ~RightTriangle() {}; //构造函数成员初始化列表,构造函数之后,函数体之前。 RightTriangle ( int n) : n(n) { } //覆盖抽象类的纯虚函数 virtual void DrawShape(); }; // RightTriangle.cpp文件 #include "RightTriangle.h" //绘制直角三角形 void RightTriangle::DrawShape() { int n; static int RT; cout<< "请选择输入要组成直角三角形的行数n(n>2):"; cin>>n; for(int i=0; i<n; i++) { //控制行数 for(int j=1; j<=i+1; j++)//控制每行星号个数 { cout<< "* "; } cout<<endl; } RT++; cout<<endl<< "^_^ 您已经绘制"<< RT << "个直角三角形^_^ "<<endl; } //********************************************* // Square.h文件 ///////////////////正方形Square///////////////////// #include "BaseShape.h" class Square : public BaseShape { private: int side; static int s; public: Square() {}; virtual ~Square() {}; Square ( int side) : side(side) { } virtual void DrawShape(); }; // Square.cpp文件 #include "Square.h" //绘制正方形 void Square::DrawShape() { static int s; int side; cout<< "请选择输入正方形的边长: "; cin>> side; cout<<endl; for (int i=1; i<=side; i++) { if (i==1 || i==side) {//输出长,即第一行和最后一行星号 for(int j=1; j<=side; j++) cout<< "* "; cout<<endl; } else { cout<< "*"; for(int j=2;j<=2*(side-2)+2;j++)//其中2*(side-2)+2为宽除星号外的空格数 cout<< " "; cout<< "*" <<endl; } } s++; cout<<endl<< "^_^ 您已经绘制"<< s << "个正方形^_^ "<<endl; } //********************************************* /* 设计一个使用空格和星号绘制图形的工厂,该工厂可以根据用户选择绘制不同的图形(如矩形?三角形?菱形?平行四边形?梯形等)? 具体要求: (1)至少能够绘制6种以上的图形? (2)可以绘制的图形名称保存在文本文件中? (3)根据用户选择设置图形参数绘制图形,并记录绘制了的图形的个数? (4)显示已经绘制的图形的总数? */ #include <fstream> #include <vector> #include <string> #include "Point.h" #include "Line.h" #include "EquilateralTriangle.h" #include "RightTriangle.h" #include "Rectangle.h" #include "Square.h" #include "Diamond.h" #include "BaseShape.h" #include "ShapeFactory.h" #include <iostream> using namespace std; int main() { /* 读infile类 的文件ShapeFactoryFile.txt中可绘制的图形并为每行加上"行号-",输出到运行屏幕上。 */ ifstream infile("ShapeFactoryFile.txt"); if(!infile) {//检验文件是否成功打开 cout<< "sorry! Unable to open ShapeFactoryFile. " <<endl; return -1; } string line; vector<string> text; while (getline(infile,line)) { text.push_back(line); } for(int j=0; j<text.size(); j++) cout<< j+1 << " - " << text[j] <<endl; cout<<endl << "*************以上是可以绘制的图形名***************" <<endl<<endl; //定义工厂对象、基类指针 ShapeFactory factory; BaseShape * pBaseShape; string shape; int t=0; while(true) { cout<<"请输入图形(英文或中文)名称(以#为结束程序): "; cin>>shape; if(shape=="#") break; BaseShape* pBaseShape=factory.SelectShape(shape);//选择具体类 pBaseShape->DrawShape();//调用具体类的画法 delete pBaseShape; t++; cout<< "您总共已经输出"<< t <<"个图形。" <<endl; } return 0; }