定义一系列算法,封装每个算法,并使它们可互换。策略使算法独立于使用该算法的客户端而变化。
通勤是我们日常生活的一部分。每天,当我们离开家上班时,我们必须选择交通工具。作为通勤者,我们有很多选择,出租车,公共汽车或火车,这实际上取决于我们的心情和我们所处的状况。就像你出门时间来得很晚而赶时间一样,那么你可能会乘出租车 。在另外的某天,如果你有充足的时间并不在有没有座位,那么乘公共汽车是一个不错的选择。在我们想要确保我们准时到达某个位置而又不会遇到交通拥堵的麻烦的日子里,我们会坐火车。
这是一个策略模式的完美示例。
公共汽车,火车和出租车都是交通工具,但它们当然在许多方面有所不同。它们在成本上彼此不同,并且它们采用不同的路线将您带到目的地。它们是相同的,因为尽管旅行时间长短不一,但它们都是到达目的地的一种方式。他们都属于一个范畴,即运输。
我们首先来创建一个关于运输(Transportation
)的接口:
interface Transportation
{
function transport(Passenger $passenger);
}
创建一个实现Transportation
接口的Bus
类:
class Bus implements Transportation
{
public function transport(Passenger $passenger)
{
echo '通过路线A带你到达目的地';
}
}
创建一个实现Transportation
接口的Train
类:
class Train implements Transportation
{
public function transport(Passenger $passenger)
{
echo '通过路线B带你到达目的地';
}
}
创建一个实现Transportation
接口的Taxi
类:
class Taxi implements Transportation
{
public function transport(Passenger $passenger)
{
echo '通过路线C带你到达目的地';
}
}
最后,我们需要创建一个乘客(Passenger
)类来代表我们:
class Passenger
{
private $_transportation = null;
public function goToWork()
{
$this->_transportation->transport($this);
}
public function chooseTransport(Transportation $transportation)
{
$this->_transportation = $transportation;
}
}
接下来我们来看看,乘客如何在上下文中使用不同的交通工具:
$john = new Passenger();
$bus = new Bus();
$train = new Train();
$taxi = new Taxi();
// 乘坐公交车
$john->chooseTransport($bus);
$john->goToWork();
// 乘坐火车
$john->chooseTransport($train);
$john->goToWork();
// 乘坐的士
$john->chooseTransport($taxi);
$john->goToWork();
公交车(Bus
),火车(Train
)和出租车(Taxi
)的类与乘客(Passenger
)的类有所不同,因为它们都实现了运输(Transportation
)接口。
在我们的示例中,通过应用策略模式,我们定义了算法(公交车,火车和出租车)的范畴(运输范畴),封装了每个算法(Passenger
乘客类仅知道运输(Transportation
)接口),并使它们可互换(它们实现了通用接口) )。策略使算法独立于使用该算法的客户端(Passenger
类)而变化。