PHP OOP工厂模式和开放/关闭原则

发布于 2025-01-21 21:38:41 字数 2851 浏览 2 评论 0原文

我想用PHP OOP实现PHP通知系统。我有许多通知类型,每个通知将进行自定义工作,并在向用户显示通知之前检查用户设置。我添加通知抽象类以修复所有通知类型的通知行为。

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

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

然后,我使用这样的儿童课程扩展父母通知课:

    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";
    }
}

现在我想实现工厂模式。

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");
        }
    }
}

然后在index.html中,

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

我知道工厂很糟糕,因为它尊重O/C原理,我需要对其进行修改以添加新的通知类型,因此我选择了下面的另一种征用:

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];
        } 
    }
}

然后我填充了所有通知类型的工厂。

    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([]);

有了这种批准的O/C原理,但是使用Befaore的内存和Ressource存在很大的问题,即使我使用它们,我也必须将所有通知类型进行实例化。对此的优化解决方案是什么。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏天碎花小短裙 2025-01-28 21:38:41

经过一些调查,我发现另一种模式女巫更适合我的要求,即尊重O/C原理,并且不使用太多记忆。这种模式不多使用,也称为代理。
在HAW下,我实现了它:

    interface NotificationInterface {
        //put your code here
        public function notify();
    }

class LikesNotification implements NotificationInterface{
    //put your code here
    public function notify() {
        echo "Likes Notification content".PHP_EOL;
    }    
}

class AddRequestNotification implements NotificationInterface{
    //put your code here
    public function notify() {
        echo "Add Request Notification Content" .PHP_EOL;
    }    
}

然后我使用了通知代理类。为此,我使用魔术PHP方法__call()Witch Fire(如果类的对象实例都使用类未在类中实现的方法调用)。

class NotificationProxy {    
    //put your code here
    protected $instance;
    
    public function __construct($type) {
       $class=$type."Notification";
       $this->instance=new $class();
    }
    
    public function __call($name, $arguments) {
        return call_user_func_array([$this->instance,$name],$arguments);
    }
}

然后,在index.php中,我仅致电JSON收到的适当通知类:

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

/** we get incoming Notification JSON { 'type':'Likes'} **/
$notification_Proxy=new NotificationProxy("Likes");
$notification_Proxy->notify();

/** if incoming Notification JSON has type { 'type':'AddRequest'} **/
$notification_Proxy=new NotificationProxy("AddRequest");
$notification_Proxy->notify();

这就是我希望该解决方案对其他人有帮助。

After some investigations I found another pattern witch is more appropriate to my requirement, that respect O/C principle and not use much memory ressources. This Pattern is not much used and called Proxy.
Below haw I implemented it:

    interface NotificationInterface {
        //put your code here
        public function notify();
    }

class LikesNotification implements NotificationInterface{
    //put your code here
    public function notify() {
        echo "Likes Notification content".PHP_EOL;
    }    
}

class AddRequestNotification implements NotificationInterface{
    //put your code here
    public function notify() {
        echo "Add Request Notification Content" .PHP_EOL;
    }    
}

Then I used a Notification proxy class. for this I used the magic php method __call() witch fire by default if an object instance of class is called with a method that is not implemented in class.

class NotificationProxy {    
    //put your code here
    protected $instance;
    
    public function __construct($type) {
       $class=$type."Notification";
       $this->instance=new $class();
    }
    
    public function __call($name, $arguments) {
        return call_user_func_array([$this->instance,$name],$arguments);
    }
}

Then in index.php I called only the appropriate Notification class by json received type:

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

/** we get incoming Notification JSON { 'type':'Likes'} **/
$notification_Proxy=new NotificationProxy("Likes");
$notification_Proxy->notify();

/** if incoming Notification JSON has type { 'type':'AddRequest'} **/
$notification_Proxy=new NotificationProxy("AddRequest");
$notification_Proxy->notify();

That is all I hope that this solution will be helpfull to someone else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文