Посоветуйте правильную реализацию/паттерн

surg30n

Новичок
Посоветуйте правильную реализацию/паттерн

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

Код тут (97 строк) : http://4test.ru/tmp/helloworld.phps
 

_RVK_

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

whirlwind

TDD infected, paranoid
Избавитесь, когда поймете, что чем меньше класс знает об окружающем мире, тем лучше. Ну засуньте в proto_item еще несколько очень важных функциональных возможностей, например, работу с базой данных или кеширование страниц. Да и вообще, зачем что то делить на классы?
 

surg30n

Новичок
_RVK_
Пример, есть три класса (commentable, taggable, rateable), функционал которых необходимо "подключать" к другим объектам (product, article). Вопрос все тот же - как сделать правильно, без костылей типа миксинов.

whirlwind
Как бы вы реализовали подобную задачу? Пару предложений без воды с указанием правильного направления)
 

_RVK_

Новичок
surg30n
Если я правильно понял что нужно то возможно это поможет

Но применять это решение следует очень осторожно!
 

surg30n

Новичок
_RVK_
Похоже, но немного не то.

Поясню. Вот примерный код класса commentable

PHP:
class commentable {
/** @var comment_items Comments */
protected $_comments;
function load_comments() { $this->_comments = some_lib::get_comments_by_pid($this->id); }
function get_comments() { return $this->_comments; }
}
На ruby я бы мог присоединить класс commentable к article так

class article
extend commentable
extend taggable
end

Есть ли у вас живой незамороченный пример с композиционным патерном?

-~{}~ 26.09.08 18:25:

whirlwind
Спасибо, что дали не просто ссылку на agiledev :)
 

_RVK_

Новичок
Я говорю не о том, что этот вариант решает проблемму ТАК как ты хочешь, я говорю о том что он ПРОСТО решает проблему, не обязательно через множественное наследование. Единственное наследование, позволяет решить все проблемы скопом. Любой объект системы сразу же является и commentable и taggable и еще много чего еще. При этом интерфейс у них один и тот же, и этого интерфейса достаточно (то есть расширять не надо).
Но я не настаиваю. В принципе этот паттерн (One True Lookup Table) применим в очень узких рамках. В инете можно на эту тему пару статей найти.

Воопщем, как вариант можно посмотреть ;)

ЗЫ. Убегаю, пример не успеваю написать.
 

whirlwind

TDD infected, paranoid
surg30n Вы все еще не понимаете. Попробуем по-другому. Приведите реальный пример, где article_item должна по сути работать с тэгами или комментариями или оценками. Вариант с эхами не прокатывает, Вы же не хотите в действительности сказать, что ваши статьи могут сам себя отрисовать для самых разных случаев жизни.

Или иначе - кто на кого ссылается статья на тэг или тэг на статью? Прям по базе посмотрите
 

surg30n

Новичок
whirlwind
one-to-many
статья-комментарии
статья-тэги

Пример - при удалении статьи, удаляться и связанные комментарии и тэги.
 

whirlwind

TDD infected, paranoid
surg30n Т.е. у Вас в строке таблицы, которая представляет собой статью, есть к примеру поле BLOB, в котором вы храните айдишки всех комментариев к статье?

-~{}~ 26.09.08 19:14:

PHP:
interface IItem {

	function getId();
	function delete();

}

class CommonItem implements IItem {
	...
}

class CommonItemDecorator implements IItem {

    function __construct(IItem $item){
    	...
    }
    
}

interface ITaggable {

	function get_tags();

}

class CommonTaggable extends CommonItemDecorator implements ITaggable {

	function get_tags(){
		return $this->getTags($this->getId());
	}
	
	function delete(){
		$this->deleteTags($this->getId());
		parent::delete();
	}

}
 

surg30n

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

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

whirlwind

TDD infected, paranoid
А вот это - правильный вопрос :) (&copy Азимов) Тут я вижу два варианта. Первый - magic __call в декораторе. Минус в том, что type hinting отваливается. Второй - event driven - тут все пучком, но минус - нужно мозгами пораскинуть где регать listeners (see observer pattern). Это можно назвать проблемой. Но достаточно заглянуть немного в будущее, и увидеть что любой из этих вариантов проживет/приживется гораздо дольше/легче, чем нагромождение раличного типа наследований.
 

_RVK_

Новичок
surg30n
Насчет примера. Эта штука реализована на Java но постараюсь тут от балды написать пример на PHP

Допустим такая задача. Есть у нас обьекты Article, Photo.

PHP:
class Article extends GuidComponent {
...
}

class Photo extends GuidComponent {
...
}

class Comment extends GuidComponent {
...
}

class Tag extends GuidComponent {
...
}

//Берем объекты из бвзы с ID=1
$article = new Article(1);
$photo = new Photo(1);
//Создаем новые коментарий и тэг
$tag = new Tag();
$comment = new Comment();

//Комментарий и тэг сохраняем в базе
$tag->txt = 'tag word';
$tag->save();

$comment->content = 'This is comment text';
$comment->save();

//А теперь коментируем статью
$article->addChild($comment);
//И тэг добавляем
$article->addChild($tag);

//И финт ушами, Фото будет иллюстрировать статью
$article-addChild($photo);
//Тэг будет так же относится и к фото
$photo->addChild($tag);

//Получаем все комментарии к статье
$comments = $article->loadChildren('Comment');
//ну и тд.
Суть всего этого что любой объект может быть связан с любым объектом в отношении много-ко-много. В принципе, если захочется я могу так же фото привязать к тэгу, что упростит мне выборку всех объектов с этим тэгом, а статью привязать к фото, что бы получать например список статей, проиллюстрированными этой фотографией. Вообще, гибкость колоссальная получается. Главное не увлечься ;)
 
Сверху