From 6a92fed6acd10f0e7ea121c94089e02fe8bd39ad Mon Sep 17 00:00:00 2001 From: Boris Date: Sat, 30 Sep 2017 19:34:14 +0200 Subject: [PATCH] commit initial and refactored code --- README.md | 5 +- initialCode.cpp | 74 +++++++++++++++++++++++++++++ refactoredCode.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 initialCode.cpp create mode 100644 refactoredCode.cpp diff --git a/README.md b/README.md index 3a3da5d..8f2f9f3 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -# RefactoringTest \ No newline at end of file +# RefactoringTest + +The file initialCode.cpp was given and had to be improved and refactored into +the file refactoredCode.cpp . diff --git a/initialCode.cpp b/initialCode.cpp new file mode 100644 index 0000000..4cc127d --- /dev/null +++ b/initialCode.cpp @@ -0,0 +1,74 @@ + +Refactor the code. + +Paste your solution here or provide a link to the Github repository. + + +#include + +class Feature +{ +public: + enum FeatureType {eUnknown, eCircle, eTriangle, eSquare}; + + Feature() : type(eUnknown), points(0) { } + + ~Feature() + { + if (points) + delete points; + } + + bool isValid() + { + return type != eUnknown; + } + + bool read(FILE* file) + { + if (fread(&type, sizeof(FeatureType), 1, file) != sizeof(FeatureType)) + return false; + short n = 0; + switch (type) + { + case eCircle: n = 3; break; + case eTriangle: n = 6; break; + case eSquare: n = 8; break; + default: type = eUnknown; return false; + } + points = new double[n]; + if (!points) + return false; + return fread(&points, sizeof(double), n, file) == n*sizeof(double); + } + void draw() + { + switch (type) + { + case eCircle: drawCircle(points[0], points[1], points[2]); break; + case eTriangle: drawPolygon(points, 6); break; + case eSquare: drawPolygon(points, 8); break; + } + } + +protected: + void drawCircle(double centerX, double centerY, double radius); + void drawPolygon(double* points, int size); + + double* points; + FeatureType type; +}; + +int main(int argc, char* argv[]) +{ + Feature feature; + FILE* file = fopen("features.dat", "r"); + feature.read(file); + if (!feature.isValid()) + return 1; + return 0; +} + +Refactor the code. + +Paste your solution here or provide a link to the Github repository. diff --git a/refactoredCode.cpp b/refactoredCode.cpp new file mode 100644 index 0000000..467e8ee --- /dev/null +++ b/refactoredCode.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include + +class Feature +{ +public: + Feature() { + fillDataFactory[eCircleStorage] = std::make_unique >(); + fillDataFactory[ePolygoneStorage] = std::make_unique >(); + } + + enum FeatureType {eUnknown, eCircle, eTriangle, eSquare}; + enum StorageType { eCircleStorage, ePolygoneStorage}; + + StorageType convertFeatureToStorageType(FeatureType aFeatureType) { return aFeatureType == eCircle ? eCircleStorage : ePolygoneStorage;} + + bool isValid() const { + return figure ? true : false; + } + + bool read(FILE* file) + { + FeatureType type; + if (fread(&type, sizeof(FeatureType), 1, file) != sizeof(FeatureType)) { + return false; + //it was unclear for me if the eUknown should invalidate the figure that was already + //loaded in the class. I assumed that it shouldnt. + } + auto it = figure_sizes.find(type); + if(it == figure_sizes.end()){ + return false; + } + try { + Tpoints_ptr points(new double[it->second]); + if( fread(points.get(), sizeof(double), it->second, file) == it->second*sizeof(double));{ + fillDataFactory.at(convertFeatureToStorageType(type))->initfFigure(figure, std::move(points), it->second); + } + } catch(std::bad_alloc& ba) + { + return false; + } + + } + + void draw() { + if(figure) { + figure->draw(); + } + } + +private: + typedef std::unique_ptr Tpoints_ptr; + + class BaseFigure { + public: + BaseFigure(Tpoints_ptr aPoints, size_t aSize) : points(std::move(aPoints)), size_points(aSize) {} + + virtual void draw() const = 0; + + protected: + size_t size_points; + Tpoints_ptr points; + }; + + class Circle : public BaseFigure { + public: + Circle(Tpoints_ptr aPoints, size_t aSize):BaseFigure(std::move(aPoints), aSize){} + + virtual void draw() const { + drawCircle(points[0], points[1], points[2]); + } + private: + void drawCircle(double centerX, double centerY, double radius) const; + }; + + class Polygone : public BaseFigure { + public: + Polygone(Tpoints_ptr aPoints, size_t aSize):BaseFigure(std::move(aPoints), aSize){} + virtual void draw() const { + drawPolygon(points.get()), size_points); + } + private: + void drawPolygon(double* points, int size) const; + }; + + class DummyFactoryBase { + public: + virtual void initfFigure(std::unique_ptr&, Tpoints_ptr, size_t) = 0; + }; + + template + class Factory : public DummyFactoryBase { + public: + void initfFigure(std::unique_ptr& figure, Tpoints_ptr my_ptr, size_t size) { + figure.reset(new T(std::move(my_ptr), size)); + } + }; + +protected: + const std::map figure_sizes {{eCircle,3} ,{eTriangle,6} , {eSquare,8}}; + std::map > fillDataFactory; + std::unique_ptr figure; +}; + +int main(int argc, char* argv[]) +{ + Feature feature; + FILE* file = fopen("features.dat", "r"); + feature.read(file); + if (!feature.isValid()) + return 1; + return 0; +}