Viele Anwendungen lassen sich mit dem MVC Design Pattern besser programmieren und wartbar halten. Mit Hilfe des MVC Programm Designs kann man schneller und effektiver programmieren.
Zum Einstieg gibt es hier ein kleines Programmbeispiel (mit GUI), in dem man gut nachvollziehen kann, wie manin Java MVC programmiert.
Jeder der Software schon mal geschrieben hat, kennt bestimmt das Problem vom unsauberen Code. Man kann nicht einfach schnell eine Funktion seinem Programm hinzufügen, sondern muss an sehr vielen Stellen im Programmcode arbeiten. Da durch kommt es oft zu Problemen mit anderen Methoden (Funktionen), so dass man meistens sehr viel Zeit für eine Programmänderung benötigt.
An dieser Stelle erleichtert das Java MVC Prinzip die Programmierung und eventuelle Änderungen im Source Code (Programmcode).
Der Controller bildet ein Objekt (Referenz) von dem Model und der View. Die View bekommt eine Referenz von dem Controller. So bald wie eine Action auf der View ausgelöst wird, gibt diese eine Meldung an den Controller weiter. Der Controller ändert über einen Setter oder Methode (Funktion) das Model. Wenn sich das Model ändert gibt es eine Meldung weiter, so dass die View das Model abfragt und die View sich aktualisiert.
Das MVC Prinzip (MVC Pattern) soll durch die obere Grafik besser erklärt werden. In jeder Programmiersprache muss das MVC Design anders umgesetzt werden.
Java MVC
Seit der Version 1.1 bietet Java das Model View Controller Prinzip (Java MVC Pattern) an. Dies wird technisch durch die Nutzung von Observer und Observable umgesetzt.
Sun hat bei der Umsetzung des MVC Prinzips jedoch seinen eigenen Weg gewählt. Der Controller hat jeweils eine Referenz vom Model und der View.
Beim Starten erstellt man eine Referenz von seinem Controller, welcher wiederum das Model und die View initialisiert. Jede einzelne View kann so ihren eigenen MVC Controller haben.
MEIN BEISPIEL
Zur besseren Erklärung des Java MVC Prinzipes habes ich ein kleines Programm geschrieben, welches per Button-Klick immer nur die Farbe ändert und als Button-Text die aktuellen Farbwerte ausgibt, weiterhin kann man Zahlen hoch- und runterzählen.
MEINE MODELLE
DAS MODEL FÜR DAS ZÄHLEN DER ZAHLEN
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package mod_dec_inc; import java.util.Observable; public class DecInc extends Observable { private int zahl = 0; public void dec(){ this.zahl = zahl - 1; this.setChanged(); this.notifyObservers(this); } public void inc(){ this.zahl = zahl + 1; this.setChanged(); this.notifyObservers(this); } // getter and setter /** * @return the zahl */ public int getZahl() { return zahl; } /** * @param zahl the zahl to set */ public void setZahl(int zahl) { this.zahl = zahl; } } |
DAS MODEL FÜR DIE ZUFALLSFARBE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package ModelViewController; import java.awt.Color; import java.util.Observable; import java.util.Random; public class Model extends Observable { // init private Color color = new Color(255, 255, 255); // methods public void randomColor(){ // Hier erzeuge ich mir einen Zufallsgenerator. Random random = new Random(); // per Zufallsgenerator erzeuge ich mir die einzelnen Farben (RGB) int color1 = random.nextInt(254); int color2 = random.nextInt(254); int color3 = random.nextInt(254); // ich erzeuge ein neues Farbobjekt this.setColor(new Color(color1, color2, color3)); // hier informiere ich meine Observer setChanged(); notifyObservers(this); } // getter and setter /** * @return the color */ public Color getColor() { return color; } /** * @param color the color to set */ public void setColor(Color color) { this.color = color; } } |
In den Modellen werden die Grundfunktionen von einem Programm definiert. Im ersten Model wird ein Zahl (Integer) hoch und runter gezählt. Dazu werden die Methoden dec() -> Decrement und inc() -> Increment aufgerufen, diese werden durch den Controller angesteuert. Als Controller kann auch die Main-Methode mit einer Kommandozeilen Eingabe funktionieren. An dieser Stelle macht sich die Verwendung des MVC Prinzps bemerkbar, Man kann einfach zu seinem Programm Funktionen hinzufügen ohne, das die Änderung anderen Programmcode beeinflusst. An dieser Stelle sollte man jedoch Acht geben, da Man diese Aussage nicht Pauschalisieren sollte.
Die Modelle werden von den View observiert und greifen auf die Klasse Observable als Object zu.
DER CONTROLLER
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package ModelViewController; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mod_dec_inc.DecInc; public class Controller implements ActionListener { // Initialisierung des Models private Model model = new Model(); private DecInc decInc = new DecInc(); // Initialisierung der View, mit Übergabe des Controllers (dieser Klasse). private View view = new View(this); public Controller(){ view.setVisible(true); model.addObserver(view); decInc.addObserver(view); } /** * An dieser Stelle kommen die Events aus der View an. * Diese werden mit Hilfe von Actioncommands übergeben. */ @Override public void actionPerformed(ActionEvent e) { if(e.getActionCommand() != null) System.out.println("ActionCommand: " + e.getActionCommand()); if(e.getActionCommand().equals("neueFarbe")) model.randomColor(); if(e.getActionCommand().equalsIgnoreCase("plus")) decInc.inc(); if(e.getActionCommand().equalsIgnoreCase("minus")) decInc.dec(); } } |
Der Controller hat Referenzen (Objekte) auf die beiden Modelle und die View. So bald wie in der View ein Aktion (Klick, Doppelklick etc. ) ausgelöst. Dies wird hier durch sogenannte ActionCommands übernommen und verarbeitet. Diese lösen nach einen ActionCommand (gewähltes nach einem String) eine Methode (Funktion) von den Modellen aus.
DIE VIEW
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
package ModelViewController; import java.util.Observable; import java.util.Observer; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SpringLayout; import javax.swing.JPanel; import java.awt.FlowLayout; import javax.swing.JLabel; import mod_dec_inc.DecInc; public class View extends JFrame implements Observer { private static final long serialVersionUID = 1L; private SpringLayout springLayout = new SpringLayout(); private JButton btnNeueHintergrundfarbe = new JButton("neue Hintergrundfarbe"); private JButton btnNewButton = new JButton("dec"); private JLabel label = new JLabel("0"); private JButton btnInc = new JButton("inc"); /** * Create the frame. * @param controller */ public View(Controller controller) { setLocationByPlatform(true); setVisible(true); setTitle("ModelViewController"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 251, 200); getContentPane().setLayout(springLayout); springLayout.putConstraint(SpringLayout.NORTH, btnNeueHintergrundfarbe, 10, SpringLayout.NORTH, getContentPane()); springLayout.putConstraint(SpringLayout.WEST, btnNeueHintergrundfarbe, 10, SpringLayout.WEST, getContentPane()); springLayout.putConstraint(SpringLayout.SOUTH, btnNeueHintergrundfarbe, 51, SpringLayout.NORTH, getContentPane()); getContentPane().add(btnNeueHintergrundfarbe); btnNeueHintergrundfarbe.setActionCommand("neueFarbe"); JPanel panel = new JPanel(); springLayout.putConstraint(SpringLayout.NORTH, panel, 6, SpringLayout.SOUTH, btnNeueHintergrundfarbe); springLayout.putConstraint(SpringLayout.WEST, panel, 10, SpringLayout.WEST, getContentPane()); springLayout.putConstraint(SpringLayout.SOUTH, panel, -10, SpringLayout.SOUTH, getContentPane()); springLayout.putConstraint(SpringLayout.EAST, panel, -10, SpringLayout.EAST, getContentPane()); springLayout.putConstraint(SpringLayout.EAST, btnNeueHintergrundfarbe, 0, SpringLayout.EAST, panel); getContentPane().add(panel); panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5)); btnNewButton.setActionCommand("minus"); btnNewButton.addActionListener(controller); panel.add(btnNewButton); panel.add(label); btnInc.setActionCommand("plus"); btnInc.addActionListener(controller); panel.add(btnInc); btnNeueHintergrundfarbe.addActionListener(controller); } @Override public void update(Observable o, Object arg) { if(arg instanceof Model){ btnNeueHintergrundfarbe.setBackground(((Model) arg).getColor()); btnNeueHintergrundfarbe.setText(((Model) arg).getColor().toString()); } if(arg instanceof DecInc){ this.label.setText(Integer.toString(((DecInc) arg).getZahl())); } } } |
Ein weiteres Beispiel zur Model-View-Controller-Programmierung kann man in folgendem Artikel -> Kleines MVC Beispiel (Java) finden. Einen anderen tollen Artikel zu Java MVC könnt ihr hier finden – Blog von BigBasti