---
lang: de
format:
    pdf:
        toc: true
        number-sections: true
        colorlinks: true
crossref:
    custom:
      - kind: float
        reference-prefix: UML-Diagramm
        key: uml
        latex-env: uml
        latex-list-of-description: UML-Diagramme
---

{{< pagebreak >}}

# Entwurfsmuster
Zusätzlich zu den beiden im Folgenden dargestellten Entwursmustern benutzen wir einen [Service Locator](https://en.wikipedia.org/wiki/Service_locator_pattern), der zu den [Architectural Patterns](https://en.wikipedia.org/wiki/Architectural_pattern) zählt. Dieses Pattern nutzt ein `HashMap`, in der verschiedene Komponenten des Programms gespeichert werden, um das Komponenten-Management zu vereinfachen und explizite Abhängigkeiten der Komponenten untereinander zu vermeiden, die das Initialisieren der einzelnen Komponenten erschweren könnten. 
In unserem Projekt fungiert [`PICComponentLocator`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/c38835fd7b47c662a344c9ab2c41e0527760bd61/src/main/java/fabrik/simulator/pic16f84/PICComponentLocator.java) als dieser Locator. Er besitzt einen `componentCatalogue` als Member, der eine `Map<Class<? extends PICComponentInterface>, PICComponentInterface>` ist. Das bedeutet, dass alle Klassen, die durch den Locator gemanaget werden sollen, das `PICComponentInterface` implementieren müssen. 

Um nicht bei allen Zugriffen die `PICComponentLocator.getComponent()` ausführen zu müssen, wurde zusätzlich die `abstract` Klasse `PICComponent` [eingeführt]. Sie besitzt als Member alle implementierten Komponenten, also sollten neue Komponenten ebenfalls das Interface implementieren und als Member in `PICComponent` angelegt werden. Alle Komponenten können diese Klasse `extend`en und dadurch auch alle weiteren Komponenten als Member haben, dies ist auch in @uml-observer dargestellt [^1]. Durch die `initialize`-Funktion des `PICComponent` werden durch einen Aufruf der `PICComponentLocator.initAll()` alle Member vom Locator geholt. 

## Marker-Entwurfsmuster
[Marker-Patterns](https://en.wikipedia.org/wiki/Marker_interface_pattern) werden allgemein genutzt, um Klassen Metadaten zuzuordnen. In unserem Projekt stellen die `FrontendSpecific`-Interfaces Marker dar, die genutzt werden um zu kommunizieren, dass Klassen andere Klassen benötigen, die Frontend-spezifisch sind und somit besonders beachtet werden müssen. So können alle [`Interface`s](LINK ZU ORDNER) definiert werden ohne direkt von fremdem Code abhängig zu sein. Bei möglichen anderen Frontend-Implementierungen müssten entsprechend nur die passenden Klassen die jeweiligen Interfaces implementieren und nichts an den Interfaces ändern.
Eingeführt wurden die `FrontendSpecific`s in [diesem Commit](https://git.paulmartin.cloud/paul/PIC-Simu/commit/06e934801645e32dea5415ccb4f38368a1667df6) ([hier](https://git.paulmartin.cloud/paul/PIC-Simu/commit/ef3b0fce5f9b6cce06494ff6ce59f5534064e7d2) verfollständigt). Es wurde zunächst ein `FrontendSpecificObject`-Interface angelegt, das alle Frontend-spezifischen Klassen beschreibt, die von Methoden anderer Klassen genutzt werden (sprich, die in den  [`Interface`s](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/interfaces) vorkommen). Es ist - entsprechend des Marker-Patterns - komplett leer [definiert](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/frontendspecifics/FrontendSpecificObject.java):
```java
public interface FrontendSpecificObject { 
}
```
Zusätzlich gibt es für spezifische Frontend-Klassen auch `FrontendSpecific`-Interfaces, sodass nach wie vor nur bestimmte Klassen über- bzw. zurückgegeben werden können. Diese spezifischen Interfaces sind ebenfalls leer, nur nutzen sie `extends FrontendSpecificObject` um zu verdeutlichen, dass sie zu den allgemeinen `FrontendSpecificObject`s gehören. Hier beispielsweise [`FrontendSpecificCircle`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/ef3b0fce5f9b6cce06494ff6ce59f5534064e7d2/src/main/java/fabrik/simulator/pic16f84/frontendspecifics/FrontendSpecificCircle.java):
```java
public interface FrontendSpecificCircle extends FrontendSpecificObject {
}
```
Tatsächlich genutzt werden die `FrontendSpecific`-Interfaces von [Circle], [ToggleButtonGroup] und [Vbox]. Sie `extenden` ihr jeweiliges `JavaFX`-Pendant und `implementen` ihr jeweiliges `FrontendSpecific`-Interface. Darüber hinaus implementieren sie nur die nötigen (also im Code tatsächlich genutzten) Konstruktoren, die wiederum nur `super()` aufrufen, hier bspw. [`ToggleButtonGroup`]:
```java
public class ToggleButtonGroup extends 
              com.gluonhq.charm.glisten.control.ToggleButtonGroup 
                implements FrontendSpecificToggleButtonGroup {
    public ToggleButtonGroup(){
        super();
    }

    public ToggleButtonGroup(ToggleButton... toggles) {
        super(toggles);
    }    
}
```
Alle für das Marker-Pattern eingeführten Klassen sind in @uml-marker erkennbar [^1]:

::: {#uml-marker}

```{mermaid}
%%| fig-width: 6.5
classDiagram
direction TB
class FrontendSpecificObject {
    <<Interface>>
}
class FrontendSpecificToggleButtonGroup {
    <<Interface>>
}
class ToggleButtonGroup {
    public ToggleButtonGroup()
    public ToggleButtonGroup(ToggleButton... toggles)
}

class `com.gluonhq.charm.glisten.control.ToggleButtonGroup` {
    ...
    ....()
}

FrontendSpecificObject <|-- FrontendSpecificToggleButtonGroup : << extends >>
FrontendSpecificToggleButtonGroup <|-- ToggleButtonGroup : << implements >>
`com.gluonhq.charm.glisten.control.ToggleButtonGroup` <|-- ToggleButtonGroup : << extends >>

class FrontendSpecificVBox{
    <<Interface>>
}
class VBox {
    public VBox()
}

class `javafx.scene.layout.VBox` {
    ...
    ....()
}

FrontendSpecificObject <|-- FrontendSpecificVBox : << extends >>
FrontendSpecificVBox <|-- VBox : << implements >>
`javafx.scene.layout.VBox` <|-- VBox : << extends >>

class FrontendSpecificCircle {
    <<Interface>>
}
class Circle {
    public Circle()
}

class `javafx.scene.shape.Circle` {
    ...
    ....()
}


FrontendSpecificObject <|-- FrontendSpecificCircle : << extends >>
FrontendSpecificCircle <|-- Circle : << implements >>
`javafx.scene.shape.Circle` <|-- Circle : << extends >>

class PICComponentInterface{
    <<Interface>>
    + initialize(PICComponentLocator picComponents)
}

class WindowManagement{
    <<Interface>>
    refreshTable()$
    startFromMain(String[] args)$
}

FrontendSpecificObject <|-- WindowManagement : << extends >>
PICComponentInterface <|-- WindowManagement : << extends >>

```

Das genutzte Marker-Pattern und alle seine Verwendungen.
:::
## Beobachter- (/Observer-) Entwurfsmuster
[Beobachter-Entwurfsmuster](https://en.wikipedia.org/wiki/Observer_pattern) werden genutzt, damit ein Subjekt mehrere Beobachter über eine Zustandsänderung informieren kann. In unserem Projekt passiert das bei einer Änderung der `totalExecutionTime`. Das Subjekt `ExecutionTimeSubject` führt hierbei ein `Set` an Beobachtern, die bei uns durch das Interface `ExecutionTimeObserver` repräsentiert werden, welches durch die `registerObserver`- und `unregisterObserver`-Funktionen verwaltet werden kann. Bei einer Zustandsänderung muss die `notifyObservers`-Funktion aufgerufen werden, welche für alle Observer die im Interface spezifizierte `executionTimeChanged`-Funktion aufruft. Die Implementierung wurde [hier](https://git.paulmartin.cloud/paul/PIC-Simu/commit/85bc6e9ebae4655ba3ad7ee360332010edc910dd) begonnen, [hier](https://git.paulmartin.cloud/paul/PIC-Simu/commit/cf6bcd8498cd2d03e85b0c5f6faaaed935d3a155) vereinfacht um das Threading des Frontends zu respektieren und [hier](https://git.paulmartin.cloud/paul/PIC-Simu/commit/52d63523341179c3c49e0ac31a60a8d7c11cdddc) in die letzten Tests eingefügt.
In der aktuellen Umsetzung übernimmt die [`Commands`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/ef3b0fce5f9b6cce06494ff6ce59f5534064e7d2/src/main/java/fabrik/simulator/pic16f84/Commands.java)-Klasse gleichzeitig die Rolle des `ExecutionTimeSubject`s und `CommandsInterface`s. Deshalb [wird in der `Main`-Klasse](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/85bc6e9ebae4655ba3ad7ee360332010edc910dd/src/main/java/fabrik/simulator/pic16f84/Main.java) das `Commands`-Objekt dem `ComponentLocator` sowohl für die `ExecutionTimeSubject.class` als auch für die `CommandInterface.class` hinzugefügt. `ExecutionTimeObserver` sind die Klassen, die vorher `commands.getTotalExecutionTime()` gepollt haben. Die Implementierung dieses Entwursmusters ist in @uml-observer erkennbar [^1]:

:::{#uml-observer}

```{mermaid}
%%| fig-width: 6.5
classDiagram
direction TB
class PICComponentInterface{
    <<Interface>>
    + initialize(PICComponentLocator picComponents)
}


class CommandInterface {
    <<Interface>> 
    + CALL(int isr);

    + get_wRegister();

    + decode(int i);
}


class PICComponent{
    <<Abstract>>
    # DataRegisterInterface dataRegister
    ...

    + initialize(PICComponentLocator locator)
}


class ExecutionTimeSubject{
    <<Abstract>>
    - Set~ExecutionTimeObserver~ observers

    + registerObserver(ExecutionTimeObserver observer)
    + unregisterObserver(ExecutionTimeObserver observer)
    + getTotalExecutionTime()
    + addExecutionTime(int i)
    + getExecutionTimeMultiplier()
    # notifyObservers()
    ....()
}


class Commands{
    - wRegister
    - totalExecutionTime
    - executionTimeMultiplier
    ....()
}

class FrontendSpecificObject {
    <<Interface>>
}

class FrontendControllerInterface{
    <<Interface>>
    + getPORTbuttons() FrontendSpecificToggleButtonGroup[]
    + getTRISbuttons() FrontendSpecificToggleButtonGroup[]
    + stopRunFromBackend(String watchdogTimer)
}


class Controller_Frontend {
    ...
    ....()
}

class TimerInterface {
    <<Interface>>
    + cycles(int i)
    + incrementFromPin(int directRegister)
    + increment(boolean manual)
}

class Timer {
    ...
    ....()
}


class EEPROMInterface {
    <<Interface>>
    registerTime(double executionTime, boolean b)
    parse(int i, int content, int i1)
    read(int address) long
    write(int address, long data)
}

class EEPROM {
    ...
    ....()
}


class ExecutionTimeObserver {
    <<Interface>>
    + executionTimeChanged()
}

ExecutionTimeObserver <|-- Timer : << implements >>
TimerInterface <|-- Timer : << implements >>
PICComponent <|-- Timer : << extends >> 
PICComponentInterface <|-- TimerInterface : << extends >> 
PICComponentInterface <|-- EEPROMInterface : << extends >> 
ExecutionTimeObserver <|-- EEPROM : << implements >>
EEPROMInterface <|-- EEPROM : << implements >>
PICComponent <|-- EEPROM : << extends >> 
ExecutionTimeObserver <|-- Controller_Frontend : << implements >>
PICComponent <|-- Controller_Frontend : << extends >> 
PICComponentInterface <|-- PICComponent : << implements >>
PICComponentInterface <|-- FrontendControllerInterface : << extends >> 
FrontendControllerInterface <|-- Controller_Frontend : << implements >>
FrontendSpecificObject <|-- FrontendControllerInterface : << extends >> 
CommandInterface <|-- Commands : << implements >> 
ExecutionTimeSubject <|-- Commands : << extends >>
PICComponent <|-- ExecutionTimeSubject : << extends >> 
PICComponentInterface <|-- CommandInterface : << extends >>

```

Das genutzte Observer-Pattern und seine Verwendungen im (Nicht-Test-) Code. 
:::

[^1]: Für das Pattern unwichtige Funktionen und Variablen wurden ausgelassen


# Clean Architecture
Die Clean Architecture ist dafür gedacht, Softwareprojekte langfristig betreiben, flexibel und wartbar halten zu könnnen. Man teilt das Softwareprojekt in verschiedene Schichten ein, bei denen ein klarer Abhängigkeitsfluss von den äußeren zu den inneren Schichten besteht. Unser Projekt besitzt eine [Interfaces-Schicht](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/interfaces), die alle Klassen offenlegt, die miteinander kommunizieren. Alle Klassen im [`package fabrik.simulator.pic16f84`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84), die nicht das [`FrontendSpecificObject`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/frontendspecifics/FrontendSpecificObject.java) `extenden`, sind in einer Schicht weiter außen, dem Application Code. Alle Klassen - nicht Interfaces -, die das [`FrontendSpecificObject`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/frontendspecifics/FrontendSpecificObject.java) `extenden`, also [alle Klassen im `package fabrik.simulator.pic16f84.frontendspecifics`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/frontendspecifics), [`Controller_Frontend`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/Controller_Frontend.java), [`CreateWindow`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/CreateWindow.java), [`IOPorts`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/IOPorts.java) und [`ToggleButtonGroupExt`](https://git.paulmartin.cloud/paul/PIC-Simu/src/commit/f28603843d7ef6cbf4666ab2b2ceda02ca411eb7/src/main/java/fabrik/simulator/pic16f84/ToggleButtonGroupExt.java). 
Main-Klasse:
- Alle Objekte werden erstellt und dem Locator hinzugefügt
- WindowManagement startet das Frontend. Wenn man alle Referenzen darauf (Z. 19, 20, 23) entfernen würde, würde App trotzdem starten und funktionieren.

+ Evtl Schaubild 