необходимо множественное наследие

Подрыв мозга

Новичок
Поэтому ещё раз говорю, что не стоит целиком распространять выводы касательно такой АБСТРАКЦИИ как ORM на ООП.
Ну я, например, решаю вполне конкректные а не абстрактные задачи. Меня не интересует теоретическая возможность сделать что-то, если в реальной жизни это не будет работать. Я дал несколько вариантов декомпозиции, альтернативной множественному наследованию в различных ситуациях. Одной из ситуаций был пример с магазином, где, по моему мнению, объекты вообще не нужны. Этот пункт вызвал наибольшие споры. Попробую объяснить подробнее.

Объект (Object)- набор данных (полей) и методов для работы с ними.
Кортеж (Tuple) - просто набор данных, к которым можно обращаться по индексу.
Запись (Record) - то же, что и Tuple, но обращение к полям идет по имени.

В разных языках это реализовано по-разному. В JavaScript объекты могут динамически изменяться, в Java - нет. В F# есть туплы, в PHP нет - это вопросы реализации. Но концептуально - объект имеет определенную структуру, по которой он однозначно характерезуется, в то время как туплы/записи могут быть любыми. И я утверждаю, что когда структура данных неопределена заранее, как например, в CMS, то строить объектно-ориентированную модель бесполезно.

Пример 1.
Вам нужно сделать пятиэтажный запрос запрос к базе данных, делающий выборку из трех таблиц с четырямя join'ами. Типичная ситуация не так ли? Какой при этом должен быть возвращенный результат? Либо вы возвращаете коллекцию туплов (или их заменителей), либо коллекцию нехилых графов объектов.

Пример 2.
Как вы будете программироваь работу с объектами, если ваша CMS уже продана заказчику? Очевидно, что теперь он сам должен рулить со своим ассортиментом, и бизнесс-правила тоже он сам будет создавать - чем лучше ваша CMS, тем больше возможностей она предоставляет без перепрограммирования. Я не знаю, как это сделать, придерживаясь ООП-стиля.

Пример 3.
Касаемо 3D графики - у вас есть объекты Vector и Point, оба содержат поля x, y, z. Метод moveТоTheRight(Vector $vector) перемещает вектор вправо. Вы хотите такой же метод но который перемещает Point, так как сигнатуры у них совпадают, а не получится - классы разные, отсюда дубляж кода. В бизнес-логике такое тоже часто встречается.


Какой именно подход имел ввиду ты в своём посте?
Когда я говорю "фукциональное программирование" я намекаю на фукциональное программирование.

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

AmdY

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

whirlwind

TDD infected, paranoid
А я вот все равно не понимаю, так же как и AmdY. Если речь об этом http://ru.wikipedia.org/wiki/Функциональное_программирование , то каким боком тут приведенные примеры? Если не об этом, то о чем вообще тут разговор?

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

PHP:
	protected function _ssh2_exec_wrapper($conn,$command){
		return ssh2_exec($conn,$command);
	}
что бы потом моком это дело перекрыть вот так

PHP:
	/**
	 * @expectedException TTK_Ssh2_Exception
	 */
	function testExecThrowsIfSsh2ExecFailed(){
		$c = $this->getMock('TTK_Ssh2_Client',Array('_ssh2_exec_wrapper'));
		$c->expects($this->once())
			->method('_ssh2_exec_wrapper')
			->with($this->equalTo('conn'),$this->equalTo('echo 123'))
			->will($this->returnValue(false));
		$c->setConnection('conn');
		$c->exec('echo 123');
	}
Было бы проще, если бы ssh2_connect был методом класса - я бы сразу его моком заткнул без написания костылей.

И этого мне достаточно, что бы признать процедурное программирование неэффективным для моего стиля работы. Это относится к каждой строчке моего кода. Где тут товары, векторы, орм или вообще конкретные классы? Какие усилия на тест мне придется затратить при функциональном подходе, я вообще не представляю.

Так что спор то пустой ИМХО. Если ты гений-математик, пишущий идеально-безбажный код с первого раза, ну так никтож тя не заставляет писать ООП. Но середнячкам нужно оставить че попроще для восприятия, например ООП.
 

korchasa

LIMB infected
>>> Разве продаются карандаши, бублики и яхты, а не товары? Разве яхты, бублики и карандаши можно только продавать? Цена, скидка, дата начала продажи, количество на складе - это же свойства товара, да?

Да свойства Товара. В программной реализации это может быть Объект, Кортеж или Запись. Не факт, что Объект - это лучшая форма пердставления товара.
Имеено для тавара я думаю таки лучший, ибо если это магазин, то с товаром будет много всякого кода связано. С другой стороны, как это часто бывает, единственная разница между товарами это категория(яхты, карандаши и бублики). В этом случае, конечно, выделять класс под яхты бессмысленно.

>>> Для валидации свойств сущностей Яхта, Карандаш и прочих, придется вводить какие спец инструкции. Для обеспечение
работы этих инструкций придется писать код. Рано или поздно придется добавлять новые валидаторы, а следовательно опять понадобиться программист.

Понимаю, пример можно, чтобы не абстрагироваться?
Каждый выставленная яхта дороже 1M должна проверяться по БД угнанных яхт(оффлайн), если только она не была продана у нас же на прошлой неделе.

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

>>> К тому же по данным в "массивах" тяжело делать аналитику.
Тоже примерчик не помешало бы.
Ну вы же не будете спорить, что неоднородные данные хуже поддаются анализу? Или будете?

Вратце: когда я увижу, что вас каждой позиции товара в магазине соответствет отдельный класс (в случае с Амазоном это десятки тысяч классов) я поверю, в то что это OOП - иначе это не объекты, а кортежи.
Поверьте - это объекты. В своей жизни я сделал ровно два магазина. Мне было проще сделать 3-5 классов, по одному на каждую сущность. Хотя возможно когда-нибудь мне придется разрабатывать систему где товары будут являться записями.

...Но концептуально - объект имеет определенную структуру, по которой он однозначно характерезуется, в то время как туплы/записи могут быть любыми. И я утверждаю, что когда структура данных неопределена заранее, как например, в CMS, то строить объектно-ориентированную модель бесполезно.
Мы видимо говорим о совсем разных CMS, ибо для меня новость(статья, файл, профиль пользователя, голосование etc) имеют четко определенные структуры.

Пример 1.
Вам нужно сделать пятиэтажный запрос запрос к базе данных, делающий выборку из трех таблиц с четырямя join'ами. Типичная ситуация не так ли? Какой при этом должен быть возвращенный результат? Либо вы возвращаете коллекцию туплов (или их заменителей), либо коллекцию нехилых графов объектов.
И? Где подвох? Показали 100 статей (для каждой подтянули авторов, коллекции комментариев, превьюшку и еще что-то), создали 400 объектов(хотя их можно и не создавать, если мы просто отображаем уже имеющиеся данные). Конечно оверхэд, но какая разница, если у нас запрос на три таблицы с 4мя join'ми. Сейчас программист все таки дороже еще одного сервера приложений(которые легко ||-ся), а узкое место почти всегда - БД. Хотя, конечно, всегда хочется максимальной эффективности.

Пример 2.
Как вы будете программироваь работу с объектами, если ваша CMS уже продана заказчику? Очевидно, что теперь он сам должен рулить со своим ассортиментом, и бизнесс-правила тоже он сам будет создавать - чем лучше ваша CMS, тем больше возможностей она предоставляет без перепрограммирования. Я не знаю, как это сделать, придерживаясь ООП-стиля.
Заказчик будет красивым конструктором в админке создавать новые типы объектов, с бизнес-правилами и собственно логикой? Хочу посмотреть на такую систему. Честно. Без шуток. Просто интересно насколько гибкой ее можно сделать.

Пример 3.
Касаемо 3D графики - у вас есть объекты Vector и Point, оба содержат поля x, y, z. Метод moveТоTheRight(Vector $vector) перемещает вектор вправо. Вы хотите такой же метод но который перемещает Point, так как сигнатуры у них совпадают, а не получится - классы разные, отсюда дубляж кода. В бизнес-логике такое тоже часто встречается.
Бывают случаи и похуже. Например есть класс Vector, а мы хотим еще один класс Vector...или это опять про type hinting?
 

rotoZOOM

ACM maniac
Касаемо 3D графики - у вас есть объекты Vector и Point, оба содержат поля x, y, z. Метод moveТоTheRight(Vector $vector) перемещает вектор вправо. Вы хотите такой же метод но который перемещает Point, так как сигнатуры у них совпадают, а не получится - классы разные, отсюда дубляж кода.
Не совсем корректный пример. Вектор - это направление. Точка - это точка. Направление нельзя переместить вправо :)
 

atv

Новичок
Поэтому ещё раз говорю, что не стоит целиком распространять выводы касательно такой АБСТРАКЦИИ как ORM на ООП.

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

Вам нужно сделать пятиэтажный запрос запрос к базе данных, делающий выборку из трех таблиц с четырямя join'ами. Типичная ситуация не так ли? Какой при этом должен быть возвращенный результат?
Любой результат, возвращаемый SQL запросом, является таблицей. Если этот результат нужен только для отображения на странице, то наиболее удачной АБСТРАКЦИЕЙ из арсенала ООП я считаю DataSet. Если результат нужен приложению, для выполнения бизнес логики, то в этом случае удачной АБСТРАКЦИЕЙ я считаю ORM.

Вратце: когда я увижу, что вас каждой позиции товара в магазине соответствет отдельный класс (в случае с Амазоном это десятки тысяч классов) я поверю, в то что это OOП - иначе это не объекты, а кортежи.
Опять же, это вопрос о выборе наиболее удачной абстракции, который зависит от многих обстоятельств. Можно объединить все товары под одной абстракцией "Товары", но если будет необходима валидация, то и на тысячу товаров будет лучше написать классы. Вобщем, выбор абстракции упирается в требования к приложению.

Когда я говорю "фукциональное программирование" я намекаю на фукциональное программирование.
Тогда многие твои высказывания становятся совсем непонятными. Похоже, ты, всё-таки, не в теме.
 

Подрыв мозга

Новичок
Господа, когда я говорю о функциональном программировании я не имею ввиду TURBO PASCAL, я говорю об этом Функциональное программирование для всех

korchasa
>>> ... В этом случае, конечно, выделять класс под яхты бессмысленно

Таким образом у вас один-единственный класс на все товары, так?

>>> Ну вы же не будете спорить, что неоднородные данные хуже поддаются анализу? Или будете?

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

>>> Мы видимо говорим о совсем разных CMS, ибо для меня новость(статья, файл, профиль пользователя, голосование etc) имеют четко определенные структуры.

Очевидно да, я говорю о прямо противоположном случае.

>>> И? Где подвох?

НЕТУ авторов, НЕТУ комментариев НЕТУ первьюшки - ничего этого нет. Есть только товары, которые еще даже никто не внес в базу. О которыx НИЧЕГО не известно.

>>> Поверьте - это объекты. В своей жизни я сделал ровно два магазина.

Первый, надо понимать, Амазон?

>>> Мне было проще сделать 3-5 классов, по одному на каждую сущность.

А теперь умножте это на 1000.

>>>Хочу посмотреть на такую систему. Честно. Без шуток. Просто интересно насколько гибкой ее можно сделать.

Аллах знает.

rotoZOOM
>>> Не совсем корректный пример. Вектор - это направление. Точка - это точка. Направление нельзя переместить вправо

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

atv
К сожалению, ваши сообщения настолько АБСТРАКТНЫ, что я не знаю, как на них реагировать. Будут (контр)примеры - обсудим.
 

atv

Новичок
К сожалению, ваши сообщения настолько АБСТРАКТНЫ, что я не знаю, как на них реагировать. Будут (контр)примеры - обсудим.
У тебя проблемы с пониманием значения абстракций в программировании? В своём ликбезе ты сам привёл несколько возможных абстракций для решения задачи множественного наследования. А тут "твоя моя непонимай"? Или не найдя контраргументов, ты прикрываешся непониманием, чтобы не признавать свою ошибку?

ваши сообщения настолько АБСТРАКТНЫ, что я не знаю, как на них реагировать
Я тебе подскажу. Признай, что оказался неправ в некоторых своих рассуждениях, а не скатывайся до сарказма и личных оскорблений.
 

whirlwind

TDD infected, paranoid
> Не буду, именно поэтому считаю, что проще сделать выборку только нужных свойств в виде Record, чем полодить сотни разнородных классов.

Данные неуправляемы, они просто есть и все. Управляем только код. Это значит, что Ваша выборка улетает в copy&paste вместе со всеми багами и последующим повсеместным переписыванием только из-за того, что нужно дату отформатировать по другому, вместо того, что бы переопределить один метод например декоратором, в экземпляр которого и передать нужный формат даты.

Если есть проблемы с выявлением сущностей при решении элементарных задачи, следует использовать модульное тестирование, что бы выйти на путь истиный.

PS. Судя по тому, что написано на rsnd, ФП на PHP это нечто.
 

Alexandre

PHPПенсионер
странно. я думал это не такая уж и редкая практика. вот например, если мы делаем класс овцебык, то как тогда быть? надо наследовать и от овцы и от быка
вот как раз овцебык не являеттся частью овцы и быка соответственно, по этому наследование противопоказанно - даже одиночное. наследование реализует абстракцию ЯВЛЯЕТСЯ ЧАСТЬЮ.
используй делегирование.
 

rotoZOOM

ACM maniac
наследование реализует абстракцию ЯВЛЯЕТСЯ ЧАСТЬЮ.
Не совсем верно, скорее "работает как". Александреску приводит замечательный пример, где опровергается как раз утверждение насчет является частью. Пример квадрат и прямоугольник. По сути квадрат является частным случаем прямоугольника, но квадрат нельзя наследовать от прямоугольника, так у него только одна размерность, а у прямоугольника две независимые.
 
Сверху