Factory method in PHP

Gepubliceerd: 30.06.2021

Fabrieksmethode is een generatief ontwerppatroon dat het probleem van het maken van verschillende producten oplost zonder specifieke productklassen te specificeren.

De fabrieksmethode definieert de methode die moet worden gebruikt in plaats van de new operator aan te roepen om productobjecten te maken. Subklassen kunnen deze methode overschrijven om het type producten dat ze maken te wijzigen.

Dit PHP patroon is vaak te vinden in elke PHP-code waar flexibiliteit vereist is bij het maken van producten.

Een PHP fabrieksmethode kan worden geïdentificeerd door methoden te maken die productobjecten retourneren via abstracte typen of interfaces. Hiermee kunt u de gegenereerde producttypen in PHP subklassen overschrijven.

In dit voorbeeld biedt het Factory Method-patroon een interface voor het maken van connectoren naar online bestandsopslag die kunnen worden gebruikt om in te loggen bij de cloudproviders, nieuwe bestanden en mappen te maken en mogelijk andere acties uit te voeren - allemaal zonder de clientcode aan bepaalde klassen te binden van een bepaalde cloudprovider voor bestandsopslag.

PHP Code:

  
    <?php

    namespace FourbisCom\FactoryMethod\FileCloudStorage;

    /**
     * De maker declareert een fabrieksmethode die kan worden gebruikt in plaats van directe oproepen naar de productconstructeur, bijvoorbeeld:
     *
     * - Voor: $p = new FourbisComFileCloudConnector();
     * - Na: $p = $this->getFileCloudConnector();
     *
     * Hierdoor kunnen CloudFile-subklassen het type product dat ze maken, wijzigen.
     */
    abstract class CloudFile
    {
        /**
          * Werkelijke fabrieksmethode. Merk op dat het terugkeert
          * abstracte connector. Hierdoor kunnen subklassen elke retourneren
          * specifieke connectoren zonder het superklasse-contract te verbreken.
        */
        abstract public function getFileCloudConnector(): FileCloudConnector;

        /**
          * Wanneer de fabrieksmethode wordt gebruikt binnen de bedrijfslogica van de Schepper,
          * subklassen kunnen logica indirect wijzigen door terug te keren van een fabrieksmethode
          * verschillende soorten connectoren.
        */
        public function folder($folderName): void
        {
            // De fabrieksmethode aanroepen om een object te maken ...
            $fileConnector = $this->getFileCloudConnector();
            // ... en gebruik het dan naar eigen inzicht.
            $fileConnector->logIn();
            $fileConnector->createFolder($folderName);
            $fileConnector->logout();
        }
    }

	/**
      * Deze class ondersteunt FourbisComFileCloud. Onthoud dat deze les
      * neemt ook de mapmethode over van de bovenliggende klasse. Specifieke makers -
      * dit zijn de klassen die de Klant daadwerkelijk gebruikt.
      */
    class FourbisComCloudFile extends CloudFile
    {
        private $login, $password;

        public function __construct(string $login, string $password)
        {
            $this->login = $login;
            $this->password = $password;
        }

        public function getFileCloudConnector(): FileCloudConnector
        {
            return new FourbisComFileCloudConnector($this->login, $this->password);
        }
    }

	/**
      * Deze class ondersteunt DropboxFileCloud.
      */
    class DropboxFileCloud extends CloudFile
    {
        private $login, $password;

        public function __construct(string $login, string $password)
        {
            $this->login = $login;
            $this->password = $password;
        }

        public function getFileCloudConnector(): FileCloudConnector
        {
            return new DropboxFileCloudConnector($this->login, $this->password);
        }
    }

    interface FileCloudConnector
    {
        public function logIn(): void;

        public function logOut(): void;

        public function createFolder($folderName): void;
    }

    /**
     * API FourbisComCloud.
     */
    class FourbisComFileCloudConnector implements FileCloudConnector
    {
        private $login, $password;

        public function __construct(string $login, string $password)
        {
            $this->login = $login;
            $this->password = $password;
        }

        public function logIn(): void
        {
            echo "Send HTTP API request to log in user $this->login with " .
                "password $this->password\n";
        }

        public function logOut(): void
        {
            echo "Send HTTP API request to log out user $this->login\n";
        }

        public function createFolder($folderName): void
        {
            echo "Send HTTP API requests to create a folder in FourbisComCloud.\n";
        }
    }

    /**
     * API Dropbox.
     */
    class DropboxConnector implements FileCloudConnector
    {
        private $email, $password;

        public function __construct(string $email, string $password)
        {
            $this->email = $email;
            $this->password = $password;
        }

        public function logIn(): void
        {
            echo "Send HTTP API request to log in user $this->email with " .
                "password $this->password\n";
        }

        public function logOut(): void
        {
            echo "Send HTTP API request to log out user $this->email\n";
        }

        public function createFolder($folderName): void
        {
            echo "Send HTTP API requests to create a folder in Dropbox.\n";
        }
    }

    /**
	 * De clientcode kan met elke FourbisComCloudFile-subklasse werken, omdat deze niet afhankelijk is van specifieke klassen.
     */
    function clientCode(FourbisComCloudFile $creator)
    {
        // ...
        $creator->folder("/aanvragen");
        $creator->folder("/personeel");
        // ...
    }

	/ **
       * In de initialisatiefase kan de applicatie kiezen met welke cloud het wil werken, 
       * een object van de overeenkomstige subklasse maken en dit doorgeven aan de klantcode.
       * /
    echo "Testing ConcreteCreator1:\n";
    clientCode(new FourbisComFileCloudConnector("john_smith", "******"));
    echo "\n\n";

    echo "Testing ConcreteCreator2:\n";
    clientCode(new DropboxConnector("john_smith@example.com", "******"));
  

Eindresultaat:

  
      Testing ConcreteCreator1:
      Send HTTP API request to log in user john_smith with password ******
      Send HTTP API requests to create a folder in FourbisComCloud.
      Send HTTP API request to log out user john_smith
      Send HTTP API request to log in user john_smith with password ******
      Send HTTP API requests to create a folder in FourbisComCloud.
      Send HTTP API request to log out user john_smith


      Testing ConcreteCreator2:
      Send HTTP API request to log in user john_smith@example.com with password ******
      Send HTTP API requests to create a folder in Dropbox.
      Send HTTP API request to log out user john_smith@example.com
      Send HTTP API request to log in user john_smith@example.com with password ******
      Send HTTP API requests to create a folder in Dropbox.
      Send HTTP API request to log out user john_smith@example.com