Noch mehr Java gibts auf www.javahochzwei.de

Model View Controller (MVC) Entwurfsmuster

Das Model-View-Controler-Entwurfsmuster (kurz MVC Design Pattern) zählt für mich zu den wichtigsten seiner Art, daher werde ich ihm auch meinen ersten fachlichen Artikel widmen.

Sinn und Zweck
Wikipedia schreibt: „Ziel des Musters ist ein flexibler Programmentwurf, der eine spätere Änderung oder Erweiterung erleichtert und eine Wiederverwendbarkeit der einzelnen Komponenten ermöglicht.“

Fakt ist, das in diesem Muster ein Program in drei verschiedene Komponenten aufgeteilt wird, die von ihrer Art her verschieden sind und somit eine Aufteilung ermöglichen: Model, View und Controler.

Die einzelnen Rollen der Komponenten

  • Model: Das Model repräsentiert die grundlegenden Daten des Programms, es ist gänzlich losgelöst von deren Darstellung und auch deren Programmlogik.
  • View: Der View hat eine recht simple Aufgabe. Er ist dafür verantwortlich das Model darzustellen.
  • Controller: Der Controller ist das Zwischenstück der vorigen Komponenten. Er empfängt auf der einen Seite die Benutzereingaben, die ihm durch den View übermittelt werden und ändert auf der anderen Seite auf Basis derer die Daten im Model.

MVC in Java
Bei der Implementierung eines MVC-Entwurfsmusters wird man glücklicherweise von Java nicht allein gelassen:

  • Interface java.util.Observer (Java API): Das Interface Observer (dt. Beobachter) wird typischerweise vom View (den Views) implementiert. Sie beobachten quasi das Geschehen und werden automatisch über die Methode „void update(Observable o, Object arg)“, die in Observer implementiert werden muss, geupdatet.
  • java.util.Observable (Java API):  Auslöser einer solchen Änderung ist typischerweise das Model, das Observable (dt. beobachtbar) erweitert. Ruft man hieraus erst die Methode „protected void setChanged()“ (die so viel sagt wie „ich Observable wurde verändert“) und dann die Methode „void notifyObservers()“ bzw. „void notifyObservers(Object arg)“ auf, werden alle Observer, die man vorher mit „void addObserver(Observer o)“ beim jew. Observable angemeldet hat unterrichtet. Es wird dann automatisch die update-Methode aufgerufen und der Observer (z.B. ein View) erneuert sich dann.

Das ganze Spiel wollen wir uns nunmal an einem konkreten Besipiel anschauen:

View:

package mvc;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.JButton;

/**
 * @author Armin
 * @since 12.09.2012
 * 
 * info@prog-blog.de
 * www.prog-blog.de
 */
public class View extends JFrame implements Observer {

	private JPanel contentPane;
	private JTextField textField;

	private Controler controler;

	public View(Controler controler) {
		this.controler = controler;

		initComponents();
	}

	private void initComponents() {

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 255, 111);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		textField = new JTextField();
		textField.setBounds(10, 11, 219, 20);
		textField.setEditable(false);
		contentPane.add(textField);
		textField.setColumns(10);

		JButton btnNewButton = new JButton("N\u00E4chste Ausgabe");
		btnNewButton.setBounds(10, 42, 219, 23);
		btnNewButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				controler.buttonWurdeGedrückt();
			}
		});
		contentPane.add(btnNewButton);

		setVisible(true);
	}

	@Override
	public void update(Observable obs, Object obj) {

		textField.setText(((Model)obj).getActualAusgabe());
	}
}

 

Model:

package mvc;

import java.util.Observable;

/**
 * @author Armin
 * @since 12.09.2012
 * 
 * info@prog-blog.de
 * www.prog-blog.de
 */
public class Model extends Observable {

	private final String[] AUSGABE = { "", "www.", "prog", "-", "blog", ".de",
			"www.prog-blog.de", "", "www.prog-blog.de" };
	private int counter;

	public Model() {
		// setzt den counter auf 0
		counter = 0;
	}

	/**
	 * diese Methode wird vom Controler aufgerufen,
	 * um das Model zu ändern
	 */
	public void incrAusgabe() {

		// ist der counter noch nicht am Ende des Arrays AUSGABE
		// setzte ihn um 1 hoch, sonst wieder an den Anfang
		if (counter < 8) {
			counter++;
		} else {
			counter = 0;
		}

		// "ich wurde verändert!"
		setChanged();
		// sag allen angemeldeten Beobachtern bescheid
		notifyObservers(this);
	}

	/**
	 * die Methode wird von den Beobachtern aufgerufen,
	 * um den neusten Stand des Models zu erfragen
	 */
	public String getActualAusgabe() {
		return AUSGABE[counter];
	}
}

 

Controler:

package mvc;

/**
 * @author Armin
 * @since 12.09.2012
 * 
 * info@prog-blog.de
 * www.prog-blog.de
 */
public class Controler {

	private View view;
	private Model model;

	public Controler() {
		view = new View(this);
		model = new Model();

		// meldet den View als Beobachter des Models an
		model.addObserver(view);
	}

	/**
	 * wird vom ActionListener im View ausgeführt
	 */
	public void buttonWurdeGedrückt() {
		model.incrAusgabe();
	}

	public static void main(String[] args) {	
		new Controler();
	}
}

 

Die Ausgabe des kleinen Programms sieht so aus:

Durch Drücken des Buttons wird nach und nach die einzelnen Elemente des Arrays AUSGABE des Models ausgegeben.

Download Sourcecode:

  MVC.rar (1,8 KiB, 76 hits)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.