PHP 促进水平代码重用的特性

示例

假设我们有一个日志记录接口:

interface Logger {
    function log($message);
}

现在说我们有两个Logger接口的具体实现:FileLogger和和ConsoleLogger。

class FileLogger implements Logger {
    public function log($message) {
        // 将日志消息追加到某些文件
    }
}

class ConsoleLogger implements Logger {
    public function log($message) {
        // 将消息记录到控制台
    }
}

现在,如果您定义了一些Foo您还希望能够执行日志记录任务的类,则可以执行以下操作:

class Foo implements Logger {
    private $logger;

    public function setLogger(Logger $logger) {
        $this->logger = $logger;
    }

    public function log($message) {
        if ($this->logger) {
            $this->logger->log($message);
        }
    }
}

Foo现在也是Logger,但其功能取决于Logger通过传递给它的实现setLogger()。如果现在我们希望类Bar也具有此日志记录机制,则必须在Bar类中复制此逻辑。

无需复制代码,可以定义一个特征:

trait LoggableTrait {
    protected $logger;

    public function setLogger(Logger $logger) {
        $this->logger = $logger;
    }

    public function log($message) {
        if ($this->logger) {
            $this->logger->log($message);
        }
    }
}

现在,我们已经在特征中定义了逻辑,我们可以使用特征将逻辑添加到Foo和Bar类中:

class Foo {
    use LoggableTrait;
}

class Bar {
    use LoggableTrait;
}

并且,例如,我们可以使用这样的Foo类:

$foo = new Foo();
$foo->setLogger( new FileLogger() );

//注意我们如何使用特征作为“代理”来调用Foo实例上的Logger的log方法
$foo->log('my beautiful message');