Wie können Sie Ihre Geschäftsprozesse mit der Workflow-Komponente von Symfony sichern und aufrechterhalten?

Artikelbild mit Vektorfigur

Wir beginnen diesen Artikel, indem wir uns ein kleines Szenario vorstellen und in dieses eintauchen.

Stellen Sie sich vor, Sie sind ein junger PHP/Symfony-Entwickler in einem Umsetzungsteam und beginnen ein Projekt zur Erstellung einer E-Commerce-Website für Ihren Kunden, der auf die Zustellung von Weihnachtspaketen spezialisiert ist.

Ihr gesamtes Team wird also zu einem Vorbereitungstreffen mit Ihrem Kunden eingeladen, um seine eigenen Bedürfnisse zu definieren und seinen Geschäftsprozess anzugehen, der von der Zusammenstellung der Pakete in der Fabrik bis zur Auslieferung an den Kunden reicht. Sie werden also herausgefordert, eine Lösung zu entwerfen und zu implementieren, die das Kerngeschäft Ihres Kunden widerspiegelt.

Sie haben jedoch keine Ahnung, wie Sie anfangen sollen, die verschiedenen aufgeführten Regeln vermischen sich und ertrinken in Ihrem Gehirn, und Sie bekommen Angst vor der Tonne komplizierter und spezifischer Informationen, die Ihr Kunde Ihnen gibt.

Doch wenn es dunkel wird und Sie nicht schlafen können, denken Sie an ein etwas unausgegorenes englisches Wort, das die Lösung für Ihr Problem sein könnte: " Workflow ".

Was für ein Glück! Sie geben dieses tolle Wort in Ihre Lieblingssuchmaschine ein und stoßen auf Ergebnisse, die über die Workflow-Komponente von Symfony berichten, und die sehen super interessant aus!

In diesem Moment stellen Sie sich eine ganze Reihe von Fragen:

  • Was ist ein Workflow?
  • Woher kommt der Begriff Workflow?
  • Wie muss ich vorgehen, um die Workflow-Komponente von Symfony zu installieren?
  • Welchen Nutzen hat diese Komponente und was kann ich damit tun?

Wenn Sie sich diese Fragen auch stellen, lade ich Sie ein, diesen Artikel zu lesen. Er wird Ihnen Antworten geben, damit Sie diese Komponente in Ihrem eigenen Projekt und diesmal im wirklichen Leben einsetzen können.


1 - Was ist ein Workflow?

Das ist die erste Frage, die Sie sich stellen müssen, nicht wahr?

Man kann sagen, dass ein Workflow (oder Arbeitsablauf) "die Gesamtheit der zu erledigenden Aufgaben und der verschiedenen Akteure, die an der Durchführung eines Geschäftsprozesses beteiligt sind" darstellt.

Mit anderen Worten: Es ist die Gesamtheit der sequenzierten Aufgaben, die es unserem imaginären Kunden ermöglichen würde, seine Bestellung von Weihnachtspaketen bei seinen Kunden zu erfüllen.

Man sieht sofort besser, wie sich der Geschäftsprozess gliedern soll, oder?

Wenn Sie es immer noch nicht sehen, könnte es in sechs einfachen Schritten zusammengefasst werden:

  • Die Erstellung der Bestellung durch den Kunden
  • Die Vorbereitung des Pakets in der Fabrik
  • Die Verpackung des Pakets
  • Der Versand des Pakets an den Kunden
  • Die Zustellung des Pakets an den Kunden
  • Der Empfang des Pakets durch den Kunden

Es sind diese verschiedenen Schritte oder Aufgaben, die den Geschäftsprozess ermöglichen, und es erlaubt uns auch, unserem Auftrag Zustände zuzuordnen, um ihn zu verfolgen.

Dies kann also durch eine Zustandsmaschine modelliert werden, die ein mathematisches Modell ist, das die Grundlage für die Workflow-Komponente von Symfony bildet, die wir im nächsten Teil erkunden werden.


2 - Automatentheorie und Zustandsmaschinen

Wir werden also ein wenig Theorie betreiben, auch wenn mir bewusst ist, dass dies nicht das ist, was Sie bevorzugen, aber es ist wichtig, um zu verstehen, wie wir unseren Geschäftsprozess artikulieren.

Wir haben also von einer Zustandsmaschine gesprochen, aber wir wissen noch nicht, was sie ist und auch nicht, welche Verbindung sie mit der Workflow-Komponente von Symfony haben kann.

Eine Zustandsmaschine ist ein mathematisches Objekt, mit dem wir Algorithmen für bestimmte Geschäftsprozesse entwerfen können. Eule, das ist genau das, was wir brauchen!

Sie besteht aus zwei wichtigen Elementen, die in der Abbildung unten zu sehen sind:

  • Zustände (dargestellt durch Kreise), die den Status eines Objekts beschreiben, von denen nur einer der aktuelle Zustand sein kann. In unserem Beispiel ist entweder die Glühbirne ein- oder ausgeschaltet.
  • Übergänge (dargestellt durch Pfeile), die die Aktionen beschreiben, die unter bestimmten Bedingungen ausgeführt werden müssen, um von einem Zustand in einen anderen zu gelangen. In unserem Beispiel kann man entweder die Glühbirne einschalten, wenn sie ausgeschaltet ist, oder die Glühbirne ausschalten, wenn sie eingeschaltet ist.

Beispiel für eine einfache Zustandsmaschine, einen Schalter.

So ist man mit diesem Werkzeug in der Lage, ein erschöpfendes Schema aller möglichen Aktionen in Abhängigkeit von den aktuellen Zuständen zu erstellen, was sich als wichtig erweist, um die Geschäftsregeln eines Prozesses zu rahmen.

Auf diesem Prinzip basiert die Workflow-Komponente von Symfony, weshalb wir diese Komponente installieren werden.


3 - Installation der Workflow-Komponente von Symfony

Wenn Sie bereits ein Symfony-Projekt gestartet haben und über den Composer Dependency Manager verfügen, ist es sehr einfach, die Workflow-Komponente zu installieren, indem Sie den folgenden Befehl eingeben:

composer require symfony/workflow

3.1 - Entwurf des Geschäftsprozesses und Konfiguration der Zustandsmaschine

Nachdem Sie Ihr Projekt mit der Workflow-Komponente eingerichtet haben, ist es Zeit für ein wenig Gehirnschmalz - aber nicht so viel!
Wir haben die wichtigsten Schritte unseres Geschäftsprozesses bereits isoliert, sodass es ein Kinderspiel ist, unsere Berichtsmaschine einzurichten.

Der erste Schritt, um eine Zustandsmaschine einzurichten, besteht darin, in unserem Projekt eine Entität mit einem Feld string die wir nennen werden state. Es ist dieses Feld, das uns mithilfe der Funktion "Paket" mitteilen kann, an welcher Stelle der Berichtsmaschine sich unser Paket befindet. getState().

Hier ist ein Beispiel für die Entität Colis zur besseren Veranschaulichung:

<?php

namespace App\Entity;

use App\Repository\ColisRepository;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass=ColisRepository::class)
*/
class Colis
{
    /**
    * @ORM\Id
    * @ORM\GeneratedValue
    * @ORM\Column(type="integer")
    */
    private $id;

    /**
    * @ORM\Column(type="string", length=255, nullable=true)
    */
    private $state;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getState(): ?string
    {
        return $this->state;
    }

    public function setState(?string $state): self
    {
        $this->state = $state;

        return $this;
    }
}

Dann geht es im zweiten Schritt in die Konfigurationsdatei ./config/packages/workflow.yaml.

Das weitere Vorgehen ist relativ einfach.
Es genügt, seine Staaten (places) und insbesondere sein Anfangszustand (initial_marking), und seine Übergänge (transitions), die es ermöglichen, von einem Zustand in einen anderen zu gelangen.

Hier ist ein Beispiel für die Konfiguration unserer Berichtsmaschine für Pakete:

framework:
    workflows:
        commande_colis:
            type: 'state_machine'
            marking_store:
                type: 'method'
                property: 'state'
            supports:
                - App\Entity\Colis
            initial_marking: nouvelle_commande
            places:
                - nouvelle_commande
                - en_preparation
                - emballe
                - expedie
                - livre
                - retourne
                - perdu
            transitions:
                preparation:
                    from: nouvelle_commande
                    to:   en_preparation
                emballage:
                    from: en_preparation
                    to:   emballe
                expedition:
                    from: emballe
                    to:   expedie
                livraison:
                    from: expedie
                    to:   livre
                retour:
                    from: [livre, expedie]
                    to:   retourne
                perte:
                    from: [expedie, livre]
                    to:   perdu

Sobald unsere Konfiguration richtig ausgefüllt ist, können wir sehen, was wir damit machen können, und Sie werden sehen, dass es Ihnen gefallen wird!

3.2 - Export eines Bildes der Zustandsmaschine

Und wenn wir sehen würden, wie unsere prächtige Staatsmaschine aussieht, mit der wir unsere Pakete verwalten, würde Ihnen das nicht gefallen?

Das ist mit diesem Befehl möglich:

php bin/console workflow:dump commande_colis | dot -Tpng -o gestion_colis.png

Und dank dessen haben wir unsere schöne Staatsmaschine mit unserem Geschäftsprozess :

Aber Sie denken jetzt vielleicht, dass es zwar süß ist, dass er seine Staatsmaschine zur Schau stellt, aber was macht er eigentlich damit?

Sie haben Recht, lassen Sie uns zur Praxis übergehen!

3.3 - Verwendung der Zustandsmaschine

Der primäre Nutzen unserer Statusmaschine besteht darin, dass wir den Bestellstatus jedes einzelnen Pakets verfolgen können.

Dazu müssen Sie einfach nur die Übergänge anwenden, die wir in unserer Konfiguration definiert haben, um von dem Zustand, in dem sich das Paket gerade befindet, in einen neuen Zustand zu wechseln.

Ein Paket befindet sich zum Beispiel im Zustand emballe und es an den Kunden versenden möchte, müssen Sie nur prüfen und den Übergang expedition auf folgende Weise:

$workflow = $this->get('workflow.commande_colis');

if ($workflow->can($colis, 'expedition')) {
    $workflow->apply($colis, 'expedition');
}

Nachdem der Übergang angewendet wurde, wenn Ihr Paket im Zustand emballe sein aktueller Zustand wird expedie. Wenn dies nicht der Fall war, dann bleibt das Paket in seinem ursprünglichen Zustand.

Wie Sie sehen können, ist dies relativ einfach und ermöglicht es, von einem Zustand des Geschäftsprozesses zum nächsten zu gelangen, aber manchmal kann unser Geschäftsprozess kompliziert sein und man braucht mehr Werkzeuge, um ihn getreu wiederzugeben. Das werden wir im nächsten Abschnitt behandeln.

3.4 - Anwendung komplexer Geschäftsregeln

Denn wie oben beschrieben, verwendet unser Geschäftsprozess einige spezifische Geschäftsregeln.

Angenommen, wir bieten unserem Kunden an, dass er sein Paket innerhalb von 7 Tagen nach dem Versanddatum zurückschicken kann, wenn er damit nicht zufrieden ist.

Derzeit erlaubt uns unsere Zustandsmaschine, so wie sie definiert ist, nicht, diese Regel zu implementieren. Aber glücklicherweise ist es möglich, diese Einschränkung mithilfe von Ereignissen zu implementieren.

Wir müssen also nur eine Klasse erstellen, die die Schnittstelle implementiert EventSubscriberInterface so:

use Symfony\Component\Workflow\Event\GuardEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RetourColisListener implements EventSubscriberInterface
{
    public function guardRetourColis(GuardEvent $event)
    {
        /** @var \App\Entity\Colis $colis */
        $colis = $event->getSubject();
        $dateExpedition = $colis->getDateExpedition();
        $now = new \DateTime();

        if ($now->diff($dateExpedition)->format('%a') < 7) {
           $event->setBlocked(true);
        }
    }

    public static function getSubscribedEvents()
    {
        return [
            'workflow.commande_colis.guard.retour' => ['guardRetourColis'],
        ];
    }
}

Sobald diese Klasse geschrieben ist, dank des Ereignisses guardBei jedem Versuch, ein Paket zurückzusenden, wird überprüft, ob das Paket vor weniger als 7 Tagen versandt wurde. Wenn dies nicht der Fall ist, ist es dem Kunden nicht mehr möglich, das Paket zurückzuschicken und eine Rückerstattung zu erhalten.

Es gibt andere Ereignisse, die ebenfalls dazu beitragen, den Geschäftsprozess unserer Anwendungen besser wiederzugeben, hier eine Liste :

  • guard : Ermöglicht es, einen Übergang unter bestimmten Bedingungen zu erzwingen und durchzusetzen.
  • leave : Ermöglicht die Ausführung von Code, wenn ein Zustand unserer Zustandsmaschine verlassen wird.
  • transition : Ermöglicht das Ausführen von Code, wenn der Übergang angewendet wurde.
  • enter : Ermöglicht die Ausführung von Code, wenn man den Zielzustand betreten wird, kurz bevor der aktuelle Zustand geändert wird.
  • entered : Ermöglicht die Ausführung von Code, wenn man den Zielzustand betreten hat, direkt nachdem der aktuelle Zustand geändert wurde.
  • completed : Ermöglicht das Ausführen von Code, wenn der Übergang vollzogen wurde, z. B. das Versenden von E-Mails.
  • announce : Ermöglicht die Ankündigung, dass ein oder mehrere Übergänge ab dem neuen Zustand nun verfügbar sind.

4 - Schlussfolgerung

In diesem Artikel habe ich Ihnen von Workflow, Automatentheorie, insbesondere von Zustandsautomaten und auch von der Workflow-Komponente von Symfony berichtet.

Das ist vielleicht sehr theoretisch, aber ich hoffe, dass Sie daraus lernen, dass diese Komponente es Ihnen ermöglichen kann, den Designteil eines Geschäftsprozesses ernst zu nehmen, um ihn besser einrahmen und Ihre Lösung besser umsetzen zu können.

Selbstverständlich stehe ich Ihnen zur Verfügung, um Sie bei der Einrichtung Ihres Workflows anzuleiten oder sogar Fragen zu beantworten, die Sie haben könnten.


Quellen

Workflow-Definition und Zustandsmaschine
Dokumentation der Workflow-Komponente von Symfony
Beispiel für die Verwendung des Workflows
Illustration
Diesen Artikel teilen
Foto eines Mannes aus dem Progicar-Team
verfasst von Pierre Petillon

Vorgeschlagene Artikel