Newsgroup: it.comp.java
Titolo: Come progettare un programma "orientato agli oggetti"

Salve,
vi chiedo di darmi alcuni consigli sulle principali linee guida da
seguire nella progettazione di un programma orientato agli oggetti che
devo sviluppare.
Premetto che pur conoscendo bene la teoria della programmazione OOP,
sono abbastanza a digiuno per quanto riguarda la pratica.
Ho infatti programmato a lungo usando linguaggi di programmazione non
orientati agli oggetti e anche quando ne ho usati alcuni che lo erano
(tipo il PHP) l'ho sempre fatto per sviluppare tanti semplici script
abbastanza piccoli e tutti diversi tra loro e per i quali quindi non
aveva molto senso ragionare "ad oggetti".
Ora mi trovo invece a sviluppare in Java, linguaggio che ho usato in
passato solo per esercitazioni accademiche basate sui thread o sui
socket, dove quindi l'aspetto OOP passava in secondo piano.
In breve l'applicazione che devo creare deve:
- all'avvio visualizzare una finestra di login
- dopo che l'utente ha immesso i dati di autenticazioni, validarli
connettendosi a un database MySQL
- in caso di autenticazione riuscita, visualizzare una seconda
finestra contenente una struttura ad albero attraverso la quale
l'utente deve poter navigare all'interno di varie directory, scegliere
quale file visualizzare e successivamente aprirlo tramite
un'applicazione esterna (del tipo Universal File Viewer).
In aggiunta devo prevedere le seguenti funzionalità:
- il login deve poter essere effettuato non solo attraverso
l'inserimento standard di username e password in due campi di testo ma
anche mediante altri metodi come per esempio attraverso smart-card o
biometrici (per ora da non implementare ma comunque da prevedere)
- ogni azione effettuata dall'utente (login riuscito, login fallito,
logout, apertura di un file, chiusura di un file, ecc.) deve venire
registrata in un log (realizzato attraverso una tabella su un
database)
- l'utente deve avere la possibilità di indicare e salvare alcune
preferenze relative al programma come per esempio l'indirizzo della
base di dati a cui connettersi, il DBMS su cui gira (se MySQL o
altro), ecc. ecc.
Ovviamente non vi chiedo di dirmi come fare le singole parti del mio
programma, volevo solo che mi aiutaste a progettare astrattamente
l'applicazione in questione, dal punto di vista di classi, interfacce
e oggetti.
Intanto vi dico come avevo pensato di svilupparla io: ditemi cosa ne
pensate e siate clementi, tenendo conto che è la prima applicazione
completamente OOP.
Il main.java contiene solo una chiamata del tipo: LoginWindow().
La classe LoginWindow presenta una finestra all'interno della quale è
possibile inserire user e password per procedere all'autenticazione.
Al clic del pulsante i dati inseriti vengono trasmessi come parametri
alla classe StandardLogin che implementa l'interfaccia Login(). Questa
interfaccia ha i due metodi astratti doLogin(String username, String
password) e doLogout(String username). Ho pensato a un'interfaccia per
poi poter in seguito implementare anche le classi BiometricLogin e
SmartCardLogin che (per semplificare) ho pensato che potrebbero
funzionare sempre inviando all'interfaccia due stringhe.
La classe StandardLogin fa uso di un'altra classe Database, la quale
si preoccupa di connettersi al database e fornire dei metodi per
eseguire su di esso delle query di interrogazione (SELECT) e delle
query di aggiornamento (DELETE, INSERT e UPDATE).
La classe StandardLogin, in caso di autenticazione riuscita, chiude il
frame di autenticazione e apre quello di visualizzazione dei files (ai
quali però penserò in un secondo momento, prima volevo impostare bene
questa prima parte del programma).
Ovviamente esiste anche una classe Log che si occupa di scrivere e
memorizzare in una apposita tabella del database qualsiasi azione
venga effettuata dall'utente. Ho quindi pensato di chiamare i metodi
Log.InserisciLog(String azione, String Usurname, String timestamp)
all'interno del codice di verifica dell'autenticazione.
Sperando di essere stato abbastanza chiaro e di non aver fatto troppi
errori, vi posto brevemente il meta-codice che ho sviluppato finora.
---------------------------------------------------
public class Main {
    public static void main(String[] args) {
        new LoginWindow();
    }
}
-------------------------------------------------
public interface Login {
    public boolean doLogin(String username, String password);
    public void doLogout(String username);
}
------------------------------------------------
public class Database {
   private String nomeDB;       // Nome del Database a cui connettersi
   private String nomeUtente;   // Nome utente utilizzato per la
connessione al Database
   private String pwdUtente;    // Password usata per la connessione
al Database
   private String errore;       // Raccoglie informazioni riguardo
l'ultima eccezione sollevata
   private Connection db;       // La connessione col Database
   private boolean connesso;    // Flag che indica se la connessione
Ã¨ attiva o meno
   public Database() { this("dbMaster", "daemon", "password"); }
   public Database(String nomeDB, String nomeUtente, String pwdUtente)
{
      this.nomeDB = nomeDB;
      this.nomeUtente = nomeUtente;
      this.pwdUtente = pwdUtente;
      connesso = false;
      errore = "";
   }
   // Apre la connessione con il Database
   public boolean connetti(DBMS quale) {
      connesso = false;
      String conString = null;
      try {
        switch (quale)
        {
            case MYSQL:
                // Carico il driver JDBC per la connessione con il
database MySQL
                Class.forName("com.mysql.jdbc.Driver");
                conString = "jdbc:mysql://localhost/" + nomeDB + "?
user=" + nomeUtente + "&password=" + pwdUtente;
                break;
            case ODBC:
                // Carico il driver JDBC per la connessione con il
database ODBC
                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
                conString = "jdbc:odbc:" + nomeDB;
                break;
        }
         // Mi connetto al database
         db = DriverManager.getConnection(conString);
         connesso = true;
      } catch (Exception e) { errore = e.getMessage(); }
      return connesso;
   }
   // Esegue una query di selezione dati sul Database
   public Vector eseguiQuery(String query) {
      //...
   }
   // Esegue una query di aggiornamento sul Database
   public boolean eseguiAggiornamento(String query) {
// ...
   }
   public boolean isConnesso() { return connesso; }   // Ritorna TRUE
se la connessione con il Database è¨ attiva
   public String getErrore() { return errore; }       // Ritorna il
messaggio d'errore dell'ultima eccezione sollevata
}
-------------------------------------------------------------
public class StandardLogin implements Login {
    public boolean doLogin(String username, String password) {
        Database db = new Database();
        db.connetti(MYSQL);
        Vector v = db.eseguiQuery("SELECT * FROM utenti WHERE
username='" + username + "' AND password = md5('" + password +
"');" );
        if ( v.size() > 0) return true;
        else return false;
    }
    public void doLogout(String username) {
    }
}
------------------------------------------------------------------
public class LoginWindow extends JFrame
{
	// Variables declaration
	private JLabel jLabel1;
	private JLabel jLabel2;
	private JTextField jTextField1;
	private JPasswordField jPasswordField1;
	private JButton jButton1;
	private JPanel contentPane;
	// End of variables declaration
	public LoginWindow()
	{
		super();
		create();
		this.setVisible(true);
	}
	private void create()
	{
		// ...
	}
	private void addComponent(Container container,Component c,int x,int
y,int width,int height)
	{
		// ...
	}
    private void jButton1_actionPerformed(ActionEvent e)
	{
		System.out.println("\njButton1_actionPerformed(ActionEvent e)
called.");
		String username = new String(jTextField1.getText());
		String password = new String(jPasswordField1.getText());
                                StandardLogin auth = new StandardLogin
();
                                if (auth.doLogin(username, password))
            {
                JLabel optionLabel = new JLabel("Login effetuato");
                JOptionPane.showMessageDialog(null,optionLabel);
                dispose();
            }
            else
            {
                JLabel optionLabel = new JLabel("Username o password
errati");
                JOptionPane.showMessageDialog(null,optionLabel);
                jPasswordField1.setText("");
            }
        }
    }
}

 se la connessione con il Database � attiva

Tutto sostanzialmente corretto.
Se vuoi un consiglio, inizia a guardarti PureMVC
Un framework come quello � sicuramente ostico e sproporzionato per
applicazioni piccole, ma ti obbliga a restare ordinato e rende
l'applicazione facile da estendere e documentare