Newsgroup: it.comp.java
Titolo: Aiuto impostazione programma Java

Salve a tutti, sono un nuovo arrivato nel mondo Java (provengo dal C)
e ho ancora le idee un po' confuse.
Stavo facendo un esercizio preso da un online judge per esercitarmi
(
http://tinyurl.com/35ry29l
) e vorrei avere un parere da persone più
esperte per sapere se mi sto muovendo nel modo corretto.
Stavo facendo la validazione dell'input, in particolare quello della
prima riga della serie, in cui vengono passati il numero di scatole e
il numero di dimensioni di ognuna di loro.
Il programma viene scritto nel file boxes.java, per cui ho iniziato
scrivendo una public class boxes che contiene il main, come riportato
qui sotto:
public class boxes{
        //Costanti usate nel programma
        static int MAX_DIMENSIONALITY=10;
        static int MIN_DIMENSIONALITY=1;
        static int MAX_NUM_BOXES=30;
        public static void main(String args[]){
                //i=num. scatole; k=dim. scatole;
                int i=0, k=0;
                //stringa che contiene i valori inseriti dall'utente
                StringaIngresso sequenza= new StringaIngresso();
                Scanner input = new Scanner(System.in);
                sequenza.inserimento=input.nextLine();
                sequenza.checkSequenza(i,k);
                System.out.println("\n i ->" + i + "; k ->" + k +
";");
        }
}
nello stesso file, dopo la classe boxes creo un'altra classe
StringaIngresso, che conterrà una stringa (inserimento) e i metodi per
la validazione. Può andare bene come impostazione generale del
programma o è sbagliata/ha complicazioni non necessarie?
Un'altra cosa che non mi è chiara è il mio obbiettivo era far salvare
nei parametri i e k che passo al metodo checkSequenza i valori di i e
k immessi nell'utente. Ovviamente i valori vengono calcolati bene nel
metodo ma poi non vengono ripassati al programma principale. Se fosse
stato un solo parametro avrei potuto metterlo nel return type del
metodo, ma se sono 2 non posso.
In questi casi come ci si comporta in java? In C passerei due
puntatori e non avrei problemi, qui dovrei per forza creare un oggetto
Array di due elementi in cui salvare i e k e passare quello? O
esistono dei sistemi migliori?
Capisco che si tratti di domande stupide per chi ha già un po' di
domestichezza con il linguaggio, ma per uno come me che è agli inizi
non sono così immediate, specie per il radicale cambiamento di
impostazione del problema rispetto a quanto sono abituato a fare.

 sistemi migliori? [...]
Invece di passare un array puoi passare un oggetto creato appositamente, 
o usare variabili di istanza o di classe, se le circostanze lo 
permettono. Se posti il codice ti dico cosa farei io.
-- 
joat.it
/ Information Technology Jack of All Trades /


Allora, se ho capito bene non ti interessa un tubo del problema in se,
ma vuoi imparare a programmare _in_java_
Pertanto ecco i miei consigli:
1) In Java, che non è solo un linguaggio ma anche una serie di
convenzioni (rispettate dai progammatori al 99,9999% (in pratica non
viene rispettato solo dalle librerie che 'wrappano' lib scritte in
altri linguaggi, nel qual caso se chi ha fatto il wrap è programmatore
java, le convenzioni sono java, se invece il wrap è fatto da un
programmatore C++ le convenzioni  sono quelle del C++ (e il javista
non capisce + un tubo...)
1.1) Ad es. in nomi delle classi con prima lettera in maiuscolo e poi
convenzione camelcase (ovvero minuscolo e poi una maiusolca ad ogni
cambio di parola. Ad es. ClasseConNomeMoltoLungo.
1.2) Non aver paura a scrivere variabili/classi/metodi con nomi
lunghi. Ne vale veramente la pena se devi manutenere il codice!
2) Solitamente, si evita di mettere qualunque logica nel main. Questo
perché poni un limite intrinseco al tuo programma (venire eseguito da
commandline). Questo può andare bene ad es. nei sistemi *nix, dove
'tutto' passa attraverso gli script di shell, ma in Java di solito i
programmi sono intesi 'monolitici' nel senso che sono intesi per
essere eseguiti in un unico processo dal'inizio alla fine (no ai fork,
si al multithreading). Credo la cosa dipenda dal fatto che è 'costoso'
tirar su una JVM, e che basarsi su shell pone limiti alla portabilità
in generale.
L'_unica_ eccezione, eventuale parsing dei parametri agrs[]. Leggendo
il problema, pare che l'input sia 'a blocchi' indipendenti. Per cui io
in teoria, dividerei l'input in problemi distinti (l'esempio mostra
due problemi, uno riguardante 5 scatole 'bidimensionali', l'altro 8
scatole 6-dimensionali.
Purtroppo chi ha deciso il formato del file ha fatto del suo meglio
per renderlo difficile da interpretare (usando una logica OO) per cui
io farei innanzitutto una funzione che dato uno stream (perché
limitarsi a System.in o ad un File? potrebbe anche essere un Url o
chissà che altro!) ritorni una lista di problemi (classe
StackingBoxes). A livello implelemtatitvo darei una occhiata alle
classi BufferedInputStream che permettere di leggere una riga alla
volta, e a StreamTokenizer che permette di spezzare le stringhe
facilmente.
public class Boxes{
    //Costanti usate nel programma
    static int MAX_DIMENSIONALITY=10;
    static int MIN_DIMENSIONALITY=1;
    static int MAX_NUM_BOXES=30;
    public static void main(String args[]){
       if(args.length!=1)
         throw Exception("Filename is required")
       new Boxes(new File(args[0]));
    }
    Boxes(InputStream is){
        List<StackingBoxes> problems = parse(is);
        List<StackingBoxesSolutions> solutions = new
ArrayList<StackingBoxesSolutions>();
        for(StackingBoxes problem:problems){
           solution.add(problem.solve());
        }
        for(StackingBoxesSolutions solution:solutions)
           solution.display();
    }
}