jeudi 8 février 2018

Using different image drivers

<?php
interface InterfaceImage {

    public function crop();
    public function resize();
}


class GD implements InterfaceImage {

    public function crop() {}
    public function resize() {}
}


class ImageMagick implements InterfaceImage {

    public function crop() {}
    public function resize() {}
    public function rotate() {}
}


class Image {

    private $driver;
    private $image;

    public function setDriver($driver) {
        $this -> driver = new $driver();
    }

    public function setImage($image) {
        $this -> image = $image;
    }

    public function __call($method, $params) {

        if(true === is_callable([$this -> driver, $method])) {
            return call_user_func_array([$this -> driver, $method], array_merge([$this -> image], func_get_args()));
        }
    }
}


$image = new Image();
$image -> setDriver('GD');
$image -> setImage('path/to/image');
$image -> crop();
$image -> rotate(); //Dit is enkel beschikbaar bij de ImageMagick driver
?>

The above is example code which enables the user to crop and resize images. Cropping and resizing can be done via PHP's GD library or via ImageMagick, but I want the user to have only one class to use the functionality.

This is a use case but this can just as easily be made with databases classes o.i.d.

Now I have three questions:

Question 1: I have created an interface for both "drivers" only the ImageMagick driver can do much more than the GD driver. As an example I added a "rotate" functionality which is not supported by the GD driver. This means that on the basis of the chosen driver, functionality is added to the Image class. Is this the right way or does this go against certain design pattern rules?

Question 2: At the moment I check if the functionality exists of the driver in the Image class by creating a universal "__call" method that controls that. I can also implement all the separate functions which the drivers have but because the GD driver has fewer functions than the ImageMagick driver, that may not be a good idea because there is a function in the Image class for a function in the driver that does not have to to exist. What is best practice here?

Question 3: Is there a specific design pattern for this? It looks both on the factory design pattern and also on the proxy design pattern and a bit of the bridge design pattern.

I'm not sure if I'm approaching this in the right way.

Aucun commentaire:

Enregistrer un commentaire