ООП - использование одного объекта внутри другого

korpus

злой бобёр
ООП - использование одного объекта внутри другого

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

Класс "block1". Необходим, чтобы вывысти какой-то элемент страницы в браузер.
Код:
class block1
{
  public function __construct()
  {

  echo '
  <div>';

  //Здесь выполняются какие-то операции и что-то выводится на  страницу 

  echo '
  </div>';
  }
}
Класс "block2". Этот класс выводит другой блок данных.
Код:
class block2
{
  public function __construct()
  {

  echo '
  <div>';

  //Здесь выполняются какие-то операции и что-то выводится на  страницу 

  echo '
  </div>';
  }
}
Класс "forma". Необходим, чтобы вывести в браузер типовую форму, используемую во всех блоках (а таких блоков может быть и два и больше). Предположим, что эта форма настолько сложна, что ей необходимо подключаться к базе данных, обрабатывать данные из неё и вообще лучше один раз написать код и использовать его многократно, поэтому она и сделана в виде отдельного класса. Функция print_this() выводит в браузер html-код формы.
Код:
class forma
{

  public function __construct()
  {
    //Что-то делается
  }


  public function print_this()
  {
    echo '....'; //выводится html-код формы
  }
}

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

Я вижу только два решения
1 способ) создавать объект с формой forma в самих классах block1 и block2 и использовать его там. Но так как блоков 2, то 2 раза будут производится одни и те же операции и 2 раза будет подключение к БД.
Пример:
Код:
class block1
{
  public function __construct()
  {
  include_once('forma.php');//подключается скрипт с определением класса forma
  $forma=new forma();

  echo '
  <div>';

  //Здесь выполняются какие-то операции и что-то выводится на главную страницу 

  $forma->print_this(); //выводится форма

  //что-то делается

  echo '
  </div>';

  }
}
2 способ) Объект класса forma создаётся раньше, чем классы block1 или block2 и передаётся как параметр при инициализации этих классов. при этом один раз происходит подключение к базе данных, что конечно же хорошо.
Пример:
Код:
include('block1.php');
include('forma.php');
$forma=new forma;
$block1=new block1($forma);

Класс block1 при этом переделывается таким образом:
Код:
class block1
{
  private $forma;
  public function __construct(forma $forma)
  {
  $this->forma=$forma;

  echo '
  <div>';

  $this->forma->print_this(); //выводится форма

  echo '
  </div>';
  }
}
Насколько второй вариант корректен с точки зрения ООП в PHP5? Можно ли объект глобальный $forma записать в закрытую переменную внутри объета класса block1 и использовать его там, учитывая, что объект $forma будет использоваться в другом объекте класса block2? Что вообще происходит с объектом, если его передать как параметр в функцию другого объекта?
Если способ 2 неправильный, то как надо поступать?
 

Adelf

Administrator
Команда форума
Ну.. с точки зрения ООП форма у тебя слишком много умеет делать :)
Правильнее работу с базой в одном месте. А форма уже использует его. И т.д.
А уже потом обсуждать как ее включать в другие обьекты.

А еще лучше вот - посмотри готовые фреймворки(Zend Kohana). Их коды. Поучись. Там много интересного.
 

Духовность™

Продвинутый новичок
Тут целый букет вопросов и ответов.

Как мне спроектировать его, чтобы он был правильный с точки ООП?
Читал - http://wiki.agiledev.ru/doku.php?id=ooad:dependency_injection ?

Но так как блоков 2, то 2 раза будут производится одни и те же операции и 2 раза будет подключение к БД.
Класс "forma". Необходим, чтобы вывести в браузер типовую форму, используемую во всех блоках (а таких блоков может быть и два и больше). Предположим, что эта форма настолько сложна, что ей необходимо подключаться к базе данных, обрабатывать данные из неё
этот класс обречен на вечные муки, страшный суд, АдЪ и погибель. Класс не должен выполнять куеву тучу действий. Класс должен предназначаться для ограниченного количества конкретных операций, а тут и подключение к базе и проверка и чего только нет!

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

-~{}~ 22.12.09 22:06:

2 раза будет подключение к БД
http://ru.wikipedia.org/wiki/Синглтон

Ну и
в классе убивает...
 

korpus

злой бобёр
Автор оригинала: triumvirat

Ну и
в классе убивает...
Это только пример. Ведь можно сделать объект, который выводит html-код формы?

Из ответов я понял, что действительно ничего не понимаю в архитектуре ООП.
Критика, надеюсь, справедливая. Но посоветуйте тогда и предложите архитектуру. Как сделать, чтобы в html-коде в разных местах (или даже на разных страницах) отображались одни и те же данные, взятые из БД. Я считаю, что делаю примерно правильно, потому что код становится проще, если сделать классы, внутри которых будут выполняться все нужные операции. В таком случае не надо заботиться о том, чтобы выполнять какие-то дополнительные действия, вызывать дополнительные методы например: $block1->dosomething(). Т.е. здесь у объектов простая задача - убрать повторяющийся код и сократить объем текста в скрипте.

Если внутри класса block1 поместить определение класса forma, тогда не надо заботиться об этом классе forma. Подключил скрипт с классом block1 с помощью include, а внутри него уже выполняются все нужные операции.

Если знаете корректное решение задачи, прошу привести код.
 

dimagolov

Новичок
объектов простая задача - убрать повторяющийся код и сократить объем текста в скрипте.
это не задача ООП. для убирания повторяющегося кода достаточно ф-й.
 

Adelf

Administrator
Команда форума
korpus
функций. твои обьекты от функций не отличаются вообще никак. ту же $forma можно просто передавать в эти функции как параметр и все.
Ты пока не умеешь мыслить обьектами. Поэтому цитирую самого себя:
посмотри готовые фреймворки(Zend, Kohana). Их коды. Поучись. Там много интересного.
 

dimagolov

Новичок
я имел в виду функции. include это способ подключать нужные наборы ф-ий и разделять код
 

Духовность™

Продвинутый новичок
Но посоветуйте тогда и предложите архитектуру.
книшки какие читал по теме?

Попробуй разложить веб-сайт, свою гипотетическую программу, на Слои, а слои разложи на Классы. И расскажи нам что получилось.

-~{}~ 23.12.09 16:52:

и на вот http://phpclub.ru/talk/showthread.php?s=&threadid=117497&rand=4
 

korpus

злой бобёр
Автор оригинала: triumvirat
книшки какие читал по теме?

Попробуй разложить веб-сайт, свою гипотетическую программу, на Слои, а слои разложи на Классы. И расскажи нам что получилось.

-~{}~ 23.12.09 16:52:

и на вот http://phpclub.ru/talk/showthread.php?s=&threadid=117497&rand=4
А попроще нет чего? Чтоб доходчиво объяснялись принципы построения систем с помощью ООП
 

440hz

php.ru
Чтоб доходчиво объяснялись
что бы доходчиво понимались объяснения, надо знать некоторые вещи и иметь как минимум опыт.

ты взял взял этого слишком большую задачу.

ставь задачи поменьше, делай их и тогда придет понимание и опыт.
 

Духовность™

Продвинутый новичок
А попроще нет чего? Чтоб доходчиво объяснялись принципы построения систем с помощью ООП
начни с http://www.ozon.ru/context/detail/id/3600968/ и мануала. Как только будешь знаком с синтаксисом и средствами ОО проектирования в PHP, начинай читать всякие умные книжки.
 

korpus

злой бобёр
Спасибо всем за советы. Начал более углублённо ООП изучать и стало ясно, что для этого надо не в одну книжку заглянуть. Особенно спасибо Adelf за ссылку на интересный фреймворк Kohana.
 
Сверху