DEV Community

Discussion on: Clean Architecture in TypeScript Projekt: Angular als Plugin

 
jim108dev profile image
jim108dev
  1. ok, meine Idee war einfach, dass ein UseCase nur eine Aufgabe haben sollte und alles, was nicht dazugehört um diese zu erfüllen, sollten andere Komponenten übernehmen.
  2. Nehmen wir mal an, alle UseCases bekommen einen Ladeindicator. Bekommen dann alle den selben Presenter? Sie sind verschachtelt, besteht die Gefahr das ein UseCase des anderen Indicator stellt. Bekommen sie unterschiedliche, brauche ich wieder Logik um sie zusammenzuführen.
  3. Wie sieht es denn aus mit Routing? Bekommen UseCases Routing-Interfaces?
  4. Kannst du vielleicht nochmal sagen, warum du Funktionen die eigentlich synchron funktionieren in ein Promise einbettest und dann die Funktion mit await aufrufst. Z. B. bei
  public async enterString(currentValue?: string): Promise<string> {
    return prompt('Eingabe:', currentValue) ?? ''
  }

Aufruf

          todo.description = await this.interaction.enterString(
            todo.description
          )

Im Prinzip das selbe wie

  public enterString(currentValue?: string): string {
    return prompt('Eingabe:', currentValue) ?? ''
Thread Thread
 
devtronic profile image
Julian Finkler

1) Der Use Case hat ja nur eine Aufgabe: er kümmert sich um die Geschäftslogik für diesen einen Anwendungsfall. Da die Geschäftslogik geschäftsübergreifend ist und nicht für diese eine Anwendung gilt, hast du gar keine Möglichkeit die Teilaufgaben sinnvoll auszulagern. (Du kannst und solltest natürlich das Integration Operation Segregation Principle (IOSP) anwenden und die einzelnen Aufgaben in Sub-Methoden unterteilen)

2) In diesem Fall sollte man anfangen zu verallgemeinern. Nehmen wir an, du hast noch 10 weitere Listen.
Dann kannst du ja einfach eine Komponente für alle Liste erzeugen, welche den UseCase "ShowList" hat. Der UseCase erwartet dann im Konstruktor ein kompatibles Repository mit einer allgemeinen Methode, welche die anzuzeigenden zurück liefert. (Kann ja z.B. in Form eines generischen Interface sein).
Der Presenter ist wie gewohnt bei der Komponente implementiert. Wie die Daten dann in eine darstellbare Form gelangen ist wieder ein anderes Thema (wobei bei einer Liste im Grunde ja ein String-Array genügt, welches die Propertynamen der anzuzeigenden Eigenschaften enthält).

Anders sieht es natürlich aus, wenn bei wirklich jedem Use Case ein Ladeindikator angezeigt werden soll.
In dem Fall würde ich im core einen abstrakten "BusyService" bauen, welcher die beiden Methoden show & hide des Presenters enthält. Der Service kann dann im UseCase injected und angesprochen werden werden.
Bei der implementierung würde ich vermutlich auf ein BehaviorSubject zurückgreifen, welches im äußersten Template per async-Pipe verwendet wird. In der show Methode würde ich den Wert inkrementieren und beim hide dekrementieren. Das hat den Vorteil, dass verschaltete show & hide calls sauber funktionieren. (Im Template dann einfach auf > 0 prüfen).

3) Das Thema Routing habe ich bisher so gelöst, dass ich einen abstrakten "RouterService" im core/service abgelegt habe. Darin ist dann pro Seite eine eigene Methode. z.B. showDashboard() oder showTodo(todoId).
Implementiert wird das dann im infrastructure-Modul. (ähnlich wie beim Interaction service)

4) Quasi als Vorsorge 😁 Es könnte ja durchaus sein... Nein es wird definitiv so sein, dass irgendwann ein hübscher asynchroner Dialog den synchronen prompt Dialog ersetzt.
Wir wissen ja: Die einzige Konstante ist die Veränderung

Thread Thread
 
jim108dev profile image
jim108dev • Edited

ok danke. Wie sieht es denn aus, wenn ich drei Views auf die Todos habe?, Z.B. Menü-Button "Revert Todos" falls mehr als 0 vorhanden, TodoListComponent und View Anzahl Todos im Footer. Ich möchte ja jetzt nicht dreimal die Daten vom Server laden, noch für jede Komponente auf der Seite raten, wurde presenter.reset und usecase.execute schon aufgerufen. Ist ein Usecase jetzt Todo anzeigen oder Seite anzeigen?

Thread Thread
 
devtronic profile image
Julian Finkler

Du darfst natürlich auch mit Subscriptions arbeiten. (Um in der Geschäftslogik nicht von RxJs abzuhängen, würde ich für die verwendeten RxJs-Komponenten minimale, kompatible Interfaces bauen. Z.B. für die (Un-) Subscribe Methoden.)

Im Repository fügst du dann ein Property length$ hinzu, welches die Anzahl der Elemente im Repository emittiert und im UseCase subscribed wird. (Ebenso kannst du auch ein Property elements$ verwenden, welches die aktuellen Elemente emittiert. )
Im Presenter fügst du dann noch eine Methode displayCount(count: number) hinzu, welches vom UseCase bei einer Änderung von length$ gecalled wird.
Somit rufst du die Daten nicht doppelt und dreifach ab.

Ein UseCase stellt ein fachliches Ziel ("business goal") dar. Siehe auch hier: de.wikipedia.org/wiki/Anwendungsfall
Das kann sowohl Todo anzeigen als auch das anzeigen der Liste der Todos sein.