После статьи «ООП не мертво. Вы просто пользуетесь им как молотком по клавиатуре» комментарии кипели
Кто-то звал Smalltalk, кто-то бросал в нас Haskell, кто-то доставал из-под кровати подшивку статей «ECS лучше всего» — и всё это с праведной уверенностью.
Что ж…
Пора прекратить спор на словах. И начать спор в коде.
Code-Battle: MVP графического редактора
-
Задача: реализовать базовый графический редактор
-
Фигуры: точка, линия, круг, квадрат, прямоугольник, треугольник, ромб, овал
-
Функциональность: добавление фигур на канвас, отрисовка
Правила:
-
Один .cpp / .py / .exs / .c / .rs / .lisp / whatever файл
-
Язык и подход — любой
-
Главное: читаемость, понятность, архитектурная целостность
-
Пишите максимально просто, если надо — используйте псевдокод
-
MVP сейчас — фичи потом
-
Все решения оформляются одним Merge Request
-
В конце — разбор решений, сравнение подходов, и, как обычно: наказание невиновных и награждение непричастны
Для затравки: C++ / ООП реализация (v1)
В качестве точки отсчёта — наш базовый вариант.
ООП, без усложнений.
Всё в одном файле.
#include <iostream> #include <string> #include <vector> class Shape { public: virtual void draw() const = 0; virtual std::string name() const = 0; virtual ~Shape() {} }; class Point : public Shape { int x, y; public: Point(int x, int y) : x(x), y(y) {} void draw() const override { std::cout << «Drawing Point at (« << x << «, « << y << «)\\n»; } std::string name() const override { return «Point»; } }; class Circle : public Shape { int x, y, r; public: Circle(int x, int y, int r) : x(x), y(y), r(r) {} void draw() const override { std::cout << «Drawing Circle at (« << x << «, « << y << «), r = « << r << «\\n»; } std::string name() const override { return «Circle»; } }; class Rectangle : public Shape { int x, y, w, h; public: Rectangle(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {} void draw() const override { std::cout << «Drawing Rectangle at (« << x << «, « << y << «), « << w << «x» << h << «\\n»; } std::string name() const override { return «Rectangle»; } }; class Canvas { std::vector<Shape*> shapes; public: void add(Shape* s) { shapes.push_back(s); } void render() const { for (auto s : shapes) s->draw(); } ~Canvas() { for (auto s : shapes) delete s; } }; int main() { Canvas canvas; canvas.add(new Point(1, 1)); canvas.add(new Circle(5, 5, 3)); canvas.add(new Rectangle(0, 0, 6, 3)); canvas.render(); return 0; }
Теперь — вы.
Реализуйте то же самое:
-
На любом языке и в любой парадигме
-
В своей манере — функциональной, процедурной, декларативной, минималистской
-
Без фреймворков. Без магии. Только архитектура
Это только начало.
Следующая итерация уже в пути. Требования изменятся. Канвас расширится. Архитектура проявит себя.
А мы, разберём каждую реализацию — и, возможно, найдём ответ на вопрос:
«To OOP or not to OOP — вот в чем загвоздка”.
Репозитарий с правилами, шаблоном и инструкциями:
ссылка на оригинал статьи https://habr.com/ru/articles/909368/
Добавить комментарий