Помогите разобраться с правильным ООП.

Camillo

Новичок
Помогите разобраться с правильным ООП.

Привет.

Я достаточно давно "программирую" на PHP, но всё это время я использовал PHP для написания полезных мне одному утилит или простых веб-приложений. При этом я программировал процедурно и никогда не заморачивался по этому поводу.

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

Решил начать с того, что стал изучать книгу "PHP5 для профессионалов" от изд-ва Wrox. В какой-то момент поймал себя на мысли, что примеров, которые даны в книге просто недостаточно и они не взаимосвязаны между собой. Отрывочные главы, которые едва ли можно увязать друг с другом. Куча рекоммендаций, но все примеры очень обтекаемые и мало что имеют общего с реальной разработкой (имхо). Не хватает какого-нибудь реального приложения, на примере которого было бы показано: "Вот так стоит делать
до тех пор, пока вы сами не поймете, что такой подход уже не достаточно гибкий.".

Я решил придумать самое простое приложение и на его примере научиться основам ООП...

Приложение: Каталог веб-сайтов разбитых по категориям.

Всё приложение умещается в 3х таблицах.
1. Таблица categories (category_id / title)
Список категорий. Каждый сайт может находиться только в одной категории.

2. Таблица websites (website_id / domain / category_id)
Список сайтов с указанием домена и индекса категории.

3. Таблица websites_meta (uid / website_id / meta_title / meta_value)
Таблица с параметрами сайта. Я "превратил" вертикали параметров в горизонтали, чтобы приложение было
более гибким и процесс разработки был более интересным.


Для начала необходимо реализовать...
1. Форма добавление\редактирования\удаления сайта.
2. Форма добавление\редактирования\удаления категории (добавление\удаление\редактирование категории можно сделать Ajax')..
3. Страница постраничного просмотра сайтов с фильтрацией по категориям (смена страниц Ajax'ом).
4. Страница постраничного просмотра категорий (смена страниц Ajax'ом).

Достаточно простое приложение, в котором задействовано несколько таблиц.


Допустим, в первую очередь - я создам Collection классы для категорий и для вебсайтов, чтобы оперировать не
просто массивами переменных, а именно объектами. Сразу возникают вопросы...

Сделать универсальный класс Collection и методы работы с коллекциями категорий\вебсайтов наследовать у него?

Вносить ли в Collection классы методы взаимодействия с БД, например добавление новой категори в базу, удаление категории из БД и т.д.?
Или создать отдельный класс именно для взаимодействий? Как назвать эти классы?

В каком классе определить метод, который будет отдавать HTML с массивом объектов для асинхронной подгрузки списка?

Каким образом производить валидацию входных данных и как увязать это с классом Collection?


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

Спасибо!
P.S. Сорри, что так много букаф. :D

-~{}~ 27.01.09 03:44:

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

-~{}~ 27.01.09 03:52:

В данном случае хотелось бы нарушить вот это золотое правило и сделать как раз так, как не рекоммендуется делать, т.к. это поможет мне понять как это всё работает.

Простота – чем меньше архитектурных решений, тем лучше. 1 класс, который решает ровно одну проблему здесь и сейчас, возможно, лучше, чем набор из 1 класса, 3-х декораторов, одной фабрики и одного фасада, которые в будущем помогут решить 5 схожих проблем.
 

Krishna

Продался Java
1. Здесь тебе дадут гораздо больше вредных советов чем полезных, ибо в ООП здесь хорошо рюхают единицы.
2. Такие топики тут появляются раз в неделю, юзай поиск.
3. Купи и прочитай книжки по ООП, а потом сваяй что-нить на ООП фреймворке типа Зенда или Симфони, разобрав сначала примеры готовых приложений на них. Всё это куда полезнее изобретения собственных кривых велосипедов, с точки зрения самообразования.
 

AmdY

Пью пиво
Команда форума
Camillo
первым делом постарайся избегать разбор устройства моделей, коллекций, активную запись, orm оставь на потом.
начни с разбора mvc, где-то была ссылка на simple mvc. мне ещё mzz фреймворк понравился, он лаконичнее zend framework и symfony, в которых местами слишком много ООП

чтобы использовать преимущества php5 познакомся с библиотекой spl
 

zerkms

TDD infected
Команда форума
Сделать универсальный класс Collection и методы работы с коллекциями категорий\вебсайтов наследовать у него?
обычно я делаю так: сначала пишу несколько классов, затем - если появляется дублирование кода, либо код обоих классов можно привести к общему знаменателю - произвожу наследование с вынесением общего кода в потомка. естественно только в том случае, если наследование в данной конкретной ситуации логично.
у тебя - коллекция это инкапсуляция массива в объект.
предложение: пусть он для начала сможет только обходить хранимые объекты (остальное допишешь позже).

Вносить ли в Collection классы методы взаимодействия с БД, например добавление новой категори в базу, удаление категории из БД и т.д.?
нет. пусть этим занимается каждый из классов. вообще для работы с БД придумано немало всяких клёвых подходов. google://active record

остальные вопросы - они слишком обширны для обсуждения в одном топике, и были на форуме уже не раз.
 

x-yuri

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

-~{}~ 27.01.09 07:28:

В данном случае хотелось бы нарушить вот это золотое правило и сделать как раз так, как не рекоммендуется делать, т.к. это поможет мне понять как это всё работает.
ты рискуешь получить вот такой hello, world. А правило такое потому, что паттерны надо применять основываясь на том, что они дают в результате и нужно ли это "в результате" тебе

что касается изучения ООП, я соглашусь с Krishna. Потому что лучше сначала посмотреть, как это реализовано в других фреймворках, а не писать сразу свой (допустим не фреймворк, но все же)

-~{}~ 27.01.09 07:31:

если свое все же хочешь создавать, посмотри это

-~{}~ 27.01.09 08:36:

что касается вопросов

Допустим, в первую очередь - я создам Collection классы для категорий и для вебсайтов, чтобы оперировать не
просто массивами переменных, а именно объектами. Сразу возникают вопросы...
первый вопрос, который должен был возникнуть, это зачем тебе этот класс? Объяснение типа чтобы это был объект, а не массив не канает. Вот, например, "чтобы отделить работу с БД от остального" имеет смысл. Но если бы у тебя к БД только один запрос в приложении был, это бы смысла не имело

Сделать универсальный класс Collection и методы работы с коллекциями категорий\вебсайтов наследовать у него?
Наследование лучше применять для полиморфизма. Т.е. в идеальном случае у тебя базовый класс - интерфейс (код отсутствует), а каждый потомок реализует методы, описанные в интерфейсе по-своему. Т.е. если тебе нужно обращаться к объектам разных классов используя один и тот же интерфейс. Что именно ты наследовать собрался?

Вносить ли в Collection классы методы взаимодействия с БД, например добавление новой категори в базу, удаление категории из БД и т.д.?
Или создать отдельный класс именно для взаимодействий? Как назвать эти классы?
это имеет смысл, если у тебя еще какая-то логика намечается, а не просто извлечь/изменить/удалить. Т.е. чтобы отедлить доступ к БД от этой самой логики

В каком классе определить метод, который будет отдавать HTML с массивом объектов для асинхронной подгрузки списка?
во-первых, чем сложнее твое приложение, тем лучше каким-нибудь JSON или XML данные передавать, потому что ты будешь дублировать шаблон списка (вывод странички и передача через Ajax). Во-вторых, можно создать какую-нибудь "страничку", которая будет выдавать клиенту информацию по Ajax, а для доступа к БД использовать соответствующие классы (Collection похоже)

Каким образом производить валидацию входных данных и как увязать это с классом Collection?
можно для этого создать класс, чтобы можно было просто сказать: этот параметр - int, это - строка, это email. Т.е. опять же, чтобы отедлить валидацию от остального кода

по поводу БД: лучше, как советовали, для начала каким-нибудь готовым ORM воспользоваться
 

zerkms

TDD infected
Команда форума
вот наследование так лучше не использовать. Оно предназначено для полиморфизма, а не для исключения дублирования кода, с последним композиция неплохо справляется
мде :)
если по логике объекты находятся в одной иерархии наследования, и определённо - у них должен быть общий предок, содержащий общий код, то какой алгоритм ты будешь использовать при написании. очень хотелось бы подробнее процесс услышать, как ты, не имея на руках кода, пишешь код для абстрактного родителя?

-~{}~ 27.01.09 16:53:

Т.е. если тебе нужно обращаться к объектам разных классов используя один и тот же интерфейс. Что именно ты наследовать собрался?
да например тот же самый самописный AR:
было на руках у человека 2 сущности news и article. в итоге все общие методы работы с БД было решено вынести в родительский record.
стандартная практика.
 

x-yuri

Новичок
стандартная практика.
+1

было на руках у человека 2 сущности news и article. в итоге все общие методы работы с БД было решено вынести в родительский record.
почему же было не создать класс для удобной работы с БД и, например, в методе update писать db::update( 'news', $this->fields ) ?
и зачем в Active Record наследование, она его не подразумевает. Вот если у тебя вдруг окажется коллекция статей _и_ новостей и тебе надо будет их сохранить, в этом случае оба класса могут реализовать интерфейс Active Record - и пожалуйста, сохраняй ;-)
 

Alexandre

PHPПенсионер
советы Кришны рулят!
Хара Кришна
Хара Рама
Рама Хара!
- начни с изучения классического ООП, примеров в сети миллион
- не надо использовать "паттерны" ради паттернов
или программирование ради программирования
к сожалению, многие этим страдают... в частности и вышеприведенные примеры и фреймворки
хороший был выше совет - ООП надо использовать там, где оно действительно нужно
 

zerkms

TDD infected
Команда форума
почему же было не создать класс для удобной работы с БД и, например, в методе update писать db::update( 'news', $this->fields ) ?
потому что реализация выродилась в AR. а сохранение данных в ORM это несколько более сложный процесс, чем просто 1 update от dbal.

и зачем в Active Record наследование, она его не подразумевает.
посмотри на доктрину, на пропел...

ООП надо использовать там, где оно действительно нужно
чем фреймворк (как гибкий инструмент для разработки) - не место для использования ОО подхода?
 

Alexandre

PHPПенсионер
чем фреймворк (как гибкий инструмент для разработки) - не место для использования ОО подхода?
согл с утверждением
это хорошая тема для флуда, несомненно ООП - это великая вещь
но многие фреймворки на практике не такие гибкие, как хотелось бы
или существующая гибкость за счет производительности.
В итоге - либо модернизируешь существующие (если это возможно), либо разрабатываешь вновь.
 

korchasa

LIMB infected
Автор оригинала: Alexandre
...
или существующая гибкость за счет производительности.
А оно под другому и не может быть. Любая абстракция снижает производительность.
 

atv

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

P.S. А самый гибкий, это событийно-ориентированный подход :)
 
Сверху