2015-07-31 10 views
11

A volte visualizzo finestre di dialogo nella mia applicazione Java.Quale modello di progettazione è possibile utilizzare per mostrare le finestre di dialogo?

Attualmente le classi di controller sono (si aspettano alcune eccezioni in cui solo i getter vengono chiamati sul mio modello) utilizzate come mediatori tra il mio modello e l'interfaccia utente.

Ma la mia interfaccia utente conosce i miei controller ei miei controller conoscono la mia interfaccia utente.

Ogni volta che aggiungo una nuova finestra di dialogo aggiungo un metodo in un controller e nella classe di visualizzazione.

C'è un modo più elegante per estendere il mio programma con le finestre di dialogo di nuovi utenti utilizzando un modello di progettazione?

Per illustrarti come appare la mia interazione adesso aggiungerò alcuni frammenti di codice.

codice dal mio UI

itmEmailSettings.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      controller.showEmailSettingsDialog(); 
     } 
    }); 

più codice UI

public void showEmailSettingsDialog(String host, int port, int authMode, 
      String user, String pass, String fromEMail, String fromName) { 
     EmailSettingsDialog d = new EmailSettingsDialog(
       host, port, authMode, 
       user, pass, fromEMail, fromName 
       ); 
     d.createJDialog(mainFrame.getFrame()).setVisible(true); 
     if(d.isValid()){ 
      controller.changeEmailSettings( d.getHost(), d.getPort(), d.getAuthMode(), d.getFromEMail(), d.getFromName(), d.getUser(), d.getPass() ); 
     } 
    } 
codice

Controller:

public void showEmailSettingsDialog() { 
    try{ 
     if(!pm.hasProjectFileAccess()){ 
      mainFrame.showNoProjectfileAccess(); 
      return; 
     } 
     ProgrammSettingsRepository pr = Utils.getProgrammSettingsRepository(pm); 
     String host = pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_HOST); 
     int port = pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_PORT)==null?0:Integer.parseInt(pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_PORT)); 
     int authMode = pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_SSL_MODE)==null?0:Integer.parseInt(pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_SSL_MODE)); 
     String user = pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_USER); 
     String pass = pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_PASSWORD); 
     String fromEMail = pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_FROM_EMAIL); 
     String fromName = pr.retreive(ProgrammSettingsRepository.KEY_EMAIL_FROM_NAME); 

     menuView.showEmailSettingsDialog(host, port, authMode, user, pass, fromEMail, fromName); 
    }catch(SQLException e){ 
     throw new RuntimeException(e.getMessage(), e); 
    } 
} 

public void changeEmailSettings(String host, int port, int authMode, 
     String fromEMail, String fromName, String user, String pass) { 
    try { 
     ProgrammSettingsRepository pr = Utils.getProgrammSettingsRepository(pm); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_HOST , String.valueOf(host)); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_PORT , String.valueOf(port)); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_SSL_MODE , String.valueOf(authMode)); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_USER , String.valueOf(user)); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_PASSWORD, String.valueOf(pass)); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_FROM_EMAIL , String.valueOf(fromEMail)); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_FROM_NAME , String.valueOf(fromName)); 
     pr.store(ProgrammSettingsRepository.KEY_EMAIL_SETTINGS_CONFIGURED, "true"); 
    } catch (SQLException e) { 
     throw new RuntimeException(e.getMessage(), e); 
    } 
} 
+0

Forse posso utilizzare un metodo onIsValid per i miei dialoghi e un metodo onIsInvalid. Questi metodi ricevono i runnable dai controller. Il Controller è responsabile della creazione dell'oggetto Dialog e dell'invio all'interfaccia utente. Che visualizza la finestra di dialogo e utilizza i callback. Ma in questo modo la classe controller deve ancora essere cambiata per ogni finestra di dialogo da mostrare, ciò che penso sia ok. Ogni comando dell'interfaccia utente comporta un cambiamento nelle mie classi di controller, vero? –

+1

Non sono sicuro che l'utilizzo diretto di uno schema di progettazione * riconosciuto * sia necessario per pulire questo problema. – crush

+0

Anche il buon OOP potrebbe fare il lavoro. –

risposta

3

I underst e che dall'interfaccia utente chiamate Controller e quindi chiamate l'interfaccia utente dal controller per mostrare la finestra di dialogo. Il controller esegue alcuni calcoli e quindi chiama l'interfaccia utente per mostrare la finestra di dialogo.

Se si implementa IReportable nelle classi UI.

public interface IReportable { 
    public void showYesNoDialog(//all needed params); 
    public void showSimpleDialog(//all needed params); 
      . 
      . 
      . 
} 

public class DialogController() { 
    private IRportable _reportable;//delegator 

    public DialogController(IRportable _reportable) {//bridge pattern. 
     _reportable = reportable; 
    } 

    public void showEmailDialog() { 
     //calculations 
     _reportable.showSimpleDialog(//params); 
    } 

    public void showCustomerDialog() { 
     //calculations 
     _reportable.showYesNoDialog(//params); 
    } 

} 

public class UIClass implements IReportable { 
    private DialogController _dialogController; 

    public UIClass() { 
     _dialogController = new DialogController(); 
    } 

    public void someMethod() { 
     if() { 

     } 
     ... 
     _dialogController.showEmailDialog(); 
    } 

    public void someOtherMethod() { 
     if() { 

     } 
     ... 
     _dialogController.showCustomerDialog(); 
    } 

    @Override 
    public void showYesNoDialog(//all needed params) { 
     //code here to show dialog according to params. 
    } 

    @Override 
    public void showSimpleDialog(//all needed params) { 
     //code here to show dialog according to params. 
    } 

} 

In questo modo si dispone di dipendenza per l'interfaccia e non a singoli componenti dell'interfaccia utente. È possibile modificare l'interfaccia in classe astratta per avere la stessa funzionalità per tutte le classi dell'interfaccia utente ...

+0

Attualmente non passo i parametri ma le classi che creano una finestra di dialogo concreta nell'interfaccia utente. Ma non c'è un vero vantaggio presumo –

+2

È meglio esporre interfacce rispetto alla classe in un modo per creare plug-in separati per ciascuno dei tuoi pacchetti ed è meglio distribuire le interfacce e chiedere ai programmatori di rispettarle. Non date lezioni che date interfacce. – ddarellis