I'm building a service to send push notifications to the user.
At first, I designed an Interface for the push notification adapters, something like this:
interface PushNotificationAdapterInterface
{
/**
* @throws NotificationException
*/
function sendNotification(string $appIdentifier, PushNotificationTemplate $pushNotificationTemplate): void;
}
class PushNotificationTemplate
{
public function __construct(
private string $to,
private string $from,
private string $title,
private string $body
)
{
}
}
I tried to model the interface based on the basic needs required to send a push notification, which usually is: "to" (where to send), "from" (who is sending), "title", and "body".
the problem:
Not all the concrete adapters would use the PushNotificationTemplate
properties to send the notification
and in theory, I know that this should not be a problem/concern to the interface, but it should for those who implement it.
Some adapters are too different to conform to this interface, an example is one that uses an API to send the notification, using only specific params of the API and not using a single property of PushNotificationTemplate
API example:
class ApiPushNotificationAdapter implements PushNotificationAdapterInterface {
public function __construct(
private string $customApiParam1,
private string $customApiParam2,
//... more params
)
{
}
function sendNotification(string $appIdentifier, PushNotificationTemplate $pushNotificationTemplate): void
{
// not using $pushNotificationTemplate
}
}
one problem with this specific adapter:
some constructor
parameters should be used in the sendNotification()
method because they're are dynamic and should be changed with ease, such as title and body (the API uses a different approach, with a template_id
being a constructor parameter)
Firebase implementation example that fits the Interface:
class FirebasePushNotificationAdapter implements PushNotificationAdapterInterface {
public function __construct(
private string $googleApiKey,
private string $googleSDK,
//... more params
)
{
}
function sendNotification(string $appIdentifier, PushNotificationTemplate $pushNotificationTemplate): void
{
$this->googleSDK->send(
$pushNotificationTemplate->to(),
$pushNotificationTemplate->from(),
$pushNotificationTemplate->title(),
//....
)
}
}
I thought about using an array
as the second parameter, but I don't like it at all, being an array takes out the standardization and wouldn't be useful or meaningful for all the adapters.
I know that these are low-level implementation details that could be passed into the constructor
, but in the end, not all adapters would use the PushNotificationTemplate
properties or even the appIdentifier variable
What are some good approaches/patterns to solve this scenario? create some kind of abstract factory for different adapters? does it even fit as an adapter?