Öncelikle her Sms gönderim hizmeti sağlayacısında kullanacağımız bir interface tanımlıyoruz:
interface SmsNotificationInterface
{
public function send(SmsNotificationMessageData $message): SmsNotificationResultData;
public function isSupport(string $companyCode): bool;
}
Akabinde aşağıdaki gibi somut sınıflarımızı bu arayüzden implement ediyoruz:
class XCompanySmsNotification implements SmsNotificationInterface
{
private string $companyCode = "XCompany";
public function send(SmsNotificationMessageData $message): SmsNotificationResultData
{
// sms gönderim işlemi burada yapılıyor.
}
public function isSupport(string $companyCode): bool
{
return $companyCode == $this->companyCode;
}
}
class YCompanySmsNotification implements SmsNotificationInterface
{
private string $companyCode = "YCompany";
public function send(SmsNotificationMessageData $message): SmsNotificationResultData
{
// sms gönderim işlemi burada yapılıyor.
}
public function isSupport(string $companyCode): bool
{
return $companyCode == $this->companyCode;
}
}
Şimdi bize bu gelen veriye göre hangi somut sınıfın kullanılacağını belirleyen ve işlemi yapıp sonucu return eden bir sınıf lazım. Bunun için bir manager yazıyoruz:
class SmsNotificationManager
{
protected array $notificationProviders;
public function __construct(array $notificationProviders = [])
{
foreach ($notificationProviders as $notificationProvider) {
$this->addNotificationProviders($notificationProvider);
}
}
private function addNotificationProviders(SmsNotificationInterface $smsNotification)
{
$this->notificationProviders[] = $smsNotification;
}
public function send(SmsNotificationMessageData $message): SmsNotificationResultData|\Exception
{
foreach ($this->notificationProviders as $notificationProvider) {
if ($notificationProvider->isSupport($message->companyCode)) {
return $notificationProvider->send($message);
}
}
throw new \Exception("Desteklenmeyen bir şirket bilgisi girildi.");
}
}
Service provider içinde SmsNotificationManager çağrıldığında __construct methoduna enjekte edilecek sınıfları yazıyoruz. Artık yeni bir şirket eklediğimizde buradan somut sınıfı eklememiz yeterli olacak.
$this->app->singleton(SmsNotificationManager::class, function () {
$notificationProviders = [
$this->app->make(XCompanySmsNotification::class),
$this->app->make(YCompanySmsNotification::class),
];
return new SmsNotificationManager($notificationProviders);
});
Controller de aşağıdaki gibi sadece send methodunu yazarak işlemi halledebiliriz:
class SmsController
{
private SmsNotificationManager $smsNotificationManager;
public function __construct(SmsNotificationManager $smsNotificationManager)
{
$this->smsNotificationManager = $smsNotificationManager;
}
public function index(SmsNotificationRequest $request)
{
// ...
$smsNotificationMessageData = SmsNotificationMessageData::fromRequest($request);
$smsNotificationResult = $this->smsNotificationManager->send($smsNotificationMessageData);
// ...
}
}