Document the conception
This commit is contained in:
130
README.md
Normal file
130
README.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Ebullition
|
||||
|
||||
Une application Java et JavaFX pour gérer des capteurs de température.
|
||||
|
||||
## Conception
|
||||
|
||||
### Interfaces partagées
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Tickable {
|
||||
+tick()*
|
||||
}
|
||||
<<interface>> Tickable
|
||||
class Nameable {
|
||||
+getName()* String
|
||||
+getDisplayName() String
|
||||
}
|
||||
<<interface>> Nameable
|
||||
class Identifiable {
|
||||
+getId()* int
|
||||
+setName(name : String)*
|
||||
}
|
||||
<<interface>> Identifiable
|
||||
class ObservableIdentifiable {
|
||||
+idProperty()* ReadOnlyIntProperty
|
||||
+getId() int
|
||||
+nameProperty()* StringProperty
|
||||
+getName() String
|
||||
+setName(name : String)
|
||||
+displayNameExpression() StringExpression
|
||||
+getDisplayName() String
|
||||
}
|
||||
<<interface>> ObservableIdentifiable
|
||||
class SensorFactory {
|
||||
+create(registry : SensorRegistry, name : String)* Sensor
|
||||
}
|
||||
<<interface>> SensorFactory
|
||||
class AutoUpdateStrategyFactory {
|
||||
+create()* AutoUpdateStrategy
|
||||
}
|
||||
<<interface>> AutoUpdateStrategyFactory
|
||||
Nameable <|-- Identifiable
|
||||
Identifiable <|-- ObservableIdentifiable
|
||||
Nameable <|-- SensorFactory
|
||||
Nameable <|-- AutoUpdateStrategyFactory
|
||||
```
|
||||
|
||||
L'interface `Tickable` définit une méthode `tick` qui est appelée périodiquement par un thread.
|
||||
|
||||
Tous les objets héritent en Java de `java.lang.Object` et ont donc une méthode `toString` utilisée principalement pour déboguer.
|
||||
Lorsqu'un objet est fait pour être affiché à l'utilisateur, ce n'est pas du débogage.
|
||||
L'interface `Nameable` définit les méthodes `getName` et `getDisplayName` qui retourne les noms à afficher pour ces objets.
|
||||
|
||||
Un objet peut être identifié par un identifiant unique, un `UUID` ou un `int`.
|
||||
L'interface `Identifiable` définit la méthode `getId` qui permet de récupérer cet identifiant sous forme d'entier.
|
||||
Elle définit aussi une méthode `setName` pour changer le nom de l'objet.
|
||||
|
||||
Des objets qui implémentent `Nameable` ou `Identifiable` ne sont pas nécessairement observables.
|
||||
C'est pourquoi l'interface `ObservableIdentifiable` hérite de ces deux interfaces et expose les propriétés observables pour l'identifiant et le nom.
|
||||
Il s'agit du même nom que les méthodes `getId` et `getName` mais en exposant une propriété observable.
|
||||
|
||||
D'autres éléments de l'application sont nommables, comme certaines fabriques d'objets : `SensorFactory` crée des capteurs et `AutoUpdateStrategyFactory` crée des stratégies d'actualisation automatique.
|
||||
Ces deux interfaces héritent de `Nameable` pour proposer un affichage de ces fabriques dans l'application.
|
||||
|
||||
### Capteurs
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ObservableIdentifiable {
|
||||
...
|
||||
}
|
||||
<<interface>> ObservableIdentifiable
|
||||
class Tickable {
|
||||
+tick()*
|
||||
}
|
||||
<<interface>> Tickable
|
||||
class Sensor {
|
||||
-id : IntegerProperty
|
||||
-name : StringProperty
|
||||
-displayName : StringExpression
|
||||
-temperature : DoubleProperty
|
||||
+Sensor(id : int, name : String)
|
||||
+idProperty() int
|
||||
+nameProperty() StringProperty
|
||||
+displayNameExpression() StringExpression
|
||||
+temperatureProperty() ReadOnlyDoubleProperty
|
||||
+getTemperature() double
|
||||
}
|
||||
class ManualSensor {
|
||||
+temperatureProperty() DoubleProperty
|
||||
}
|
||||
class AutoSensor {
|
||||
-updateStrategy : ObjectProperty~AutoUpdateStrategy~
|
||||
+tick()
|
||||
+getUpdateStrategy() AutoUpdateStrategy
|
||||
+setUpdateStrategy(s : AutoUpdateStrategy)
|
||||
+updateStrategyProperty() ReadOnlyObjectProperty~AutoUpdateStrategy~
|
||||
}
|
||||
class VirtualSensor {
|
||||
-sources : ObservableList~DataSource~
|
||||
-sourcesProperty : ListProperty~DataSource~
|
||||
+addSource(s : Sensor, weight : double)
|
||||
+removeSource(s : Sensor) bool
|
||||
+sourcesProperty() ReadOnlyListProperty~DataSource~
|
||||
#compute()
|
||||
}
|
||||
class DataSource {
|
||||
-sensor : Sensor
|
||||
-weight : DoubleProperty
|
||||
+sensor() Sensor
|
||||
+weight() double
|
||||
}
|
||||
Sensor <|-- ManualSensor
|
||||
Sensor <|-- AutoSensor
|
||||
Sensor <|-- VirtualSensor
|
||||
ObservableIdentifiable <|.. Sensor
|
||||
Tickable <|.. AutoSensor
|
||||
DataSource "*" <-- VirtualSensor
|
||||
Sensor "1" <-- DataSource
|
||||
```
|
||||
|
||||
Un capteur est un objet observable et identifiable.
|
||||
|
||||
S'il peut être mis à jour périodiquement comme c'est le cas pour les capteurs automatiques `AutoSensor`, il implémente l'interface `Tickable`.
|
||||
|
||||
Un capteur manuel ne fait qu'autoriser publiquement la modification de la température par rapport à la classe abstraite `Sensor`.
|
||||
|
||||
Un capteur virtuel est composé de plusieurs sources de température.
|
||||
C'est une variante du patron de conception composite : chaque capteur virtuel contient une liste de capteurs et de poids associés avec des objets `DataSource`.
|
@@ -16,12 +16,12 @@ import fr.uca.iut.clfreville2.model.sensor.ManualSensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.VirtualSensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.provider.AutoSensorProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.provider.ManualSensorProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.provider.SensorProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.provider.VirtualSensorProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.AutoUpdateStrategyFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.StandardUpdateStrategyFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.factory.AutoSensorFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.factory.ManualSensorFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.factory.SensorFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.factory.VirtualSensorFactory;
|
||||
import fr.uca.iut.clfreville2.persistence.StubSensorRegistryLoader;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
@@ -64,7 +64,7 @@ public class MainWindows {
|
||||
private Button changeBtn;
|
||||
|
||||
@FXML
|
||||
private ChoiceBox<AutoUpdateStrategyProvider> autoType;
|
||||
private ChoiceBox<AutoUpdateStrategyFactory> autoType;
|
||||
private final ChangeListener<AutoUpdateStrategy> autoUpdateChangeHandler = this::changedUpdateStrategy;
|
||||
|
||||
@FXML
|
||||
@@ -86,7 +86,7 @@ public class MainWindows {
|
||||
private TextField newName;
|
||||
|
||||
@FXML
|
||||
private ChoiceBox<SensorProvider> createType;
|
||||
private ChoiceBox<SensorFactory> createType;
|
||||
|
||||
@FXML
|
||||
private Button createButton;
|
||||
@@ -216,7 +216,7 @@ public class MainWindows {
|
||||
|
||||
@FXML
|
||||
private void bindProvidable() {
|
||||
autoType.getItems().addAll(StandardUpdateStrategyProvider.values());
|
||||
autoType.getItems().addAll(StandardUpdateStrategyFactory.values());
|
||||
autoType.setConverter(new NameableStringConverter<>(autoType.getItems()));
|
||||
autoType.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||
Sensor selected = getSelectedSensor();
|
||||
@@ -227,9 +227,9 @@ public class MainWindows {
|
||||
});
|
||||
|
||||
createType.getItems().addAll(
|
||||
new ManualSensorProvider(),
|
||||
new AutoSensorProvider(),
|
||||
new VirtualSensorProvider()
|
||||
new ManualSensorFactory(),
|
||||
new AutoSensorFactory(),
|
||||
new VirtualSensorFactory()
|
||||
);
|
||||
createType.setConverter(new NameableStringConverter<>(createType.getItems()));
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import fr.uca.iut.clfreville2.model.shared.TemperatureHolder;
|
||||
import fr.uca.iut.clfreville2.model.shared.ObservableIdentifiable;
|
||||
import javafx.beans.binding.DoubleExpression;
|
||||
import javafx.beans.binding.StringExpression;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
@@ -38,21 +39,6 @@ public abstract class Sensor implements ObservableIdentifiable, TemperatureHolde
|
||||
return temperatureProperty().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name.set(requireNonNull(name, "name"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyIntegerProperty idProperty() {
|
||||
return id;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.AutoUpdateStrategyFactory;
|
||||
|
||||
public interface AutoUpdateStrategy {
|
||||
|
||||
@@ -18,5 +18,5 @@ public interface AutoUpdateStrategy {
|
||||
*
|
||||
* @return The type of this strategy.
|
||||
*/
|
||||
AutoUpdateStrategyProvider getType();
|
||||
AutoUpdateStrategyFactory getType();
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.AutoUpdateStrategyFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.StandardUpdateStrategyFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -21,7 +21,7 @@ public class CpuUpdateStrategy implements AutoUpdateStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoUpdateStrategyProvider getType() {
|
||||
return StandardUpdateStrategyProvider.CPU;
|
||||
public AutoUpdateStrategyFactory getType() {
|
||||
return StandardUpdateStrategyFactory.CPU;
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.AutoUpdateStrategyFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.StandardUpdateStrategyFactory;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@@ -28,7 +28,7 @@ public class RandomUpdateStrategy implements AutoUpdateStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoUpdateStrategyProvider getType() {
|
||||
return StandardUpdateStrategyProvider.RANDOM_UPDATE;
|
||||
public AutoUpdateStrategyFactory getType() {
|
||||
return StandardUpdateStrategyFactory.RANDOM_UPDATE;
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.AutoUpdateStrategyFactory;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.factory.StandardUpdateStrategyFactory;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@@ -26,7 +26,7 @@ public class RandomVariationStrategy implements AutoUpdateStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoUpdateStrategyProvider getType() {
|
||||
return StandardUpdateStrategyProvider.RANDOM_VARIATION;
|
||||
public AutoUpdateStrategyFactory getType() {
|
||||
return StandardUpdateStrategyFactory.RANDOM_VARIATION;
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto.provider;
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto.factory;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy;
|
||||
import fr.uca.iut.clfreville2.model.shared.Nameable;
|
||||
|
||||
public interface AutoUpdateStrategyProvider extends Nameable {
|
||||
public interface AutoUpdateStrategyFactory extends Nameable {
|
||||
|
||||
AutoUpdateStrategy create();
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto.provider;
|
||||
package fr.uca.iut.clfreville2.model.sensor.auto.factory;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.CpuUpdateStrategy;
|
||||
@@ -10,7 +10,7 @@ import fr.uca.iut.clfreville2.model.sensor.auto.RandomVariationStrategy;
|
||||
* <p>
|
||||
* This enum ensures that the same strategy is always returned with the same identity.
|
||||
*/
|
||||
public enum StandardUpdateStrategyProvider implements AutoUpdateStrategyProvider {
|
||||
public enum StandardUpdateStrategyFactory implements AutoUpdateStrategyFactory {
|
||||
RANDOM_UPDATE {
|
||||
@Override
|
||||
public AutoUpdateStrategy create() {
|
@@ -1,10 +1,10 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.provider;
|
||||
package fr.uca.iut.clfreville2.model.sensor.factory;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.SensorRegistry;
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.auto.RandomVariationStrategy;
|
||||
|
||||
public class AutoSensorProvider implements SensorProvider {
|
||||
public class AutoSensorFactory implements SensorFactory {
|
||||
|
||||
@Override
|
||||
public Sensor create(SensorRegistry registry, String name) {
|
@@ -1,9 +1,9 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.provider;
|
||||
package fr.uca.iut.clfreville2.model.sensor.factory;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.SensorRegistry;
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
|
||||
public class ManualSensorProvider implements SensorProvider {
|
||||
public class ManualSensorFactory implements SensorFactory {
|
||||
|
||||
@Override
|
||||
public Sensor create(SensorRegistry registry, String name) {
|
@@ -1,10 +1,10 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.provider;
|
||||
package fr.uca.iut.clfreville2.model.sensor.factory;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.SensorRegistry;
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
import fr.uca.iut.clfreville2.model.shared.Nameable;
|
||||
|
||||
public interface SensorProvider extends Nameable {
|
||||
public interface SensorFactory extends Nameable {
|
||||
|
||||
Sensor create(SensorRegistry registry, String name);
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package fr.uca.iut.clfreville2.model.sensor.provider;
|
||||
package fr.uca.iut.clfreville2.model.sensor.factory;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.SensorRegistry;
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
|
||||
public class VirtualSensorProvider implements SensorProvider {
|
||||
public class VirtualSensorFactory implements SensorFactory {
|
||||
|
||||
@Override
|
||||
public Sensor create(SensorRegistry registry, String name) {
|
@@ -17,6 +17,11 @@ public interface ObservableIdentifiable extends Identifiable {
|
||||
*/
|
||||
ReadOnlyIntegerProperty idProperty();
|
||||
|
||||
@Override
|
||||
default int getId() {
|
||||
return idProperty().get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name property of this object.
|
||||
*
|
||||
@@ -25,6 +30,16 @@ public interface ObservableIdentifiable extends Identifiable {
|
||||
*/
|
||||
StringProperty nameProperty();
|
||||
|
||||
@Override
|
||||
default String getName() {
|
||||
return nameProperty().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setName(String name) {
|
||||
nameProperty().set(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name of this object.
|
||||
*
|
||||
|
Reference in New Issue
Block a user