Laden...

Sequentielles ausführen von Funktionen. Gibt es da ein Pattern?

Erstellt von ill_son vor 2 Jahren Letzter Beitrag vor 2 Jahren 346 Views
I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 2 Jahren
Sequentielles ausführen von Funktionen. Gibt es da ein Pattern?

Hallo,

folgende Frage: Ich arbeite aktuell an einer Software zum Firmwareupdate eine Gerätes. Nun besteht die ganze Prozedur aus mehreren Schritten (Datei einlesen, in Hex-File umwandeln, Com-Port erstellen, Gerät suchen, gegenbenfalls zum Reset auffordern, Flash programmieren, rücklesen usw.) und zwischendurch soll auch noch mittels Progress über den Ablauf informiert werden. Abhängig davon, ob der eine Schritt erfolreich war, wird der nächste durchgeführt oder abgebrochen. Nun ist das eine Schachtelei von if-Bedinungen. Ich wollte fragen, ob es dafür ein schlaues Pattern gibt, oder ob sich das nicht anders lösen lässt?

Grüße, Alex

Final no hay nada más

6.911 Beiträge seit 2009
vor 2 Jahren

Hallo ill_son,

als einfaches "Pattern":


public interface IStep
{
    Task ExecuteAsync(CancallationToken cancellationToken);
}

public class FirstStep : IStep
{
    // ...
}

public class SecondStep : IStep
{
    // ...
}

public class Manager
{
    private readonly List<IStep> _steps;

    public Manager(List<IStep> steps) => _steps = steps;

    public async Task RunAsync(CancallationToken cancellationToken)
    {
        foreach (IStep step in _steps)
        {
            try
            {
                await step.ExecuteAsync(cancellationToken);    // mit od. ohne ConfigureAwait -- abhängig von der Umgebung
                // Hier ev. Event feuern für Fortschritt od. mittels IProgress-Pattern das berichten
            }
            catch (Exception ex)
            {
                // Loggen od. was auch immer
                // Schleife kann hier auch mit break verlassen werden        
            }
        }
    }
}

So ist jeder Schritt eine eigene Klasse und kann separat implementiert und getestet werden.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

I
ill_son Themenstarter:in
227 Beiträge seit 2009
vor 2 Jahren

Hallo gfoidl,

danke für deine Anwort. In die Richtung hatte ich auch überlegt. Das Problem ist, dass die Schritte teilweise voneineander anhängen. In einem Schritt wird das File eingelesen und, wenn es geht, in ein Intel Hex File Format geparst. Im nächsten daraus die MemoryMap erstellt, die geflasht werden soll usw. Dann habe ich auch noch einen optionalen Schritt. Wenn z.B. das Gerät nicht gleich gefunden wurde, muss eine Auforderung an den Benutzer kommen, einen Reset durchzuführen. Wenn es direkt gefunden wurde (weil der Flash noch leer ist und der Controller auf den Flashvorgang wartet), dann geht es direkt los, zwingend ohne Reset. Das ist irgendwie nicht so richtig straight forward.

Final no hay nada más

16.807 Beiträge seit 2008
vor 2 Jahren

Das ist nun aber eine logische Anforderung und hat mit dem Pattern nichts mehr zutun.

Im Endeffekt kannst Du den Pattern aber erweitern und zB auch https://www.dofactory.com/net/chain-of-responsibility-design-pattern nutzen.
zB. dass gewisse Steps eben noch (Pattern-)Parameter annehmen, die sich aus anderen Steps ergeben.

Dann ist das nichts anderes als eine Mehrfach-Implementierung des gleichen Patterns mit jeweils unterschiedlichen Aufgaben.
Die Dokumentationen und das Beispiel von gfoidl sind ja nur einfache Darstellungen; dass Du das auf Deinen Fall "aufbohren" musst: völlig normal.

Im Endeffekt funktionieren viele Implementierungen auf solchen Pattern, zB. auch die gesamte ASP.NET Core Request, Render und Response-Pipeline.
Hat auch einzelne Abschnitte.

4.931 Beiträge seit 2008
vor 2 Jahren

Hallo ill_son,

wenn du verschiedene Zustände hast, dann könntest du auch einen Zustandsautomaten benutzen, s. z.B. Stateless 3.0 - A State Machine library for .NET Core.

C
2.121 Beiträge seit 2010
vor 2 Jahren

Die verschachtelten if kannst du doch auch ersetzen durch

if Fehler bei Schritt 1 then return
if Fehler bei Schritt 2 then return
if Fehler bei Schritt 3 then return