策略设计模式

策略设计模式允许我们在运行时改变对象的行为。

假设我们有一个类,可以将一个数字提升到幂,但在运行时,我们想改变这个数字是平方还是立方。

让我们先定义一个接口,一个可以将数字提升到给定幂次的函数:

Unresolved include directive in modules/ROOT/pages/ch05/ch5-07.adoc - include::example$Chapter 5/Strategy/Power.php[]

我们可以相应地通过实现接口来定义 SquareCube 给定数字的类。

下面是我们的 Square 类:

Unresolved include directive in modules/ROOT/pages/ch05/ch5-07.adoc - include::example$Chapter 5/Strategy/Square.php[]

让我们定义我们的 Cube 类:

Unresolved include directive in modules/ROOT/pages/ch05/ch5-07.adoc - include::example$Chapter 5/Strategy/Cube.php[]

我们现在可以构建一个类,该类本质上将使用这些类之一来处理数字。

类如下:

Unresolved include directive in modules/ROOT/pages/ch05/ch5-07.adoc - include::example$Chapter 5/Strategy/RaiseNumber.php[]

现在我们可以使用 index.php 文件演示整个设置:

<?php

require_once('Power.php');
require_once('Square.php');
require_once('Cube.php');
require_once('RaiseNumber.php');

$processor = new RaiseNumber(new Square());

var_dump($processor->raise(5));

输出如预期,52 是 25。

下面是输出:

image 2023 10 31 11 00 07 828

我们可以在 index.php 文件中将 Square 对象与 Cube 对象交换:

<?php

require_once('Power.php');
require_once('Square.php');
require_once('Cube.php');
require_once('RaiseNumber.php');

$processor = new RaiseNumber(new Cube());

var_dump($processor->raise(5));

这是更新后的脚本的输出:

image 2023 10 31 11 01 10 803

到目前为止,一切都很好; 但这很棒的原因是我们可以动态添加实际改变类操作的逻辑。

这是所有这一切的一个相当粗略的演示:

Unresolved include directive in modules/ROOT/pages/ch05/ch5-07.adoc - include::example$Chapter 5/Strategy/index.php[]

因此,为了演示这一点,让我们在 nGET 变量设置为 4 的情况下运行脚本,这应该对数字 4 进行立方,给出输出 64:

image 2023 10 31 11 07 38 084

现在,如果我们传递数字 6,我们期望脚本对数字 6 进行平方,给出输出 36:

image 2023 10 31 11 08 06 204

在这个设计模式中,我们做了很多工作:

  • 我们定义了一系列算法,由一个公共接口绑定,

  • 这些算法是可以互换的;它们可以在不影响客户端实现的情况下进行换入和换出。

  • 我们将每个算法封装在一个类中

现在我们可以独立于使用它的客户端来改变算法。