/** * This is the public service provided by this class and its subclasses. * Notice it is final to "freeze" the global behavior of algorithm. * If you want to override this contract, make an interface with only takeATrip() * and subclass it. */ finalpublicfunctiontakeATrip() { $this->thingsToDo[] = $this->buyAFlight(); $this->thingsToDo[] = $this->takePlane(); $this->thingsToDo[] = $this->enjoyVacation(); $buyGift = $this->buyGift();
if ($buyGift !== null) { $this->thingsToDo[] = $buyGift; }
$this->thingsToDo[] = $this->takePlane(); }
/** * This method must be implemented, this is the key-feature of this pattern. */ abstractprotectedfunctionenjoyVacation(): string;
/** * This method is also part of the algorithm but it is optional. * You can override it only if you need to */ protectedfunctionbuyGift(): ?string { returnnull; }
privatefunctionbuyAFlight(): string { return'Buy a flight ticket'; }
privatefunctiontakePlane(): string { return'Taking the plane'; }
classJourneyTestextendsTestCase { publicfunctiontestCanGetOnVacationOnTheBeach() { $beachJourney = new BeachJourney(); $beachJourney->takeATrip();
$this->assertSame( ['Buy a flight ticket', 'Taking the plane', 'Swimming and sun-bathing', 'Taking the plane'], $beachJourney->getThingsToDo() ); }
publicfunctiontestCanGetOnAJourneyToACity() { $cityJourney = new CityJourney(); $cityJourney->takeATrip();
$this->assertSame( [ 'Buy a flight ticket', 'Taking the plane', 'Eat, drink, take photos and sleep', 'Buy a gift', 'Taking the plane' ], $cityJourney->getThingsToDo() ); } }