2015-07-31 19 views
11

Ich zeige manchmal Dialogfelder in meiner Java-Anwendung.Welches Entwurfsmuster könnte ich zum Anzeigen von Dialogfeldern verwenden?

Derzeit werden die Controller-Klassen (erwarten einige Ausnahmen, bei denen nur Getter auf meinem Modell aufgerufen werden) als Mediatoren zwischen meinem Modell und meiner UI verwendet.

Aber meine Benutzeroberfläche kennt meine Controller und meine Controller kennen meine Benutzeroberfläche.

Immer, wenn ich einen neuen Dialog hinzufüge, füge ich eine Methode in einem Controller und in der View-Klasse hinzu.

Gibt es eine elegantere Möglichkeit, mein Programm mit neuen Benutzerdialogen zu erweitern, indem ein Designmuster verwendet wird?

Um Ihnen zu zeigen, wie meine Interaktion jetzt aussieht, werde ich einige Code-Schnipsel anhängen.

-Code von meinem UI

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

Weitere UI-Code

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() ); 
     } 
    } 

Controller-Code:

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

Vielleicht kann ich eine OnIsValid-Methode für meine Dialoge und eine OnIsInvalid-Methode verwenden. Diese Methoden erhalten Runnables von den Controllern. Der Controller ist dafür verantwortlich, das Dialog-Objekt zu erstellen und es an die Benutzerschnittstelle zu senden. Welche den Dialog anzeigt und die Rückrufe verwendet. Aber auf diese Weise muss die Controller-Klasse noch für jeden anzuzeigenden Dialog geändert werden, was ich für okay halte. Jeder UI-Befehl führt zu einer Änderung meiner Controller-Klassen, nicht wahr? –

+1

Ich bin mir nicht sicher, ob direkt ein anerkanntes * Designmuster * verwendet werden muss, um dies zu bereinigen. – crush

+0

Gute OOP könnte auch den Job erledigen. –

Antwort

3

I underst und das von der Benutzeroberfläche rufen Sie Controller und dann rufen Sie die Benutzeroberfläche von Controller, um den Dialog anzuzeigen. Der Controller führt einige Berechnungen durch und ruft dann die Benutzeroberfläche auf, um den Dialog anzuzeigen.

Wenn Sie IReportable für die UI-Klassen implementieren.

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. 
    } 

} 

Auf diese Weise haben Sie Abhängigkeit für die Schnittstelle und nicht für einzelne Komponenten. Sie können die Schnittstelle zur abstrakten Klasse ändern, um die gleiche Funktionalität für alle UI-Klassen zu haben ...

+0

Zur Zeit übergebe ich keine Parameter, sondern Klassen, die einen konkreten Dialog zur Benutzeroberfläche erstellen. Aber es gibt keinen wirklichen Vorteil, den ich annehme –

+2

Es ist besser, Interfaces als Klasse in einer Weise verfügbar zu machen, separate Plugins für jedes Ihrer Pakete zu erstellen, und es ist besser, Ihre Schnittstellen herauszugeben und Programmierer zu bitten, mit ihnen kompatibel zu sein. Sie geben keine Klassen, die Sie Schnittstellen geben. – ddarellis

Verwandte Themen