• [^] # Re: ... et pas qu'un ...

    Posté par (site web personnel, Mastodon) . En réponse au journal Du développement full-stack en Java. Évalué à 10. Dernière modification le 03 août 2018 à 16:18.

    Être obligé de jongler avec plusieurs langages en fonction du type d'application à développer ? Non merci, je préfère pouvoir développer tout type d'application en utilisant un seul langage ; c'est beaucoup plus efficace.

    Ou pas.

    Mon stage de fin d'études c'était justement la migration d'une application mono-langage (Progress 4GL) à une pile de langages plus spécialisés (Java, HTML, JS, SQL). Eh bien la pile de langages était infiniment plus facile à comprendre et utiliser que l'espèce de soupe qui prétendait tout faire, des requêtes à la BDD aux effets présentés à l'utilisateur.


    Ça fait la troisième fois (en comptant la version Node.js) qu'ont dit que mon code est nettement perfectible (ce dont j'ai parfaitement conscience, comme je l'ai à maintes fois indiqué). Je veux bien, mais est-ce que quelqu'un aurait la bonté de me montrer ne fût-ce qu'un exemple de ce qui ne va pas, et comment le corriger, histoire que j'ai l'occasion d'améliorer mon code ? Ou alors je vais finir pas penser que mon code n'est peut-être pas aussi mauvais que certains le prétendent !

    Je vais être sec aussi, mais en ce qui concerne ton code Java, il n'y a tellement rien qui va que te l'expliquer en détail est un travail si énorme que c'est décourageant.

    Si je prends juste en exemple le TODO MVC :

    • Le fichier s'appelle main.java mais ne contient pas de classe publique qui s'appelle main.
    • Le fichier n'est pas dans un package.
    • Deux classes (package-protected) dans le même fichier.
    • Tu utilises des new String("...").
    • int index = this.index; ?!
    • D'ailleurs tu passes ton temps à masquer la variable de classe index avec des variables locales index.
    • Tu n'utilises pas les possibilités de l'API standard (l'itérateur ligne 43, le while ligne 197 par exemple, ou tout le bloc de if / else if à partir de la ligne 230).
    • if ( false ) { !?
    • La ligne 273 ressemble beaucoup à une boucle infinie.
    • Ton main lance Exception, ce qu'il ne devrait pas faire, et en plus rien dans ton code ne déclare que cette Exception devrait être lancée.
    • Tu appelles des méthodes avec leur package complet au lieu de les importer (info.q37.xdhq.XDH.readAsset).
    • Tout est ultra-manuel : génération de XML à la main en dur dans le code, méthode escape que tu as réinventé, etc.
    • Tout est en vrac dans un seul fichier : personnellement je ne comprends pas ce que fait ce code à sa simple lecture.
    • J'imagine que le index de la classe TodoMVC pourrait être nullable pour gérer le cas particulier au lieu d'utiliser la valeur spécifique -1.
    • Dans la méthode push tu modifies ton paramètre xml.
    • La logique contient des triples négations : dans handleCount tu as un else sur une condition négative qui active un truc qui s'appelle HideBidule. Au final ça fait quoi ?
    • D'ailleurs le projet s'appelle TODO MVC mais n'est pas du tout du MVC ?!
    • Je passe sur les détails comme le formatage, la présence d'un System.out, l'import de packages complets ou le manque d'accolades.
    • Je passe aussi sur ton API qui me semble très étrange, comme ces méthodes qui attendent un tableau de tableau de String.

    Rien qu'en re-présentant le code correctement, ça donnerait quelque chose comme :

    package todomvc;
    /*
     Copyright (C) 2018 Claude SIMON (http://q37.info/contact/).
     This file is part of XDHq.
     XDHq is free software: you can redistribute it and/or
     modify it under the terms of the GNU Affero General Public License as
     published by the Free Software Foundation, either version 3 of the
     License, or (at your option) any later version.
     XDHq is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     Affero General Public License for more details.
     You should have received a copy of the GNU Affero General Public License
     along with XDHq If not, see <http://www.gnu.org/licenses/>.
    */
    import info.q37.atlas.Atlas;
    import info.q37.atlas.DOM;
    import info.q37.atlas.GUI;
    import info.q37.xdhq.XDH;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.ListIterator;
    class Todo {
     public boolean completed;
     public String label;
     Todo(String label, boolean completed) {
     this.completed = completed;
     this.label = label;
     }
     Todo(String label) {
     this(label, false);
     }
    }
    class TodoMVC extends Atlas {
     private Boolean exclude;
     private int index = -1;
     private List<Todo> todos;
     private int itemsLeft() {
     return (int) todos.stream()
     .filter(todo -> !todo.completed)
     .count();
     }
     private String escape( String text ) {
     return text
     .replace( "&", "&amp;")
     .replace( "\"", "&quot;")
     .replace( "<", "&lt;")
     .replace( ">", "&gt;");
     }
     private String push(Todo todo, int id, String xml) {
     return xml
     + "<Todo"
     + " id=\"" + id + "\""
     + " completed=\"" + todo.completed + "\">"
     + escape(todo.label)
     + "</Todo>\n";
     }
     private void displayCount(DOM dom, int count) {
     String text = "";
     switch (count) {
     case 0:
     break;
     case 1:
     text = "1 item left";
     break;
     default:
     text = count + " items left";
     break;
     }
     dom.setContent("Count", text);
     }
     private void handleCount( DOM dom ) {
     int count = itemsLeft();
     if (count != todos.size())
     dom.disableElement("HideClearCompleted");
     else
     dom.enableElement("HideClearCompleted");
     displayCount(dom, count);
     }
     private void displayTodos( DOM dom ) {
     String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<XDHTML>\n<Todos>\n";
     ListIterator<Todo> li = todos.listIterator();
     while (li.hasNext()) {
     int index = li.nextIndex();
     Todo todo = li.next();
     if ((exclude == null) || (todo.completed != exclude))
     xml = push(todo, index, xml);
     }
     xml = xml + "</Todos>\n</XDHTML>";
     dom.setLayoutXSL("Todos", xml, "Todos.xsl");
     handleCount( dom );
     }
     private void submitNew( DOM dom ) {
     String content = dom.getContent("Input");
     dom.setContent("Input", "");
     if (!"".equals(content.trim())) {
     todos.add(0, new Todo(content));
     displayTodos( dom );
     }
     }
     private void submitModification( DOM dom ) {
     int index = this.index;
     this.index = -1;
     String content = dom.getContent("Input." + index);
     dom.setContent("Input." + index, "");
     if (!"".equals(content.trim())) {
     todos.set(index, new Todo(content, todos.get(index).completed));
     dom.setContent("Label." + index, escape(content));
     dom.removeClasses( new String[][] { { "View." + index, "hide" }, { "Todo." + index, "editing" } } );
     } else {
     todos.remove(index);
     displayTodos( dom );
     }
     }
     private void toggle( DOM dom, String id) {
     int index = Integer.parseInt(id);
     Todo todo = todos.get(index);
     todo.completed = !todo.completed;
     todos.set(index, todo);
     dom.toggleClass( "Todo." + id, "completed");
     dom.toggleClass( "Todo." + id, "active");
     if (exclude != null)
     displayTodos( dom );
     else
     handleCount( dom );
     }
     private void all( DOM dom ) {
     exclude = null;
     dom.addClass("All", "selected");
     dom.removeClasses(new String[][] { { "Active", "selected" }, { "Completed", "selected" } } );
     dom.disableElements(new String[]{"HideActive","HideCompleted"});
     }
     private void active( DOM dom ) {
     exclude = true;
     dom.addClass("Active", "selected");
     dom.removeClasses(new String[][] { { "All", "selected" }, { "Completed", "selected" } } );
     dom.disableElement("HideActive");
     dom.enableElement("HideCompleted");
    }
     private void completed( DOM dom ) {
     exclude = false;
     dom.addClass("Completed", "selected");
     dom.removeClasses( new String[][] { { "All", "selected" }, { "Active", "selected" } } );
     dom.disableElement("HideCompleted");
     dom.enableElement("HideActive");
     }
     private void clear( DOM dom ) {
     todos.removeIf(todo -> todo.completed);
     displayTodos( dom );
     }
     private void edit(DOM dom, String id) {
     String content = dom.getContent(id);
     index = Integer.parseInt(content);
     dom.addClasses( new String[][] { { "View." + content, "hide" }, { id, "editing" } } );
     dom.setContent("Input." + content, todos.get(index).label);
     dom.focus("Input." + content);
     }
     private void cancel( DOM dom ) {
     int index = this.index;
     this.index = -1;
     dom.setContent("Input." + index, "");
     dom.removeClasses( new String[][] { { "View." + index, "hide" }, { "Todo." + index, "editing" } } );
     }
     public TodoMVC() {
     System.out.println("Connection detected...");
     todos = new ArrayList<>();
     }
     public void handle( DOM dom, String action, String id ) {
     switch (action) {
     case "Connect":
     dom.headUp(XDH.readAsset("HeadDEMO.html"));
     dom.setLayout("", XDH.readAsset("Main.html"));
     dom.focus("Input");
     dom.disableElements(new String[]{"HideActive", "HideCompleted"});
     displayTodos(dom);
     break;
     case "Submit":
     if (index == -1)
     submitNew(dom);
     else
     submitModification(dom);
     break;
     case "Destroy":
     todos.remove(Integer.parseInt(dom.getContent(id)));
     displayTodos(dom);
     break;
     case "Toggle":
     toggle(dom, id);
     break;
     case "All":
     all(dom);
     break;
     case "Active":
     active(dom);
     break;
     case "Completed":
     completed(dom);
     break;
     case "Clear":
     clear(dom);
     break;
     case "Edit":
     edit(dom, id);
     break;
     case "Cancel":
     cancel(dom);
     break;
     default:
     throw new RuntimeException("No or unknown action !!!");
     }
     }
     public static void main(String[] args) {
     String dir;
     if ( System.getenv("EPEIOS_SRC") == null )
     dir = ".";
     else
     dir = "TodoMVC";
     launch("Connect", dir, GUI.DEFAULT, args);
     while (true)
     new TodoMVC();
     }
    }

    (non testé).

    La connaissance libre : https://zestedesavoir.com