我需要一个包装类的解释,其中包含一个孩子会理解的例子

时间:2012-02-21 02:14:41

标签: php

我读了this entire post。它描述了包装类对其他有经验的程序员来说是什么,而不是像我这样的新手。

我理解PHP语法,面向对象的概念,但还没有在面向对象的代码中编写我自己的应用程序。在试图弄清楚包装类究竟是什么时,我感到很困惑。我不懂技术术语。

我希望有人回答一个漂亮的详细的儿童描述,这个描述对于理解面向对象程序基础知识的人来说很容易理解,并且已经阅读了几乎所有的php.net语言参考,但没有实际的面向对象编程经验。尚未编写任何申请。

2 个答案:

答案 0 :(得分:18)

由于你所链接的问题的解释非常广泛,我不会再为你重新定义它。相反,我会尝试通过注射示例向您展示。

class Logger {

    private $__logger;

    public function __construct($logger) {
        $class = $logger . "Logger";
        $this->$__logger = new $class();
    }

    public function write($message) {
        $this->$__logger->write($message);
    }
}

所以,上面你有一个类Logger,你可能会用来在某处记录信息。我们并不关心它是如何做到的,我们只是知道它。

现在,我们有几种不同的日志记录可能性......

class DBLogger {

    public function write($message) {
        // Connect to the database and 
        // INSERT $message
    }
}

class FileLogger {

    public function write($message) {
        // open a file and
        // fwrite $message
    }
}

class EMailLogger {

    public function write($message) {
        // open an smtp connection and 
        // send $message
    }
 }

现在,当我们使用记录器时,我们通过执行以下任何操作来执行此操作:

$logger = new Logger("DB");
$logger = new Logger("EMail");
$logger = new Logger("File");

我们始终以同样的方式与$logger互动(即我们称之为write($message))。包装器实例Logger包装实际的日志记录类并代表我们调用它的方法。

上述类型代码的更常见用法是使用配置文件来确定记录器的内容。例如,考虑您希望将日志记录发送到文件的情况。您可能有一个如下所示的配置:

$logging = array( 
               'type' => 'file',
               'types' => array(
                   'file' => array(
                       'path' => '/var/log'
                       'name' => 'app_errors.log'
                    ),
                    'email' => array(
                       'to' => 'webmaster@domain.com',
                       'from' => 'error_logger@domain.com',
                       'subject' => 'Major fail sauce'
                    ),
                    'db' => array(
                        'table' => 'errors',
                        'field' => 'error_message'
                    )
                )
);

您的改编课程可能如下:

class FileLogger {

    public function __construct() {
        // we assume the following line returns the config above.  
        $this->config = Config::get_config("logger");
    }

    public function write($message) {
        $fh = fopen($this->config->path . '/' . $this->config->file);
        fwrite($fh, $message . "\n");
        fclose($fh);
    }
}

我们会对其他adapted类做同样的事情。然后,通过对主Wrapper Logger稍作修改,我们可以使用配置数据创建正确的包装实例,并将其基于配置中定义的type。一旦你有了类似的东西,切换到通过电子邮件记录就像更改配置中的type一样简单。

答案 1 :(得分:2)

包装类只是让他们的子类更容易用于特定环境。编写了许多库以涵盖各种各样的情况,因此使用起来变得麻烦且复杂。很多项目都会为库创建一个包装器,使其更易于使用。

以此PDO类用法为例:

$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();

不要过分担心细节。只知道这些代码行查询数据库。包装类允许使用上述相同的功能:

Db::query('SELECT name, colour, calories
  FROM fruit
  WHERE calories < :calories AND colour = :colour',
  array($calories, $colour));

我们已经将子类的一些繁琐但很少使用的功能移除到易于使用的界面中。在内部,包装器类正在构建对PDO的相同类型的调用,但这是来自开发人员的隐藏

免责声明:这些例子只是......例子。并不意味着展示最佳实践甚至是实用的。