PHP: пример ООП Реального мира

Деревья используются намного больше на языках функционального программирования из-за их рекурсивного характера.

кроме того, графики и деревья являются хорошим способом смоделировать много проблем AI.

46
задан Eric Leschinski 11 December 2013 в 19:36
поделиться

3 ответа

ООП - это не только то, как выглядит и работает отдельный класс. Это также о том, как экземпляры одного или нескольких классов работают вместе.

Вот почему вы видите так много примеров, основанных на «Машинах» и «Людях», потому что они действительно хорошо иллюстрируют этот принцип.

В моем По мнению, наиболее важными уроками ООП являются инкапсуляция и полиморфизм .

Инкапсуляция: Связывание данных и логика, которая воздействует на эти данные вместе кратким и логическим образом Полиморфизм: Способность одного объекта выглядеть и / или вести себя как другой.

Хорошим реальным примером этого может быть что-то вроде итератора каталога. Где этот каталог? Может быть, это локальная папка, а может, удаленная, как 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 не заботятся о том, как они отображаются.

Почему? Потому что мы их так спроектировали. Они просто подключаются друг к другу и работают. Это ООП в действии .

81
ответ дан 26 November 2019 в 20:22
поделиться

Я бы посоветовал вам держаться подальше от каких-либо фреймворков в данный момент, если вы не знаете ООП, копаться в 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.

1
ответ дан 26 November 2019 в 20:22
поделиться

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

Тем не менее, я думаю, что этому не так-то легко научиться на огромном фрагменте производственного кода, поскольку он на самом деле не был создан, чтобы вас чему-то научить. Но если вам нужен реальный объектно-ориентированный код PHP, возможно, вам подойдет Zend Framework (или Symfony, или, может быть, CakePHP).

1
ответ дан 26 November 2019 в 20:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: