Re[4]: Объясняем наследование
От: Tesh США  
Дата: 10.11.14 19:10
Оценка: +1
Здравствуйте, vpchelko, Вы писали:

V>Ну да для конечного пользователя — это просто List — интерфейс.


Только в одном случае быстрый доступ, а в остальных весьма медленный с возможными проблемами с сетью/БД.
Re[3]: Объясняем наследование
От: Tesh США  
Дата: 10.11.14 19:19
Оценка:
Здравствуйте, Tilir, Вы писали:

Можно не ограничивать людей и предложить им написать что угодно с использованием ООП. Хоть игру
Re[9]: Объясняем наследование
От: Dufrenite Дания  
Дата: 11.11.14 06:19
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вот это меня опять настораживает. Я имею в виду — ввод паттернов на ровном месте.


Даже не знаю что ответить. Чем вас паттерны настораживают?

S>Ух ты ж блин! Сколько всего. И всё это вместо пары классов Path и Canvas.

S>Круто, чё.

Вы всю логику хотите в 2 класса поместить? Видал я классы по 5000 строк, но уверяю что это неверный путь.

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

S>Вынужден поверить вам на слово, хотя сам такого не видел.

Логически подумайте. Чем больше разнообразных задач вы навесите на иерархию, тем больше в ней будет нестыковок, костылей и компромиссов.

Идеально разнести задачи по разным классам или иерархиям. В этом случае понимание кода сильно упрощается.

S>А какой код и сколько нам потребуется в ShapeDrawer? Я же правильно понял, что в нём будет по методу на каждого потомка Shape?


Верно. Всё, что связано с рисованием будет в нём.

S>Простите, но такой код хорош только для списания затрат по time spent basis.

S>Для реальной работы надо минимизировать усилия. В вашем коде стоимость добавления новой фигуры — запредельна.

Добавление одного метода из 10 строк для вас запредельная сложность?
Re[10]: Объясняем наследование
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.11.14 07:00
Оценка: +1
Здравствуйте, Dufrenite, Вы писали:
D>Даже не знаю что ответить. Чем вас паттерны настораживают?
Тем же самым — паттерн должен вводиться не как самоцель, а как решение какой-то задачи. Причём так, что "без паттерна" решение получается хуже по объективным характеристикам.

D>Вы всю логику хотите в 2 класса поместить? Видал я классы по 5000 строк, но уверяю что это неверный путь.

В данном случае двух классов вполне достаточно. В вашем решении банально больше строк — то есть больше объём работы по тестированию, больше шансов сделать ошиююку.

D>Логически подумайте. Чем больше разнообразных задач вы навесите на иерархию, тем больше в ней будет нестыковок, костылей и компромиссов.

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

D>Идеально разнести задачи по разным классам или иерархиям. В этом случае понимание кода сильно упрощается.


S>>А какой код и сколько нам потребуется в ShapeDrawer? Я же правильно понял, что в нём будет по методу на каждого потомка Shape?


D>Верно. Всё, что связано с рисованием будет в нём.


S>>Простите, но такой код хорош только для списания затрат по time spent basis.

S>>Для реальной работы надо минимизировать усилия. В вашем коде стоимость добавления новой фигуры — запредельна.
D>Добавление одного метода из 10 строк для вас запредельная сложность?
С чего это "одного"? В вашем решении мне нужно:
1. Добавить новый класс фигуры. Сколько в нём будет строк кода?
2. Добавить новый метод в IShapeVisitor
3. Добавить новый метод в каждую реализацию IShapeVisitor. В вашем примере их две.

В моём решении единственное, что потребуется добавить во весь проект — это как раз один метод.
Примерно вот так:
public static Path CreateRightAngleTriangle(Pen pen, Point corner, int height, int width)
{
  return Path.CreateClosedPath(pen, corner, corner + new Offset(0, -height), corner + new Offset(width, 0));
}

Всё. А теперь приведите мне тот код, который потребуется написать в вашем проекте, чтобы заработали прямоугольные треугольники.
Если я попрошу вас научить вашу программу поворачивать Shape на произвольный угол, то вы мгновенно утонете в коде. А у меня добавится ровно один метод Path RotatePath(Path original, double angle). Никакого полиморфизма, никакого размазывания изменений по всем файлам проекта, минимум риска сделать ошибку.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Объясняем наследование
От: Dufrenite Дания  
Дата: 11.11.14 07:23
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Тем же самым — паттерн должен вводиться не как самоцель, а как решение какой-то задачи. Причём так, что "без паттерна" решение получается хуже по объективным характеристикам.


В данном случае паттерны сильно упрощают жизнь.

S>Не вижу никакой логики, равно как и причин, по которым вы предлагаете мне навесить на единую иерархию множество разнообразных задач.

S>Проектирование от поведения совершенно не об этом.

Ну вы же не думаете, что развитие вашей программы ограничится простым отображением фигур на экране?

S>С чего это "одного"? В вашем решении мне нужно:

S>1. Добавить новый класс фигуры. Сколько в нём будет строк кода?
S>2. Добавить новый метод в IShapeVisitor
S>3. Добавить новый метод в каждую реализацию IShapeVisitor. В вашем примере их две.

Вам в любом случае придётся как-то эту функциональность реализовать.

S>В моём решении единственное, что потребуется добавить во весь проект — это как раз один метод.

S>Примерно вот так:
S>
S>public static Path CreateRightAngleTriangle(Pen pen, Point corner, int height, int width)
S>{
S>  return Path.CreateClosedPath(pen, corner, corner + new Offset(0, -height), corner + new Offset(width, 0));
S>}
S>


S>Всё. А теперь приведите мне тот код, который потребуется написать в вашем проекте, чтобы заработали прямоугольные треугольники.

S>Если я попрошу вас научить вашу программу поворачивать Shape на произвольный угол, то вы мгновенно утонете в коде. А у меня добавится ровно один метод Path RotatePath(Path original, double angle). Никакого полиморфизма, никакого размазывания изменений по всем файлам проекта, минимум риска сделать ошибку.

Вы ошибаетесь. Я добавлю в класс Shape матрицу трансформации. Соответственно в методе DrawLines появляется ещё один параметр.

А теперь я вас попрошу внести в ваше решение маленькое изменение: пусть квадрат заливается текстурой, которую я назначил. А ещё я хочу, чтобы вокруг треугольника отображалось гало. А ещё хочу экспорт 3D моделей из 3D Studio Max. И ещё чтобы можно было крутить в трёх измерениях. И экспортировать в популярные форматы, включая PDF.

Дальше продолжать?
Re[12]: Объясняем наследование
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.11.14 16:29
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Вам в любом случае придётся как-то эту функциональность реализовать.

Функциональность — да. А вот весь код ради кода (т.е. визиторы, override, и прочий мусор) — нет, не придётся.

D>Вы ошибаетесь. Я добавлю в класс Shape матрицу трансформации. Соответственно в методе DrawLines появляется ещё один параметр.

Матрицу-то вы добавите. А как вы предполагаете её использовать и где? Пример кода — в студию.
Мой — вот он:
public static Path RotatePath(Path original, double angle)
{
  var m = TransformMatrix.CreateRotationMatrix(angle);
  var rotatatedSegments = from s in original.Segments select m.Transform(s);
  return new Path(rotatedSegments);
}

подразумеваем, естественно, что мы написали хелпер-метод
public static PathSegment Transform(this TransformMatrix m, PathSegment segment)
{
  var s = segment.Clone();
  s.Point1 = m.Transform(s.Point1);
  s.Point2 = m.Transform(s.Point2);
  return s;
}

D>А теперь я вас попрошу внести в ваше решение маленькое изменение: пусть квадрат заливается текстурой, которую я назначил.
Без проблем. Мы просто добавим в наш единственный метод DrawPath(Path path) опциональный параметр Brush fill.
И забесплатно получим возможность заливать текстурами не только квадраты, а и треугольники, и прямоугольники, и все будущие фигуры.

D>А ещё я хочу, чтобы вокруг треугольника отображалось гало.

Подход — такой же. Придумываем параметры гало (скорее всего цвет, насыщенность, и поперечник), и добавляем метод, который их использует.

D>А ещё хочу экспорт 3D моделей из 3D Studio Max. И ещё чтобы можно было крутить в трёх измерениях.

Ну, для начала придётся перейти от Path к 3dSurface. Затем принять решение, что из данных 3DS нам будет интересно — там, вообще-то, дохрена всего. С учётом того, что это — параметрический 3d-аниматор, а не просто "рисовалка 3d моделей".
А уже затем мы напишем совершенно отдельный от всего код лоадера 3DS, который будет читать файлы и отдавать те объекты, которые нам интересны.

D>И экспортировать в популярные форматы, включая PDF.

Ну, экспорт в PDF нам будет доступен забесплатно, потому что есть готовые экспортилки, которые реализуют тот же самый Canvas (он же DeviceContext), который мы использовали в нашем методе DrawPath.

D>Дальше продолжать?

Да сколько угодно. Я только по-прежнему не понимаю, как тут поможет ваша иерархия Shape и иерархия Visitor.
Во всех этих задачах она будет только путаться под ногами. И будет существенно усложнять процесс добавления нового Shape в проект.

Если вы собираетесь мне возразить, то будьте любезны привести пример кода.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.