代理模式
代理(Proxy)是一个类,它只是其他东西的一个接口。它可以是任何东西的接口,包括网络连接、文件、内存中的大型对象或任何其他难以复制的资源。
在我们的示例中,我们将创建一个简单的代理,根据代理的实例化方式,转发给两个对象中的一个。
通过访问一个简单的代理类,客户端可以从一个对象访问猫和狗的两个喂食器,具体取决于它是否已被实例化。
首先,让我们为 AnimalFeeder
定义一个接口:
Unresolved include directive in modules/ROOT/pages/ch04/ch4-07.adoc - include::example$/Chapter 4/Proxy/AnimalFeeder.php[]
这样,我们就可以为一只猫和一只狗定义两个动物饲养器:
Unresolved include directive in modules/ROOT/pages/ch04/ch4-07.adoc - include::example$/Chapter 4/Proxy/AnimalFeeders/Cat.php[]
这是我们的狗狗 AnimalFeeder:
Unresolved include directive in modules/ROOT/pages/ch04/ch4-07.adoc - include::example$Chapter 4/Proxy/AnimalFeeders/Dog.php[]
有了这些定义,我们现在就可以创建代理类了,这个类基本上是使用构造函数来解读它需要实例化的类的类型,然后将所有函数调用重定向到这个类。为了重定向函数调用,我们使用了 __call
魔术方法。
它看起来像这样:
Unresolved include directive in modules/ROOT/pages/ch04/ch4-07.adoc - include::example$/Chapter 4/Proxy/AnimalFeederProxy.php[]
您可能已经注意到,我们必须在构造函数中手动创建带有命名空间的类。我们使用 __NAMESPACE__
魔术常量来查找当前的命名空间,然后将其连接到类所在的特定子命名空间。请注意,我们必须使用另一个 \
来转义 \
,这样才能在指定命名空间时不被 PHP 解释为转义字符。
让我们创建 index.php 文件并利用代理类来创建对象:
Unresolved include directive in modules/ROOT/pages/ch04/ch4-07.adoc - include::example$/Chapter 4/Proxy/index.php[]
输出如下:
chicken
chicken with water
turkey and beef
turkey and beef with water
那么在现实中如何使用呢?假设您从数据库中获得了一条记录,其中包含一个详细说明了动物类型和名称的对象;您只需将此对象传递给代理类的构造函数,并将其作为创建类的机制。
在实践中,这在支持资源消耗型对象时有很好的用例,除非客户真的需要,否则你不一定要实例化这些对象;同样的情况也可能发生在资源消耗型网络连接和其他类型的资源上。