Деревья используются намного больше на языках функционального программирования из-за их рекурсивного характера.
кроме того, графики и деревья являются хорошим способом смоделировать много проблем AI.
ООП - это не только то, как выглядит и работает отдельный класс. Это также о том, как экземпляры одного или нескольких классов работают вместе.
Вот почему вы видите так много примеров, основанных на «Машинах» и «Людях», потому что они действительно хорошо иллюстрируют этот принцип.
В моем По мнению, наиболее важными уроками ООП являются инкапсуляция и полиморфизм .
Инкапсуляция: Связывание данных и логика, которая воздействует на эти данные вместе кратким и логическим образом Полиморфизм: Способность одного объекта выглядеть и / или вести себя как другой.
Хорошим реальным примером этого может быть что-то вроде итератора каталога. Где этот каталог? Может быть, это локальная папка, а может, удаленная, как FTP-сервер. Кто знает!
Вот базовое дерево классов, демонстрирующее инкапсуляцию:
<?php
interface DirectoryIteratorInterface
{
/**
* @return \Traversable|array
*/
public function listDirs();
}
abstract class AbstractDirectoryIterator implements DirectoryIteratorInterface
{
protected $root;
public function __construct($root)
{
$this->root = $root;
}
}
class LocalDirectoryIterator extends AbstractDirectoryIterator
{
public function listDirs()
{
// logic to get the current directory nodes and return them
}
}
class FtpDirectoryIterator extends AbstractDirectoryIterator
{
public function listDirs()
{
// logic to get the current directory nodes and return them
}
}
Каждый класс / объект отвечает за свой собственный метод получения списка каталогов. Данные (переменные) связаны с логикой (функции классов, т. Е. Методы), которые используют данные.
Но история не закончена - помните, как я сказал, что ООП касается того, как экземпляры классов работают вместе, а не какие-либо отдельные класс или объект?
Хорошо, давайте что-нибудь сделаем с этими данными - распечатаем их на экране? Конечно. Но как? HTML? Простой текст? RSS? Давайте рассмотрим это.
<?php
interface DirectoryRendererInterface
{
public function render();
}
abstract class AbstractDirectoryRenderer implements DirectoryRendererInterface
{
protected $iterator;
public function __construct(DirectoryIteratorInterface $iterator)
{
$this->iterator = $iterator;
}
public function render()
{
$dirs = $this->iterator->listDirs();
foreach ($dirs as $dir) {
$this->renderDirectory($dir);
}
}
abstract protected function renderDirectory($directory);
}
class PlainTextDirectoryRenderer extends AbstractDirectoryRenderer
{
protected function renderDirectory($directory)
{
echo $directory, "\n";
}
}
class HtmlDirectoryRenderer extends AbstractDirectoryRenderer
{
protected function renderDirectory($directory)
{
echo $directory, "<br>";
}
}
Хорошо, теперь у нас есть несколько деревьев классов для просмотра и отображения списков каталогов. Как мы их используем?
// Print a remote directory as HTML
$data = new HtmlDirectoryRenderer(
new FtpDirectoryIterator('ftp://example.com/path')
);
$data->render();
// Print a local directory a plain text
$data = new PlainTextDirectoryRenderer(
new LocalDirectoryIterator('/home/pbailey')
);
$data->render();
Теперь я знаю, о чем вы думаете: «Но, Питер, мне не нужны для этого большие деревья классов!» но если вы думаете, что вы упускаете суть, как я подозреваю, вы были с примерами «Автомобиль» и «Люди». Не сосредотачивайтесь на деталях примера - вместо этого попытайтесь понять, что здесь происходит.
Мы создали два дерева классов, где одно ( * DirectoryRenderer
) использует другое ( * DirectoryIterator
) ожидаемым образом - это часто называют контрактом . Экземпляру * DirectoryRenderer
не важно, какой тип экземпляра * DirectoryIterator
он получает, также экземпляры * DirectoryIterator
не заботятся о том, как они отображаются.
Почему? Потому что мы их так спроектировали. Они просто подключаются друг к другу и работают. Это ООП в действии .
Я бы посоветовал вам держаться подальше от каких-либо фреймворков в данный момент, если вы не знаете ООП, копаться в zend или любом другом фреймворке было бы слишком много.
PHP ООП - это брось смешно ... как ха-ха смешно, потому что он поддерживается, но PHP не является языком ООП, таким как java или c #.
Краткий пример, чтобы подчеркнуть мое утверждение:
// define class
class User {
// define properties and methods
public $name = "";
}
// instantiate class
$user = new User; // or new User() or new user, it's all the same
echo $user->name;
, но если вы хотите использовать ООП »на fly "вы можете сделать следующее:
$user = (object) array('name' => 'Peter');
, а затем
$user->name;
, но вы можете использовать ООП, как в java или C #, но не в той же степени - и имейте в виду, популярные системы, такие как wordpress и drupal, не являются чистым ООП ! но вы также можете выполнять наследование и другие вещи ООП для классификации в PHP.
Как сказал астропаник, вы можете взглянуть на исходный код хорошей инфраструктуры или библиотеки PHP. Я рекомендую Zend Framework , он очень модульный и имеет отличный профессиональный дизайн. Я бы сказал, что это очень хороший объектно-ориентированный код PHP.
Тем не менее, я думаю, что этому не так-то легко научиться на огромном фрагменте производственного кода, поскольку он на самом деле не был создан, чтобы вас чему-то научить. Но если вам нужен реальный объектно-ориентированный код PHP, возможно, вам подойдет Zend Framework (или Symfony, или, может быть, CakePHP).