我需要一个包装类的解释,以及一个孩子会理解的例子

php
2022-08-30 23:18:45

我读了整篇文章。它向其他有经验的程序员描述了包装类是什么,但对于像我这样的新手却没有。

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

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


答案 1

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

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");

我们总是以相同的方式与之交互(即我们称之为)。包装器实例包装实际的日志记录类,并代表我们调用其方法。$loggerwrite($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);
    }
}

我们将对其他类执行相同的操作。然后,通过对主包装器进行一些修改,我们可以使用配置数据创建正确的包装实例,并将其基于配置中定义的实例。一旦你有了类似的东西,切换到通过电子邮件登录就像在配置中更改一样简单。adaptedLoggertypetype


答案 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 的相同类型的调用,但这是对开发人员隐藏的

免责声明:例子就是这样。例子。不是为了展示最佳实践,甚至不是为了实用。


推荐