Taking our hiring manager example above. First of all we have an interviewer interface and some implementations for it
interface Interviewer {
public function askQuestions();
}
class Developer implements Interviewer {
public function askQuestions() {
echo 'Asking about design patterns!';
}
}
class CommunityExecutive implements Interviewer {
public function askQuestions() {
echo 'Asking about community building';
}
}
Now let us create our HiringManager
abstract class HiringManager {
// Factory method
abstract public function makeInterviewer() : Interviewer;
public function takeInterview() {
$interviewer = $this->makeInterviewer();
$interviewer->askQuestions();
}
}
Now any child can extend it and provide the required interviewer
class DevelopmentManager extends HiringManager {
public function makeInterviewer() : Interviewer {
return new Developer();
}
}
class MarketingManager extends HiringManager {
public function makeInterviewer() : Interviewer {
return new CommunityExecutive();
}
}
and then it can be used as
$devManager = new DevelopmentManager();
$devManager->takeInterview(); // Output: Asking about design patterns
$marketingManager = new MarketingManager();
$marketingManager->takeInterview(); // Output: Asking about community building.
When to use?
Useful when there is some generic processing in a class but the required sub-class is dynamically decided at runtime. Or putting it in other words, when the client doesn't know what exact sub-class it might need.