John Davidson

PHP OOP Factory pattern and Open/Closed principle

0 comments
Message:


I would like to implements PHP notifications system with PHP OOP. I have many notifications type and each notification will do custom work and checks user settings before showing notification to users. I add Notification abstract class to fix Notification behaviour for all notifications types.


abstract class Notification {     
private $notificationType;

public function __construct(int $type) {
$this->notificationType=$type;
}

//put your code here
public abstract function notify(array $user_settings);
}

Then I extend parent Notification class with childrens classes like this:


    class AddRequestNotifiation extends Notification{
//put your code here
public function __construct() {
parent::__construct(1);
}
public function notify(array $user_settings) {
echo "custom ad request work here";
}
}

//----
class LikesNotification extends Notification{
//put your code here
public function __construct() {
parent::__construct(2);
}
public function notify(array $user_settings) {
echo "custom likes work here";
}
}

Now I would like to implements Factory pattern.


class NotificationFactory {
//put your code here
public static function buildNotification(int $type){
if($type==1){
return new AddRequestNotifiation();
}else if($type==2){
return new LikesNotification();
}else{
throw new Exception("not implemented");
}
}
}

Then in index.html


$notification= NotificationFactory::buildNotification(1);
$notification->notify([]);

I know that Factory is bad because it d'ont respect O/C principle and i need to modify it to add new Notification type so I choose another approche like below :


class NotificationFactory {
//put your code here
private $notifications=array();

public function addNotificationType(int $type, Notification $n){
if(!array_key_exists($type,$this->notifications)){
$this->notifications[$type]=$n;
}
}

public function buildNotification(int $type):Notification{
if(!array_key_exists($type,$this->notifications)){
throw new Exception("Not Implemented");
}else{
return $this->notifications[$type];
}
}
}

Then I populated factory with all notifications types.


    spl_autoload_register(function($class){
include $class .".php";
});

// initialisation
$notification_factory= new NotificationFactory();
$notification_factory->addNotificationType(1, new AddRequestNotifiation());
$notification_factory->addNotificationType(2, new LikesNotification());
// adding new custom notification
$notification_factory->addNotificationType(12, new CustomNotification());

/// then when Notification arrive
$notification = $notification_factory->buildNotification(2);
$notification->notify([]);

With this approche O/C principle is respected but there is big probleme with memory and ressource using befaore I must instanciate all notifications type even when I d'ont use them . what is the optimised solution for this.



My Answer:
One possible solution to optimize memory and resource usage in this scenario is to lazy load the notification objects only when they are needed. This can be achieved by using a lazy loading approach in the NotificationFactory class. Here's an example implementation:

php
class NotificationFactory {
//put your code here
private $notifications=array();

public function addNotificationType(int $type, string $className){
if(!array_key_exists($type,$this->notifications)){
$this->notifications[$type]=$className;
}
}

public function buildNotification(int $type):Notification{
if(!array_key_exists($type,$this->notifications)){
throw new Exception("Not Implemented");
}else{
$className = $this->notifications[$type];
return new $className();
}
}
}


In this updated implementation, the addNotificationType method now accepts the class name of the notification instead of an instance of the notification object. The buildNotification method then dynamically creates an instance of the notification class using the class name when it is requested.

This way, you only instantiate the notification objects when they are actually needed, reducing memory and resource usage. You can continue to add new notification types to the factory without having to instantiate all of them upfront.

Hope this helps! Let me know if you have any further questions.

Rate this post

3 of 5 based on 5788 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us