ООП. Нужен совет.
Делаю рисовалку на SVG. Сейчас у меня в файле класса рисовалки почти 300 строк кода. Я уже путаюсь что и где. Решил сделать отдельные классы для каждого элемента. Думаю, еще классы раскидать по разным файлам. До этого эти классы были методами класса рисовалки.
Пример: class Circle { constructor(x, y, r = 20, c = '#7F6565') { this.x = x; this.y = y; this.radius = r; this.color = c; } create() { const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); circle.setAttribute('r', this.radius); circle.setAttribute('cx', this.x); circle.setAttribute('cy', this.y); circle.setAttribute('fill', this.color); circle.setAttribute('stroke-width', 1); return circle; } } class Line { constructor(x1, y1, x2, y2, c = 'black') { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.color = c; } create() { const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', this.x1); line.setAttribute('y1', this.y1); line.setAttribute('x2', this.x2); line.setAttribute('y2', this.y2); line.setAttribute('stroke', this.color); return line; } } class Arrow { constructor(x1, y1, x2, y2, c = 'black') { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.color = c; } create() { const lineLength = (Math.abs(this.x1 - this.x2) ** 2 + Math.abs(this.y1 - this.y2) ** 2) ** 0.5; const cos = (this.x2 - this.x1) / lineLength; const angle = (this.y1 >= this.y2) ? Math.acos(cos) : Math.PI + (Math.PI - Math.acos(cos)); const arrowLength = 15; const arrowAngle = Math.PI / 12; const moreAngle = angle + arrowAngle; const moreAngleX = this.x2 - Math.cos(moreAngle) * arrowLength; const moreAngleY = this.y2 + Math.sin(moreAngle) * arrowLength; const moreAngleLine = new Line(this.x2, this.y2, moreAngleX, moreAngleY); const lessAngle = angle - arrowAngle; const lessAngleX = this.x2 - Math.cos(lessAngle) * arrowLength; const lessAngleY = this.y2 + Math.sin(lessAngle) * arrowLength; const lessAngleLine = new Line(this.x2, this.y2, lessAngleX, lessAngleY); return { moreAngleLine: moreAngleLine.create(), lessAngleLine: lessAngleLine.create() }; } } На сколько оправдан такой код с точки зрения ООП? И как лучше сделать? |
С точки зрения ООП, главное - как это потом будет использоваться. Какие будут объекты и какие действия (методы) с ними будут производиться.
Например. Предполагается ли у этих объектов метод перемещения объекта (move)? или изменение цвета (color)? Например const c = new Circle(100, 200, 50); c.move(200, 300).color('red') А как вы реализуете эти методы? Просто поменять координаты в объекте ничего не даст. Надо менять атрибуты у элемента. А где у вас связь между объектом и элементом? У какого элемента менять, если он никак не запомнен в объекте. В чем смысл метода create? Что дает просто создание объекта (new Line (100, 200, 200, 300);) ,без вызова create()? А если вызвать create много раз? const l = new Line (100, 200, 200, 300); l.create(); l.create(); l.create(); Это так и задумывалось, что будут созданы 3 элемента? Какой вообще смысл хранить координаты и прочие свойства элемента, если их всегда можно получить из атрибутов? Ведь при выполнении каких то действий с объектом их надо будет синхронизировать - менять и там и там. Легко сделать ошибку. Ну вот такие мысли. Главное - как использовать. От этого зависит, что и как делать. |
ЗЫ Для стрелок, обычно элемент <marker> используют
https://developer.mozilla.org/en-US/...Element/marker |
Я вижу здесь проблему в мотивации рефакторинга. Человек сразу обозначает свою проблему:
Цитата:
И то, как пытается свою проблему решить: Цитата:
Судя по представленному кода, после создания элементов дальнейшие манипуляции с ними через экземпляры классов не предполагаются, а значит и смысла в вынесении их отрисовки в отдельные классы я не вижу. Проблема не в ООП, а в удобстве чтения кода в одном классе. Это вопрос относится к знанию своего редактора кода и навыкам навигации по коду. Конечно, это не исключает "странностей" в виде функций create, названия методов или функциональности класса Arrow, который возвращает объект с составными частями элемента, а не единый цельный элемент, но эти проблемы не исправить оборачиванием методов в классы. |
voraa,
перемещение и изменение цвета не предполагается. Координаты считаются в зависимости от количества элементов и т.д. Цитата:
Цитата:
Цитата:
Просто я устал скролить по всему этому коду. Вот и хочу вынести в отдельные файлы с классами отдельных элементов. |
Цитата:
Цитата:
Цитата:
Если с созданными объектами не предполагается производить какие то действия, то зачем тут вообще ООП? Сделайте просто функции, которые создают элемент function Circle (x, y, r = 20, c = '#7F6565') { const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); circle.setAttribute('r', r); circle.setAttribute('cx', x); circle.setAttribute('cy', y); circle.setAttribute('fill', c); circle.setAttribute('stroke-width', 1); return circle; } |
Цитата:
|
Часовой пояс GMT +3, время: 20:07. |