Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 11.04.2024, 17:59
Аспирант
Отправить личное сообщение для firep91613 Посмотреть профиль Найти все сообщения от firep91613
 
Регистрация: 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()
    };
  }
}

На сколько оправдан такой код с точки зрения ООП? И как лучше сделать?
Ответить с цитированием
  #2 (permalink)  
Старый 12.04.2024, 08:11
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

С точки зрения ООП, главное - как это потом будет использоваться. Какие будут объекты и какие действия (методы) с ними будут производиться.

Например. Предполагается ли у этих объектов метод перемещения объекта (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 элемента?

Какой вообще смысл хранить координаты и прочие свойства элемента, если их всегда можно получить из атрибутов? Ведь при выполнении каких то действий с объектом их надо будет синхронизировать - менять и там и там. Легко сделать ошибку.

Ну вот такие мысли.
Главное - как использовать. От этого зависит, что и как делать.
Ответить с цитированием
  #3 (permalink)  
Старый 12.04.2024, 08:23
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

ЗЫ Для стрелок, обычно элемент <marker> используют
https://developer.mozilla.org/en-US/...Element/marker
Ответить с цитированием
  #4 (permalink)  
Старый 12.04.2024, 14:07
Аспирант
Отправить личное сообщение для roland Посмотреть профиль Найти все сообщения от roland
 
Регистрация: 02.11.2023
Сообщений: 30

Я вижу здесь проблему в мотивации рефакторинга. Человек сразу обозначает свою проблему:
Сообщение от firep91613 Посмотреть сообщение
Сейчас у меня в файле класса рисовалки почти 300 строк кода. Я уже путаюсь что и где.

И то, как пытается свою проблему решить:
Сообщение от firep91613 Посмотреть сообщение
Решил сделать отдельные классы для каждого элемента. Думаю, еще классы раскидать по разным файлам.

Судя по представленному кода, после создания элементов дальнейшие манипуляции с ними через экземпляры классов не предполагаются, а значит и смысла в вынесении их отрисовки в отдельные классы я не вижу.

Проблема не в ООП, а в удобстве чтения кода в одном классе. Это вопрос относится к знанию своего редактора кода и навыкам навигации по коду.

Конечно, это не исключает "странностей" в виде функций create, названия методов или функциональности класса Arrow, который возвращает объект с составными частями элемента, а не единый цельный элемент, но эти проблемы не исправить оборачиванием методов в классы.

Последний раз редактировалось roland, 12.04.2024 в 14:14.
Ответить с цитированием
  #5 (permalink)  
Старый 12.04.2024, 16:17
Аспирант
Отправить личное сообщение для firep91613 Посмотреть профиль Найти все сообщения от firep91613
 
Регистрация: 24.10.2023
Сообщений: 58

voraa,
перемещение и изменение цвета не предполагается. Координаты считаются в зависимости от количества элементов и т.д.
Сообщение от voraa
ЗЫ Для стрелок, обычно элемент <marker> используют
https://developer.mozilla.org/en-US/...Element/marker
Как все просто

Сообщение от roland
Судя по представленному кода, после создания элементов дальнейшие манипуляции с ними через экземпляры классов не предполагаются, а значит и смысла в вынесении их отрисовки в отдельные классы я не вижу.
То есть все методы оставить в классе рисовалки?

Сообщение от roland
Проблема не в ООП, а в удобстве чтения кода в одном классе. Это вопрос относится к знанию своего редактора кода и навыкам навигации по коду.
Я просто занимаюсь этим не каждый день. И потом чтобы вспомнить, что там навоял приходится скролить, смотреть, что и как.

Просто я устал скролить по всему этому коду. Вот и хочу вынести в отдельные файлы с классами отдельных элементов.
Ответить с цитированием
  #6 (permalink)  
Старый 12.04.2024, 16:58
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Сообщение от 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.
Ответить с цитированием
  #7 (permalink)  
Старый 12.04.2024, 17:48
Аспирант
Отправить личное сообщение для firep91613 Посмотреть профиль Найти все сообщения от firep91613
 
Регистрация: 24.10.2023
Сообщений: 58

Сообщение от voraa
А какой смысл тогда хранить в объекте эти координаты, если после создания элемента они больше никак не используются?
Если с созданными объектами не предполагается производить какие то действия, то зачем тут вообще ООП?
Сделайте просто функции, которые создают элемент
Ну да, вы правы. Пожалуй так и сделаю. Спасибо.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна помощь!Я нубище, нужен совет! IgorProkonchyk Оффтопик 2 01.10.2017 21:09
Мой первый скрипт. Нужен совет! ArtemBielykh Элементы интерфейса 2 20.01.2017 22:26
Нужен совет по верхней плашке :) espltd Элементы интерфейса 13 27.05.2016 14:30
Выделение активного пункта меню. Нужен совет! kirian222 Элементы интерфейса 14 17.10.2013 02:50
Нужен совет по Tabpanel GuardNW ExtJS 0 17.07.2011 15:07