【问题标题】:Real world abstract class usage simple samples真实世界抽象类使用简单示例
【发布时间】:2010-10-11 08:09:16
【问题描述】:

任何现实世界中使用抽象类的简单示例? 我正在尝试进入 PHP 的 OOP,但我仍然无法理解 - 为什么应该使用抽象类以及何时使用(是的,我知道创建抽象类实例是不可能的,只有继承它的类实例)。

【问题讨论】:

    标签: php oop


    【解决方案1】:

    也许您有一个图像类,并且您有 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
        } 
    }
    

    看看Kohana's source on GitHub。它有一个Image 类,即abstract

    【讨论】:

    • 嗯,我觉得创建interface Image和制作Image_Gd implements Image就够了?
    • @Kirzilla 好吧,是的,你可以这样做。想象一下那个基类中有代码。
    • 最好不要看 Kohana 的来源。这不是 OOP 设计的最佳示例。
    • @Crozin 够公平 - 你推荐什么?
    【解决方案2】:

    好的,假设您要加载脚本配置。该配置可以存储在数据库/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) 方法,它将是 DatabaseConfigurationFileConfiguration 的父类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-24
      • 2016-11-26
      • 2010-11-23
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多