It doesn't matter in what style you code, the if/else or switch would remain in factory method design pattern. But you can choose where to put the if/else or switch, so that, you can control how to handle the change that your code will face in future. First let me explain, how factory works:
The code you've provided is not actual factory method. Now, I am giving a real life bank problem as an example. Let's say there are a lots of Bank in your country which are handled by different groups of people or govt. Let's say some banks are: NationalBank, IndependentBank, SocialBank etc. Now, SocialBank provides a, b services. But IndependentBank provides b, c services and NationalBank provides a, b, x services. I hope you get the idea. How are you going to design BankFactory now(also note, NationalBank's a service and SocialBank's a service are different and so on...).
Here's the solution:
- Create a abstract class Bank which will be implemented by every Bank in your country.
- Bank abstract class would have a public method named getService() which would build the service and return it for you.
- Bank would also have a abstract method called createService() which is responsible for creating the service. Each Bank will implement the method as they want(cause, each banks services are different, even if the service name is same), and this method will hold your if/else or switch or the changes needs to make.
Let's do some code:
<?php
// interface for BankServices
interface BankService {
public function getServiceName();
// and other necessary methods
}
// NationalBank services
class NationalBankServiceA implements BankService {
private $name;
public function __construct() {
$this->name = "National Bank Service A";
}
public function getServiceName() {
return $this->name;
}
}
class NationalBankServiceB implements BankService {
private $name;
public function __construct() {
$this->name = "National Bank Service B";
}
public function getServiceName() {
return $this->name;
}
}
class NationalBankServiceX implements BankService {
private $name;
public function __construct() {
$this->name = "National Bank Service X";
}
public function getServiceName() {
return $this->name;
}
}
// SocialBank services
class SocialBankServiceA implements BankService {
private $name;
public function __construct() {
$this->name = "Social Bank Service A";
}
public function getServiceName() {
return $this->name;
}
}
class SocialBankServiceB implements BankService {
private $name;
public function __construct() {
$this->name = "Social Bank Service B";
}
public function getServiceName() {
return $this->name;
}
}
// also implement for Independent bank in the same way
abstract class Bank {
abstract public function createService($serviceType);
public function getService($serviceType) {
$bankService = $this->createService($serviceType);
// execute prepare if necessary...
// $bankService.prepare();
// execute other necessary methods
return $bankService;
}
}
// now create NationalBank
class NationalBank extends Bank {
public function createService($serviceType) {
// here goes your if/else or switch block
if($serviceType === "a") {
return new NationalBankServiceA();
}
if($serviceType === "b") {
return new NationalBankServiceB();
}
if($serviceType === "x") {
return new NationalBankServiceX();
}
// throw error, cause type not matched
}
}
// and now create SocialBank
class SocialBank extends Bank {
public function createService($serviceType) {
// here goes your if/else or switch block
if($serviceType === "a") {
return new SocialBankServiceA();
}
if($serviceType === "b") {
return new SocialBankServiceB();
}
// throw error, cause type not matched
}
}
// in this way also create IndependentBank
// Now, lets see how to use all these codes
$nationalBank = new NationalBank();
$socialBank = new SocialBank();
$nationalBankServiceA = $nationalBank->getService("a");
echo $nationalBankServiceA->getServiceName() . "\n";
$socialBankServiceA = $socialBank->getService("a");
echo $socialBankServiceA->getServiceName() . "\n";
?>
The code is pretty self explanatory. I hope you get the idea of Factory Method, and also why and where we should use it.