Re[2]: Трудные для ООП иерархии классов
От: deniok Россия  
Дата: 22.09.07 10:52
Оценка:
Здравствуйте, mrozov, Вы писали:

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


Система взглядов эксперта в предметной области может оказаться довольно наивной и слабосовместимой с системой взглядов эксперта другой области. Если уж мы допускаем эксперта до ЯП, то это должен быть специализированный (e)DSL + визуальная среда, а никак не язык общего назначения. Что мы собственно и видим: VBA для офисных автоматизаторов, TeX/LaTeX для писателей научных статей, AutoLisp для труженников AutoCad, SQL для БДкопателей, встроенные языки математических пакетов для научных расчетов.

В языке общего назначения всегда слишком много инструментов для поддержки собственно "програмистских" абстракций, которые предметникам совершенно не нужны.
Re[3]: Трудные для ООП иерархии классов
От: igna Россия  
Дата: 23.09.07 08:13
Оценка: +1
Здравствуйте, COFF, Вы писали:

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


Для этого есть множественное наследование. Но если вдруг в дополнение ко всем этим фигурам позже захочется поиметь еще и многоугольник, придется менять иерархию.

P.S. Параллелограмм это трапеция, а трапеция это четырехугольник. А еще и дельтоид есть.
Re[2]: Трудные для ООП иерархии классов
От: igna Россия  
Дата: 23.09.07 08:15
Оценка:
Здравствуйте, MatFiz, Вы писали:

MF>Одинаковый интерфейс, разные реализации (данные представлены по-разному).

MF>Тут все просто.

А setter-ы добавить сможешь?
Re[4]: Трудные для ООП иерархии классов
От: nikov США http://www.linkedin.com/in/nikov
Дата: 23.09.07 09:01
Оценка:
Здравствуйте, igna, Вы писали:

I>P.S. Параллелограмм это трапеция


Это неверно. Смотреть любой учебник геометрии или здесь.
Re[2]: Трудные для ООП иерархии классов
От: Андрей Коростелев Голландия http://www.korostelev.net/
Дата: 23.09.07 09:14
Оценка: 3 (1) +1
Здравствуйте, Кодт, Вы писали:

К>>ужно определиться с тем, что именно означает иерархия структур в каждом случае: это специализация (субклассирование) или расширение (наследование).

К>К специализации применим LSP, к расширению — очевидно, нет.

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

Наследование с целью расширения наряду со специализацией и спецификацией (поледнее является частным случаем специализации, например, наследование интерфейса) входит в список "правильных" форм наследования для которых выполняется LSP, то есть для которых подклассы всегда являются подтипами.

К>В Блоге Труъ Программиста в августе была серия статей на тему.

-- Андрей
Re[5]: Трудные для ООП иерархии классов
От: _DAle_ Беларусь  
Дата: 23.09.07 13:40
Оценка: 1 (1)
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, igna, Вы писали:


I>>P.S. Параллелограмм это трапеция


N>Это неверно. Смотреть любой учебник геометрии или здесь.


Как категорично. Предлагаю прочитать первый абзац в английской версии статьи.

P.S. Я обычно статьи (на тематику, не связанную с Россией) из русскоязычной википедии даже не читаю, когда мне ссылки дают на нее, переключаюсь на соответствующую англоязычную статью сразу.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: Трудные для ООП иерархии классов
От: jazzer Россия Skype: enerjazzer
Дата: 23.09.07 15:55
Оценка:
Здравствуйте, deniok, Вы писали:

D>Однако есть один момент. Когда ООП-ники говорят про преимущества ООП, одним из основных аргументов служит следующий:


D>ОО проектирование легко позволяет моделировать окружающий мир.

Так а в реальном мире прямоугольники и квадраты неизменяемые!
Ты не можешь в геомтерии, из которой ты несешь идею "квадрат — это прямоугольник", изменить размеры ни квадрата, ни прямоугольника. Ты можешь только породить новый объект где-нть рядом ("по построению").
В таком read-only интерфейсе между ними действительно есть строгое отношение "is a", и все операции, которые ты можешь применить в прямоугольнику (т.е. получение размеров, вычисление площади, получение координат вершин и т.п.) применимы и к квадрату.

D>Видим в нём сотрудников — делаем класс Employee, видим начальника — делаем класс Manager, поскольку начальник is a сотрудник (в окружающем мире так) пользуем наследование.

Сорри, поясни, в чем тут проблема?
Я вот не вижу навскидку, что мы такого не можем сделать с сотрудником, чего не можем сделать с его начальником.
Нанять/уволить можем? Можем.
Зарплату заплатить или не заплатить можем? Можем.
Дать людей в подчинение можем? Можем.
Перекинуть его к другому начальнику можем? Можем.
В чем проблема-то?

D>Так вот проблемы с квадратом и прямоугольником как раз показывают, что по большому счёту эта простая схема — впендюринг.

Эти примеры показывают, что ты берешь реальный мир из геометрии, в котором квадрат является прямоугольником, перемешиваешь его с виртуальным миром Visio/PowerPoint, в котором ты можешь менять размеры и того, и другого, и при этом не отсекаешь этого перехода и продолжаешь думать в терминах read-only геометрии.
Это называется просто подменой понятий и к ООП отношение имеет опосредованное.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Трудные для ООП иерархии классов
От: jazzer Россия Skype: enerjazzer
Дата: 23.09.07 16:31
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>2. Комплексное число и вещественное число. Хотя вещественное число является комплексным (наследование), вы не станете наследовать его от комплексного по многим причинам: вам не нужна его реализация (два float в памяти вместо одного), вы вряд ли будете рады тому что sqrt(4) вместо 2.0 вернёт тупл из двух комплексных чисел, и т.п.


Эта проблема, вообще-то, никакого отношения к ООП не имеет.

В математике корень степени N из любого положительного числа на множестве действительных чисел будет возвращать действительное число, а на поле комплексных — N комплексных чисел.
Соответственно, в математике одноименные функции над действитальными и комплексными числами записываются с маленькой и большой буквы соответственно, если мне память не изменяет, конечно.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Трудные для ООП иерархии классов
От: igna Россия  
Дата: 24.09.07 07:29
Оценка:
Здравствуйте, nikov, Вы писали:

N>Это неверно. Смотреть любой учебник геометрии или здесь.


В моем учебнике геометрии параллелограмм был частным случаем трапеции. Почитав русскую Википедию подумал сначала, что определение просто небрежно написано, но почитав английскую с удивлением обнаружил, что бывает и такое, исключающее частный случай параллелограмма, определение трапеции. Какой в нем смысл — для меня загадка, ведь вроде все доказательства и алгоритмы применимые к трапециям будут применимы и к параллелограммам, так к чему исключение? Подобные штуки в каком-нибудь языке программирования или в написанной на нем библиотеке меня скорее всего не удивили бы; но у математиков как правило все намного лучше продумано.
Re[2]: Трудные для ООП иерархии классов
От: igna Россия  
Дата: 24.09.07 08:48
Оценка: +1 :))
Здравствуйте, jazzer, Вы писали:

J>Эта проблема, вообще-то, никакого отношения к ООП не имеет.


Согласен. IMHO большинство проблем не имеет отношения к ООП, и наоборот ООП не имеет отношения к большинству проблем. Имею ввиду именно проблемы программирования, а не проблемы вообще, так как к счастью никакой философской школы из ООП вроде не возникло, так что ОООПисты хоть непрограммистам мозги не мучают. Менеджерам разве еще...
Re[3]: Трудные для ООП иерархии классов
От: mrozov  
Дата: 24.09.07 09:11
Оценка:
История величайших изобретений (не путать с открытиями) состоит из восклицаний "почему я раньше до этого не додумался".

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

DSL — это только один из вариантов развития. Затачивание языка под прикладную область/тип мышления. Было бы неплохо нащупать прорыв
Re[4]: Трудные для ООП иерархии классов
От: mkizub Литва http://symade.tigris.org
Дата: 24.09.07 09:50
Оценка: -3 :)
Здравствуйте, mrozov, Вы писали:

M>DSL — это только один из вариантов развития. Затачивание языка под прикладную область/тип мышления. Было бы неплохо нащупать прорыв


DSL вообще не вариант. Проблема не в создании нового языка, и уж тем более узкоспециализированного. Проблема в эффективном использовании этого языка, а эффективность обеспечивается качественными компиляторами, IDE, отладчиками, библиотеками и людьми которые умеют язык использовать. Создание подобной инфраструктуры стоит десятки, сотни миллионов баксов. Эти деньги можно вложить только в мэйнстрим язык, и то вскладчину, всем миром. В подобный уровень поддержки DSL языка никто вкладываться не будет. А без такой инфраструктуры, хоть DSL и облегчает программирование в конкретной области, он как правило не может превысить эффективности языка общего назначения.

Прорыв известен уже давно — вместо программирования в синтаксических конструкциях надо программировать в семантических значениях. Самым разрекламированным в этом направлении является Intentional Programming (особо этому помогло то, что про его детали реализации никто ничего не знает, и все надеются на лучшее). Такой подход позволит легко определять онтологии для предметных областей (функции DSL), адаптировать имеющийся язык к конкретной задаче (расширение языка), легко адаптироваться к усложняющемуся железу и т.п.

Пока этот подход был не очень конкурентоспособен — поскольку предъявляет достаточно большие требования к сложности софта и железа разработчика. Так же как кислородное дыхание было невыгодно, по сравнению с анаэробным, до определённого уровня насыщенности воды/атмосферы кислородом.

Фактически, нынешние компьютеры разработчиков уже предоставляют достаточную мощность для семантического программирования, но они не могут пробиться в массы всё по тем-же причинам — экологическая ниша уже занята. Но ниши, в которых нынешний мэйнстрим не справляется — существуют. В этих нишках и прозябают нынешние DSLи. В них семантическое программирование и начнёт своё становление. А лет через 10-15, когда закончится действие закона Мура, и изготовители железа перейдут от погони за количеством (мегагерц, транзисторов, ядер) к погоне за качеством (сложностью, адаптивностью и т.п.) — нынейшний мэйнстрим не сможет предложить никаких вариантов, и будет почти полностью вытеснен.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[4]: Трудные для ООП иерархии классов
От: COFF  
Дата: 24.09.07 09:54
Оценка:
Здравствуйте, igna, Вы писали:

I>P.S. Параллелограмм это трапеция, а трапеция это четырехугольник. А еще и дельтоид есть.


Насчет дельтоида не знал
Re[3]: Трудные для ООП иерархии классов
От: MatFiz Россия  
Дата: 25.09.07 18:34
Оценка:
Здравствуйте, igna, Вы писали:

I>А setter-ы добавить сможешь?


Зачем они могут понадобиться?
Лучше иметь immutable-классы — мороки потом меньше будет.
How are YOU doin'?
Re: Трудные для ООП иерархии классов
От: Baudolino  
Дата: 25.09.07 19:57
Оценка:
Кё>Я ищу примеры классов объектов, которые вызывают трудности при объектном моделировании в современных ЯП типа C++ или C#.
С трудностями не встречался ни разу. Нужно просто знать некоторые приёмчики (паттерны и просто трюки) и правильно анализировать предметную область.

Кё>1. Построить иерархию классов для прямоугольника и квадрата, с изменяющимися размерами. Трудность в том, что хотя квадрат всегда является прямоугольником (наследуется), он не захочет наследовать его реализацию (зачем ему раздельно хранить ширину и высоту?). Другая трудность в том, что прямоугольник иногда может являться квадратом, но классические отношения между классами, которые предлагают ЯП (наследование и implicit-conversion) не могут выразить такого отношения.

Решение тривиально после правильного анализа, который заключается в том, что необходимо выделить интерфейс или абстрактный класс (как уже отмечали выше):
public abstract class Figure {
   // координаты центра масс и 
   // угол поворота от некоторого положения по умолчанию (для прямоугольников - когда стороны параллельны осям)
   float x,y,a;
   abstract Figure rotate(float da);
   abstract Figure move(float dx, float dy);
   abstract Figure resize(float factor); // операция изменения размера производит подобную фигуру
   abstract void paint(Graphics g);
}

public abstract class Rectangle {
   // размеры: при угле равном 0, стороны соотв. ширине, параллельны оси OX
   abstract float getWidth();
   abstract float getHeight();
   abstract Rectangle move(float dx, float dy);
   // операция изменения размера производит подобную фигуру,
   // поэтому мы можем уточнить тип
   abstract Rectangle resize(float factor); 
   abstract Rectangle resize(float wfactor, hfactor);
   ...
}

public class GenericRectangle extends Rectangle {
   float x, y, a;
   float width, height;
   Rectangle resize(float factor) { return new GenericRectangle(x, y, a, width *factor, height * factor) }
   Rectangle resize(float wfactor, float hfactor) { return new GenericRectangle(x, y, a, width * wfactor, height * hfactor) }
   ...
}

public class Square extends Rectangle {
   float x,y,a,size;
   Square resize(float factor) { return new Square(x,y,a,size*factor); }
   Rectangle resize(float wfactor, hfactor) {
       if (wfactor == hfactor) {
           return new Square(x,y,a,size*wfactor);
       } else {
           return new GenericRectangle();
       }
   }
}



Кё>2. Комплексное число и вещественное число. Хотя вещественное число является комплексным (наследование), вы не станете наследовать его от комплексного по многим причинам: вам не нужна его реализация (два float в памяти вместо одного), вы вряд ли будете рады тому что sqrt(4) вместо 2.0 вернёт тупл из двух комплексных чисел, и т.п.

Аналогично, реализация отделяется от наследования. Операции над числами реализуются в соответствующей алгебре:

public interface Number {    
    double[] getTuple(); // возвращает 1,2 или 4 элемента (если угодно поддерживать экзотику, то можно 8 и 16)
    double get(int component); // возвращает значение соотв. компонента
}
public interface ComplexNumber implements Number {
    abstract double re();
    abstract double im();
}
public class GenericComplexNumber implements ComplexNumber {
    double[] tuple = new double[2];
}

public class RealNumber implements ComplexNumber {
    double[] tuple = new double[2];
    public double value() { return tuple[0]; }
}

public interface Algebra<N extends Number> {
    Number[] basis(); 
    double multiply(N n1,N n2);
    double add(N n1,N n2);
    ... // и другие операции для данной алгебры
}

public class ComplexAlgebra extends Algebra<ComplexNumber> {
    ComplexNumber[] sqrt(ComplexNumber number) { ... } 
}

public class RealAlgebra extends Algebra<RealNumber> {
    RealNumber sqrt(RealNumber number) { ... }
}
Re[2]: Трудные для ООП иерархии классов
От: Шахтер Интернет  
Дата: 26.09.07 01:33
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Кодёнок, Вы писали:


Кё>>2. Комплексное число и вещественное число. Хотя вещественное число является комплексным (наследование), вы не станете наследовать его от комплексного по многим причинам: вам не нужна его реализация (два float в памяти вместо одного), вы вряд ли будете рады тому что sqrt(4) вместо 2.0 вернёт тупл из двух комплексных чисел, и т.п.


J>Эта проблема, вообще-то, никакого отношения к ООП не имеет.


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

J>Соответственно, в математике одноименные функции над действитальными и комплексными числами записываются с маленькой и большой буквы соответственно, если мне память не изменяет, конечно.

Изменяет.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Трудные для ООП иерархии классов
От: igna Россия  
Дата: 30.09.07 09:46
Оценка:
Здравствуйте, Baudolino, Вы писали:

Если не ошибаюсь, у тебя все объекты неизменяемые, так?
Re[2]: Трудные для ООП иерархии классов
От: no4  
Дата: 01.10.07 07:41
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Кодёнок, Вы писали:


Кё>>... квадрат всегда является прямоугольником ...


I>Изменяемый квадрат не всегда является изменяемым прямоугольником. А в программировании в отличии от математики квадраты и прямоугольники как правило изменяемы.


В книжке Шлеер и Меллора было понятие "миграция подтипа", насколько я помню. Т.е. объект может стать принадлежащим другому классу
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Трудные для ООП иерархии классов
От: Gaperton http://gaperton.livejournal.com
Дата: 04.10.07 10:06
Оценка:
Здравствуйте, igna, Вы писали:

I>Если не ошибаюсь, у тебя все объекты неизменяемые, так?


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

Во втором случае — с числами — решение просто неверно. Интерфейсы, которые он определил, не содержат операций, зато они дают полный доступ к атрибутам. Определенные им типы вообще не являются абстрактными типами данных, и принцип подстановки Лисков нарушается на раз-два-три. Правильное решение — сделать абстрактный класс "поле чисел", как в алгебре, и опять — не связывать оба типа чисел наследованием.

И третье — все решения переусложнены, и вводят больше сущностей, чем необходимо.
Re[5]: Трудные для ООП иерархии классов
От: ZevS Россия  
Дата: 05.10.07 08:52
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Почему безапелляционные?

К>Возьмём 4-й пункт "У объектов есть private состояние" — с самим утверждением не будешь спорить, надеюсь?
К>Джо говорит, что состояние — одна из проблем, состояние увеличивает зависимости, уменьшает расспараллеливаемость и т.д.
К>"Обычные" языки пытаются "спрятать" состояние (с помощью модификаторов и т.п.), тогда как в декларативных функциональных есть подаваемые данные на вход и результат на выходе.

Четвертый пункт — единственный, с которым можно согласиться. Все прочие пункы — просто утверждения.

Почему "Since functions and data structures are completely different types of animal it is fundamentally incorrect to lock them up in the same cage."? А ОО утверждает, что все объекты реального мира имеют и состояние и поведенеие, и почему их надо программировать иначе?

"But in a non OO language a "time" is a instance of a data type." — ну и что с того? А ОО языке — это объект. И что с этого?

"Note that these definitions do not belong to any particular object. they are ubiquitous and data structures representing times can be manipulated by any function in the system." — а с ОО что не так? Использование вовсе != наследование.

"In an OOPL I have to choose some base object in which I will define the ubiquitous data structure, all other objects that want to use this data structure must inherit this object." — ну а это вообще бред.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.