Простые примеры использования абстрактного класса в реальном мире - PullRequest
3 голосов
/ 11 октября 2010

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

Ответы [ 2 ]

1 голос
/ 22 ноября 2010

ОК, допустим, вы хотите загрузить конфигурацию скрипта. Эта конфигурация может быть сохранена в файле базы данных / XML / INI / YAML. Каждый драйвер должен реализовывать некоторый интерфейс, назовем его ConfigurationLoader.

interface ConfigurationLoader {
    public function load();
    public function get($key, $default = null);
}

// The final usage of the code:

$configuration = new XMLConfiguration('./some/file.xml');
$configuration = new YAMLConfiguration('./some/file.yaml');
$configuration = new DatabaseConfiguration($dbHandler, 'table_name');

$configuration->load();
echo $configuration->get('abc.def.ghi');

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

class DatabaseConfiguration implements ConfigurationLoader {
    protected $config = array();

    protected $pdo, $tableName;

    public function __construct(PDO $dbHandler, $tableName) {
        $this->pdo = $pdo;
        $this->tableName = $tableName;
    }

    public function load() {
        $this->config = /* fetch data from database */;
    }

    public function get($key, $default = null) {
        return array_key_exists($this->config, $key) ? $this->config[$key] : $default;
    }
}

Теперь нам нужно реализовать драйверы XML, INI и YAML. Все они работают почти одинаково, поэтому ... давайте создадим некоторый абстрактный класс, который будет обрабатывать общий код:

 abstract class FileConfiguration implements ConfigurationLoader  {
      // Each file-based configuration loader has a constructor that takes file name as first argument
      protected $filename;

      public function __construct($filename) {
          $this->filename = $filename;
          $this->getFileContents();
      }

      // Each file-based driver has to store file content
      protected $fileContent;

      protected function getFileContents() {
          $this->fileContents = file_get_contents($this->filename);
      }

      // Each driver will have to implement its own implementation of load().
      // XMLConfiguration will parse XML, INIConfiguration will parse INI etc. 
      abstract public function load();

      // However all of them will store parsed configuration in $config array:
      protected $config = array();

      public function get($key, $default = null) {
          return array_key_exists($this->config, $key) ? $this->config[$key] : $default;
      }
 }

FileConfiguration должен быть абстрактным, потому что он не знает, как анализировать содержимое файла. Только поставленные классы знают, как это сделать:

 class XMLConfiguration extends FileConfiguration {
      public function load() {
          $xml = simplexml_load_string($this->fileContents);

          foreach ($xml->root as $config) {
              $this->config[(string) $config->key] = (string) $config->value;
          }
      }
 }

 class YAMLConfiguration extends FileConfiguration {
      public function load() {
          $yaml = new SomeYAMLParser($this->fileContents);

          foreach ($yaml->parse() as $config) {
              $this->config[$config['key']] = $config['value'];
          }
      }
 }

 class INIConfiguration extends FileConfiguration {
      public function load() {
          ...
      }
 }

Как вы можете видеть в этом примере, может быть даже еще один абстрактный класс AbstractConfiguration, который будет хранить свойство $config и метод get($key, $default = null), и это будет родительский класс для DatabaseConfiguration и FileConfiguration.

1 голос
/ 11 октября 2010

Возможно, у вас есть класс изображений, и у вас есть 2 драйвера, GD и ImageMagick.

Ваш базовый класс может быть

abstract class Image {

    public function resize($width, $height) {
        // Some prep code...
    }
}

Тогда ваш драйвер GD будет похож на

class Image_Gd extends Image {
    public function resize($width, $height) {
        // Actual code
    } 
}

Посмотрите на источник Коханы на GitHub . Он имеет класс Image, который abstract.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...