包装类可以用于许多不同的原因。大多数时候,您使用它们来隐藏现有类的功能,以便消费者只能看到有限的接口(外观),或者您也可以使用它们来增强现有类或其方法(装饰器)的功能。有时它们被用作不同接口之间的适配器。
包装类的基本思想是定义一个包含要包装的对象(通常作为私有属性)的类,并定义要使其可访问的方法。如果您的意图是隐藏原始对象的某些方法,则包装类上的方法将是包装对象方法的子集,并将简单地将调用转发给包装对象并返回它返回的任何内容。如果您想扩展对象的功能,您还可以在包装器上定义新方法,这些方法可以执行您希望它们对您的对象执行的任何魔法。
典型的实现可能如下所示:
class SomePhpWrapper {
/**
* The wrapped object
*/
private $wrapped;
/**
* Wrapping constructor
*/
public function __construct(SomePhpClass $object) {
$this->wrapped = $object;
}
/**
* A method of the wrapped object we would like to explose on the wrapper
*/
public function someMethod($someArgument) {
return $this->wrapped->someMethod($someArgument);
}
/**
* A decorated method which calls the wrapper class's method but also does something else
*/
public function query($params) {
$returnValue = $this->wrapper->query($params);
doSomethingFunky();
return $returnValue;
}
/**
* Another exposed method
*/
public function ping() {
return $this->wrapped->ping()
}
/**
* A decorator method that does not exist on the wrapped object but would be useful
*/
public function somethingComplicated() {
$this->wrapped->query(this);
$this->wrapped->query(that);
}
}
这个包装器隐藏了原始类的一些方法,还添加了一个名为somethingComplicated()的新方法。但是,此包装器不是原始类的子类。当您编写使用此包装类的函数时,它们不应该期待 SomePhpClass,而是应该期待 SomePhpWrapper。在你的情况下:
function some_function(SomePhpWrapper $object) {
$object->ping(); // works
$object->somethingComplicated(); // works
$object->getDebug(); //fails, as getDebug() is not exposed by the wrapper
}
要使用这个包装器,你可以这样:
$object = new SomePhpClass();
$wrapper = new SomePhpWrapper($object);
some_function($wrapper);