Partage
  • Partager sur Facebook
  • Partager sur Twitter

Bloque Statique

    15 janvier 2020 à 18:59:05

    Bonsoir,

    J'ai un programme qui permet de simuler des capteurs de température en fonction de différents algorithmes.

    Ces algorithmes sont créés par moi-même mais je veux laisser la possibilité aux autres développeurs d'en ajouter à leur guise.

    Le problème c'est que lorsqu'on crée un capteur, l'utilisateur a une liste des algorithmes qui existe et il peut en sélectionner un.

    Je voudrais donc permettre aux développeur d'intégrer un nouvel algorithme et qu'il apparaisse automatiquement dans ma vue.

    Pour cela, j'ai créé une classe mère qui est abstraite : 

    /***
     * WARNING : Don't forget to call notifyFatherIExist() in a static block to display this algo in the mainView comboBox
     */
    
    public abstract class SensorAlgoChanger implements Serializable {
        private static ArrayList<Class> listSons = new ArrayList<>();
        private final double MIN =-273.15;
        private final double MAX = 4000;
        private final static Random RANDOM = new Random();
        public static int i;
    
        public abstract double doTemperature();
    
        public double getMin()
        {
            return MIN;
        }
        public double getMax(){
            return MAX;
        }
        public Random getRandom(){
            return RANDOM;
        }
    
    
        public static void addSon(Class classAlgo)
        {
            listSons.add(classAlgo);
        }
    
        public static ArrayList<String> getSons() {
            ArrayList<String> listReturn = new ArrayList<>();
            for (Class c : listSons) {
                int start = c.getName().indexOf(".") + 1;
                int end = c.getName().length();
                listReturn.add(c.getName().substring(start, end));
            }
            return listReturn;
        }
    
        public static void notifyFatherIExist(Class classAlgo)
        {
            addSon(classAlgo);
        }
    
    
    }

    Et chaque fils hérite de cette classe mère de la façon suivante : 

    public class AlgoSmallFluctuation extends SensorAlgoChanger {
        private double currentTemperature;
        private boolean isFirstTemperature;
        private double delta;
    
    
        static
        {
            System.out.println("salute");
            notifyFatherIExist(AlgoSmallFluctuation.class);
        }
    
        public AlgoSmallFluctuation(double coef, double firstTemperature)
        {
            delta = coef;
            currentTemperature = firstTemperature;
            this.isFirstTemperature = true;
        }
    
    
        @Override
        public double doTemperature() {
            if (isFirstTemperature){
                isFirstTemperature = false;
                return currentTemperature;
            }
            currentTemperature = currentTemperature + (getRandom().nextDouble()*(delta + delta) - delta);
            if (currentTemperature >= getMax())
                return getMax();
            if (currentTemperature <= getMin())
                return getMin();
            //System.out.println(previousTemperature);
            return currentTemperature;
        }
    
    
    }

    Le truc c'est que je pensais que la classe était chargée automatiquement au lancement du programme et ainsi, le bloque statique était automatiquement appelé. Du coup, si je n'est pas au préalable appelé explicitement la classe dans mon code, le bloque statique n'est jamais exécuté et ainsi, le programme n'a pas connaissance que cet algorithme existe. Existe-t-il une solution pour remédier à cela sans que le développeur n'est à rajouter du code dans les classes existantes ?

    Merci de votre réponse :)

    -
    Edité par ThéoRamousse 15 janvier 2020 à 19:01:51

    • Partager sur Facebook
    • Partager sur Twitter
      16 janvier 2020 à 10:07:15

      Quelques conseils d'abord :

      • Déclare MIN et MAX private static final. Comme ce sont des constantes, ils n'ont aucune raison d'être des variables d'instance.
      • Si tu ne veux pas que les classes filles puissent modifier le minimum et le maximum, déclare les méthodes getMin() et getMax() public static final. Sinon, n'importe qui peut réécrire tes méthodes getMin() et getMax() et passer outre les limites que tu avais fixées.
      • Que se passe-t-il si la classe fille fait partie d'un package à plusieurs niveaux (par exemple com.example.AlgoSmallFluctuation) ? Est-ce que le résultat de getSons() est bien ce que tu attends dans ce cas ?

      Pour répondre à ta question principale, il te faut un système de chargement automatique de classes sur le modèle des plugins. Tu peux chercher de ce côté-là par exemple.

      • Partager sur Facebook
      • Partager sur Twitter
        16 janvier 2020 à 15:13:59

        Zachee54 a écrit:

        Quelques conseils d'abord :

        • Déclare MIN et MAX private static final. Comme ce sont des constantes, ils n'ont aucune raison d'être des variables d'instance.
        • Si tu ne veux pas que les classes filles puissent modifier le minimum et le maximum, déclare les méthodes getMin() et getMax() public static final. Sinon, n'importe qui peut réécrire tes méthodes getMin() et getMax() et passer outre les limites que tu avais fixées.
        • Que se passe-t-il si la classe fille fait partie d'un package à plusieurs niveaux (par exemple com.example.AlgoSmallFluctuation) ? Est-ce que le résultat de getSons() est bien ce que tu attends dans ce cas ?

        Pour répondre à ta question principale, il te faut un système de chargement automatique de classes sur le modèle des plugins. Tu peux chercher de ce côté-là par exemple.

        Merci pour ta réponse mais le problème reste le même : Le développeur qui veut créer un nouvel algorithme doit renseigner la classe dans le fichier META-INF ?

        Pour ce qui est de getMin et getMax, c'est normal qu'il soient abstraits pour que le développeur puisse ne pas mettre de bordures s'il le souhaite.

        • Partager sur Facebook
        • Partager sur Twitter
          16 janvier 2020 à 15:44:28

          OK pour getMin() et getMax().

          Le principe est que ton application va charger toutes les classes qui héritent de SensorAlgoChanger et qui se trouvent dans un répertoire précis, par exemple un sous-répertoire plugins.

          Ainsi le développeur n'a qu'à mettre son JAR dans ce répertoire, ton application trouvera la classe et exécutera son bloc static.

          • Partager sur Facebook
          • Partager sur Twitter
            16 janvier 2020 à 16:27:45

            Zachee54 a écrit:

            OK pour getMin() et getMax().

            Le principe est que ton application va charger toutes les classes qui héritent de SensorAlgoChanger et qui se trouvent dans un répertoire précis, par exemple un sous-répertoire plugins.

            Ainsi le développeur n'a qu'à mettre son JAR dans ce répertoire, ton application trouvera la classe et exécutera son bloc static.


            Ah ok je n'avais pas compris ça. Le problème, c'est qu'un algorithme à une page FXML associée et mes pages FXML se trouvent toutes dans le même répertoire.
            • Partager sur Facebook
            • Partager sur Twitter

            Bloque Statique

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown