11.04.2024, 17:59
|
Аспирант
|
|
Регистрация: 24.10.2023
Сообщений: 58
|
|
ООП. Нужен совет.
Делаю рисовалку на 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()
};
}
}
На сколько оправдан такой код с точки зрения ООП? И как лучше сделать?
|
|
12.04.2024, 08:11
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,743
|
|
С точки зрения ООП, главное - как это потом будет использоваться. Какие будут объекты и какие действия (методы) с ними будут производиться.
Например. Предполагается ли у этих объектов метод перемещения объекта (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 элемента?
Какой вообще смысл хранить координаты и прочие свойства элемента, если их всегда можно получить из атрибутов? Ведь при выполнении каких то действий с объектом их надо будет синхронизировать - менять и там и там. Легко сделать ошибку.
Ну вот такие мысли.
Главное - как использовать. От этого зависит, что и как делать.
|
|
12.04.2024, 08:23
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,743
|
|
|
|
12.04.2024, 14:07
|
Аспирант
|
|
Регистрация: 02.11.2023
Сообщений: 30
|
|
Я вижу здесь проблему в мотивации рефакторинга. Человек сразу обозначает свою проблему:
Сообщение от firep91613
|
Сейчас у меня в файле класса рисовалки почти 300 строк кода. Я уже путаюсь что и где.
|
И то, как пытается свою проблему решить:
Сообщение от firep91613
|
Решил сделать отдельные классы для каждого элемента. Думаю, еще классы раскидать по разным файлам.
|
Судя по представленному кода, после создания элементов дальнейшие манипуляции с ними через экземпляры классов не предполагаются, а значит и смысла в вынесении их отрисовки в отдельные классы я не вижу.
Проблема не в ООП, а в удобстве чтения кода в одном классе. Это вопрос относится к знанию своего редактора кода и навыкам навигации по коду.
Конечно, это не исключает "странностей" в виде функций create, названия методов или функциональности класса Arrow, который возвращает объект с составными частями элемента, а не единый цельный элемент, но эти проблемы не исправить оборачиванием методов в классы.
Последний раз редактировалось roland, 12.04.2024 в 14:14.
|
|
12.04.2024, 16:17
|
Аспирант
|
|
Регистрация: 24.10.2023
Сообщений: 58
|
|
voraa,
перемещение и изменение цвета не предполагается. Координаты считаются в зависимости от количества элементов и т.д. Как все просто
Сообщение от roland
|
Судя по представленному кода, после создания элементов дальнейшие манипуляции с ними через экземпляры классов не предполагаются, а значит и смысла в вынесении их отрисовки в отдельные классы я не вижу.
|
То есть все методы оставить в классе рисовалки?
Сообщение от roland
|
Проблема не в ООП, а в удобстве чтения кода в одном классе. Это вопрос относится к знанию своего редактора кода и навыкам навигации по коду.
|
Я просто занимаюсь этим не каждый день. И потом чтобы вспомнить, что там навоял приходится скролить, смотреть, что и как.
Просто я устал скролить по всему этому коду. Вот и хочу вынести в отдельные файлы с классами отдельных элементов.
|
|
12.04.2024, 16:58
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,743
|
|
Сообщение от firep91613
|
Как все просто
|
Это действительно не сложно. Сделал один маркер и используешь везде, где нужно.
Сообщение от firep91613
|
То есть все методы оставить в классе рисовалки?
|
Самой рисовалки не видно. Нет методов, которые добавляют эти элементы в DOM.
Сообщение от firep91613
|
перемещение и изменение цвета не предполагается.
|
А какой смысл тогда хранить в объекте эти координаты, если после создания элемента они больше никак не используются?
Если с созданными объектами не предполагается производить какие то действия, то зачем тут вообще ООП?
Сделайте просто функции, которые создают элемент
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;
}
Последний раз редактировалось voraa, 12.04.2024 в 17:12.
|
|
12.04.2024, 17:48
|
Аспирант
|
|
Регистрация: 24.10.2023
Сообщений: 58
|
|
Сообщение от voraa
|
А какой смысл тогда хранить в объекте эти координаты, если после создания элемента они больше никак не используются?
Если с созданными объектами не предполагается производить какие то действия, то зачем тут вообще ООП?
Сделайте просто функции, которые создают элемент
|
Ну да, вы правы. Пожалуй так и сделаю. Спасибо.
|
|
|
|