Du bist nicht angemeldet.

Anderes Das MVC

Patrick

Profi

  • »Patrick« ist der Autor dieses Themas

Beiträge: 694

Danksagungen: 168

  • Private Nachricht senden

1

17.07.2011, 17:34

Das MVC

Dieses Tutorial handelt über das MVC, welches vorallem bei größeren Projekten eine Rolle spielt.

Bei vielen kommt wahrscheinlich jetzt die Frage: „Was ist denn MVC?? :huh:
Die Frage ist nicht ganz unberechtigt, da trotz so großer Wichtigkeit viele diesen Begriff gar nicht kennen, geschweige denn benutzt haben.

Was macht man also wenn man einen Begriff nicht kennt? Man googelt es, oder schaut bei Wikipedia nach.
Wikipedia liefert einem dann folgendes Ergebnis:




Der erste Absatzt erklärt schon einiges:

Zitat von »Wikipedia«

Model View Controller (MVC, deutsch: Modell-Präsentation-Steuerung) ist ein Architekturmuster zur Strukturierung von Software-Entwicklung in die drei Einheiten Datenmodell (engl. model), Präsentation (engl. view) und Programmsteuerung (engl. controller). Ziel des Musters ist ein flexibler Programmentwurf, der eine spätere Änderung oder Erweiterung erleichtert und eine Wiederverwendbarkeit der einzelnen Komponenten ermöglicht. Es ist dann zum Beispiel möglich, eine Anwendung zu schreiben, die das gleiche Modell benutzt, aber einerseits eine Windows- oder Linux-Oberfläche realisiert, andererseits aber auch eine Weboberfläche beinhaltet. Beides basiert auf dem gleichen Modell, nur Controller und View müssen dabei jeweils neu konzipiert werden.



Okay, jetzt wissen wir also schonmal, was das ganze ist und wofür es nützlich ist.
Verdeutlichen soll das ganze diese Grafik hier, die ebenfalls auf der Seite zu finden ist:



Naja, sehr viel schlauer macht einen das ganz nicht, wenn man nicht richtig weiß, was das ganze überhaupt ist..


Unter dem Bild steht ein kleiner Text, vielleicht hilft der einem ja:

Zitat

Model-View-Controller-Konzept. Hinweis: die durchgezogene Linie symbolisiert eine direkte Assoziation, die gestrichelte eine indirekte Assoziation (zum Beispiel über einen Beobachter).



Also, hat der Controller direkten Kontakt zum View und zum Model. Der View wiederum hat direkten Kontakt zum Model und indirekten zum Controller, und das Model widerum hat nur indirekten Kontakt zum View.

Irgendwie verwirrt das ganze einem noch mehr, mit dem direkten Kontakt und indirekten Kontakt. Also schauen wir uns erstmal die Wikipedia Definition vom Model, View und Controller an.



Zitat von »Wikipedia«

Modell (model)

Das Modell enthält die darzustellenden Daten und gegebenenfalls (abhängig von der Implementierung des MVC-Patterns) auch die Geschäftslogik. Es ist von Präsentation und Steuerung unabhängig. Die Bekanntgabe von Änderungen an relevanten Daten im Modell geschieht nach dem Entwurfsmuster „Beobachter“. Das Modell ist das zu beobachtende Subjekt, auch Publisher, also „Veröffentlicher“, genannt.


Präsentation (view)

Die Präsentationsschicht ist für die Darstellung der benötigten Daten aus dem Modell und die Entgegennahme von Benutzerinteraktionen zuständig. Sie kennt sowohl ihre Steuerung als auch das Modell, dessen Daten sie präsentiert, ist aber nicht für die Weiterverarbeitung der vom Benutzer übergebenen Daten zuständig. Im Regelfall wird die Präsentation über Änderungen von Daten im Modell mithilfe des Entwurfsmusters „Beobachter“ unterrichtet und kann daraufhin die aktualisierten Daten abrufen. Die Präsentation verwendet oft das Entwurfsmuster „Kompositum“.


Steuerung (controller)


Die Steuerung verwaltet eine oder mehrere Präsentationen, nimmt von ihnen Benutzeraktionen entgegen, wertet diese aus und agiert entsprechend. Zu jeder Präsentation existiert ein Modell. Es ist nicht die Aufgabe der Steuerung, Daten zu manipulieren. Die Steuerung entscheidet aufgrund der Benutzeraktion in der Präsentation, welche Daten im Modell geändert werden müssen. Sie enthält weiterhin Mechanismen, um die Benutzerinteraktionen der Präsentation einzuschränken. Präsentation und Steuerung verwenden zusammen das Entwurfsmuster „Strategie“, wobei die Steuerung der Strategie entspricht. Die Steuerung kann in manchen Implementierungen ebenfalls zu einem „Beobachter“ des Modells werden, um bei Änderungen der Daten den View direkt zu manipulieren.




Gut, jetzt wissen wir, dass das Model wie eine Art Datenspeicher ist, der Controller die Daten vom Model auf das View transportiert und auch im View eingegebene Daten dem Model zum speichern schickt, und der View sie im Prinzip nur darstellt und die richtigen Aktionen startet, wenn auf Knöpfe gedrückt wird oder Text eingegeben wird.

Jetzt ergeben vielleicht auch die Kontakte auf der Grafik Klarheit.




Ich will euch das ganze jetzt mal etwas klarer machen, indem wir uns mal die Dateien eines gerade ausgedachten Projektes in einer ausgedachten Sprache angucken. Das Projekt ist eine Arzt-Software, die Daten für alle Patienten speichert und übersichtlich darstellt. Die „View.h” habe ich zur Verständlichkeit als Bild ersetzt.


View.h

Spoiler Spoiler




Controller.h

Spoiler Spoiler


C/C++-Quelltext

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
// Controller.h

Importiere "View.h";
Importiere "Model.h";


Klasse Controller {

    // Pointer auf View-Objekte, um daraus den Inhalt u.ä. lesen und manipulieren zu können
    Suchfeld* suchfeldPatienten;
    Tabelle*  tabelle patienten;
    Textfeld* textfeldErkrankungen;
    Textfeld* textfeldImpfungen;
    Textfeld* krankenkasse;
    

    // Pointer auf Patientenliste des Models
    Zeichenkette* Patientenliste[][];


    // View-Funktionen

    // Knöpfe u.ä.
    Funktion pushNeuerPatient();
    Funktion pushLöschePatient();
    Funktion pushSpeicherPatientDaten();
    Funktion pushLöschePatientDaten();
    Funktion suchePatient();


    // Datenbefüllung
    Funktion befüllePatientenliste();
    Funktion befüllePateintenDaten();

    // Um Zugriff auf das Model und den View zu haben
    View* view;
    Model* model;

};




Model.h

Spoiler Spoiler

C/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Model.h

Klasse Model {
    
    Zeinkette patientliste[][];  // Erste Dimension enthält Namen, zweite Dimension enthält die Erkrankungen, Impfungen und die Krankenkasse
    
    Funktion suchePatient(Zeichenkette patientname);
    Funktion erstelleNeuenPatienten(Zeichenkette name, Zeichenkette daten[]);
    Funktion löschePatient(Zeichenkette name);

    Funktion speicherePatientenDaten();
    Funktion lesePatientenDatenAusDatei();

};



Das Beispiel zeigt deutlich, warum die Einteilung sinnvoll ist, denn wäre alles in einer Klasse, wäre diese total überladen und unübersichtlich. Außerdem ist die Wartung viel viel einfacher geworden und die Erweitbarkeit geht ebenfalls schnell und übersichtlich. Ebenfalls kann man jetzt gut das Model wiederverwenden und nur die GUI für verschiedene Systeme neu basteln.

Fazit: Das MVC ist wichtig, sinnvoll und Pflicht in allen größeren Projekten.



Ich hoffe, dass euch dieses mal etwas anderes Tutorial gefallen hat und hoffentlich ihr jetzt wisst, was das MVC ist, wie es funktioniert und wie man es verwendet.



LG Patrick
Ex ungue leonem.

War der Beitrag für dich hilfreich?
Dann drück auf .

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Patrick« (17.07.2011, 17:41) aus folgendem Grund: View.h ersetzt.


Es haben sich bereits 6 registrierte Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

psycho (17.07.2011), Alex (17.07.2011), Christian (10.08.2011), cedi (22.08.2011), JuKu (08.03.2012), Johannes S. (09.09.2012)

Alex

Fortgeschrittener

Beiträge: 372

Registrierungsdatum: 23.06.2011

Wohnort: /home/alex

Danksagungen: 117

  • Private Nachricht senden

2

17.07.2011, 20:32

Ich kannte MVC vorher halbwegs, sogar (mehr oder weniger richtig).

Und ich denke jetzt hab ichs noch besser kapiert, dankeschön!

Das Tut ist echt nützlich ;)
alexthinking.com - yet another computer weblog

Zitat

Chuck Norris knows the state of schroedinger's cat.

Patrick

Profi

  • »Patrick« ist der Autor dieses Themas

Beiträge: 694

Danksagungen: 168

  • Private Nachricht senden

3

17.07.2011, 21:48

Schön, dass es dir gefällt :)
Hab mir auch viel Mühe gegeben :D
// Und lange dran gesessen ;)

Bitteschön :)
Ex ungue leonem.

War der Beitrag für dich hilfreich?
Dann drück auf .

Simon

Profi

Beiträge: 725

Registrierungsdatum: 14.06.2011

Danksagungen: 210

  • Private Nachricht senden

4

17.07.2011, 22:20

Von mir auch ein danke, ich kannte MVC zwar schon, aber eine solch ausführliche Erklärung ist echt gut :)

Alex

Fortgeschrittener

Beiträge: 372

Registrierungsdatum: 23.06.2011

Wohnort: /home/alex

Danksagungen: 117

  • Private Nachricht senden

5

22.08.2011, 14:26

Ich bin gerade bei der Planung einer PHP-Anwendung mit MVC, und habe noch eine Frage zur Struktur..

Ich abstrahier das jetzt einfach mal zu nem Beispiel :)

Ich habe 3 verschiedene Models: PollModel, ArticleModel, FoobarModel. Jedes davon benötigt eine besondere Darstellung (von der das Model selber aber natürlich nichts weiß, ->Trennung vom View)..

dann möchte ich 2 Views anbieten, nämlich HtmlView und PdfView..

Die Frage ist jetzt wie ich das so weit umsetzen soll? Weil wenn der Umgang mit dem Model-Objekten innerhalb der Views geregelt ist, müsste ich die Klassen ja jedesmal ergänzen, wenn ein neues Model dazu kommt..

Meine Idee war jetzt entsprechend meinem Bedürfnis Kindklassen anzulegen, also z. B. PollHtmlView oder ArticlePdfView, die dann halt erben und die konkrete Umsetzung selber festlegen, aber ich weiß nicht ob das wirklich das wahre ist. Als Alternative wäre mir jetzt das Strategy-Pattern eingefallen..

Wie würdet ihr das lösen??
alexthinking.com - yet another computer weblog

Zitat

Chuck Norris knows the state of schroedinger's cat.

Simon

Profi

Beiträge: 725

Registrierungsdatum: 14.06.2011

Danksagungen: 210

  • Private Nachricht senden

6

22.08.2011, 16:17

Ob es unbedingt ViewKlassen sein müssen, ist die Frage.

Templates ist in diesem Zusammenhang immer ein gutes Stichwort.
(Hier mit meine ich aber keine Templateengines ala Smarty, PHP selber reicht hier voll aus ;))

In diesen Templates kannst du dann den HTML Teil mit Variablen platzieren (Und foreach, for, oder was du auch brauchst ;) )

Nun kommt der Controller ins Spiel.

Beim Seitenaufruf bestimmt dieser, welche View geladen werden soll.
(Beispiel: $this->tpl->add($templatename); ) oder man macht es so, das es pro Controller ein View gibt.
Dann könnte z.B. der Frontcontroller bereits sagen, welches Template geladen werden soll.

Aber wie du das genau umsetzt, bleibt dir überlassen.

Für den PDF Teil bieten sich auch Templates an.
Wie du diese umsetzt, ist auch dir überlassen. So kann man zum Beispiel auch mit einigen bekannten Klassen HTML -> PDF machen, dann könntest du die Views fast komplett übernehmen ;)

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Alex (22.08.2011)

Alex

Fortgeschrittener

Beiträge: 372

Registrierungsdatum: 23.06.2011

Wohnort: /home/alex

Danksagungen: 117

  • Private Nachricht senden

7

22.08.2011, 16:42

So wie du das meinst, wäre dann ja im Endeffekt quasi $controller->tpl die ViewKlasse, oder?

Nur dann muss der Inhalt der Template-Variablen ja wieder spezifisch generiert werden, weil ja dann z. B. ein RSS-View wieder ganz andere Tags bräuchte (das mit PDF sollte nur ein Beispiel sein)..


also irgendwie bin ich gerade ein bisschen verwirrt :)
alexthinking.com - yet another computer weblog

Zitat

Chuck Norris knows the state of schroedinger's cat.

Simon

Profi

Beiträge: 725

Registrierungsdatum: 14.06.2011

Danksagungen: 210

  • Private Nachricht senden

8

22.08.2011, 16:48

Also ich meine es so, dass es eine HTML Template Klasse gibt. Diese wird dann mit Templatedateien und den benötigten Daten gefüttert.

Dann gibt es meinet wegen noch RSS Template Klasse und PDF Template klassen. (Wobei sich RSS und HTML Templateklassen nur in den Templates unterscheiden.)

Dann bekommt die Templateklasse entweder eine Instanz vom Model oder die benötigten Daten aus dem Model übergeben. Dann muss die Templateklasse nur noch die Templatedatei ausführen und ihr hier für die Daten bereitstellen (Das Model bereitstellen)

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Alex (22.08.2011)

Alex

Fortgeschrittener

Beiträge: 372

Registrierungsdatum: 23.06.2011

Wohnort: /home/alex

Danksagungen: 117

  • Private Nachricht senden

9

22.08.2011, 17:17

Ah oke..

Aber sagen wir ich hab folgende Models

Spoiler Spoiler


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
class PollModel {
  private frage, antwortmoeglichkeiten[];

  function loadPoll();
  //verschiedene Getter
}

class ArticleModel {
  private title, inhalt, autor;
  
  function loadArticle();
  //wieder verschiedene getter
}

(is nur n hässliger Pseudocode, aber ich denke ist klar was gemeint ist)


dann bräuchte ich ja verschiedene Templates, z. B.

Spoiler Spoiler


für Polls:

PHP-Quelltext

1
2
3
4
<html>
<head><title><?php echo $poll->getFrage(); ?></title></head>
<body><!-- usw --></body>
</html>


und für Artikel:

PHP-Quelltext

1
2
3
4
<html>
<head><title><?php echo $article->getTitle(); ?></title></head>
<body><!-- usw --></body>
</html>



oder hab ich da immer noch was falsch verstanden?
alexthinking.com - yet another computer weblog

Zitat

Chuck Norris knows the state of schroedinger's cat.

Simon

Profi

Beiträge: 725

Registrierungsdatum: 14.06.2011

Danksagungen: 210

  • Private Nachricht senden

10

22.08.2011, 18:34

Jop, genau so meinte ich das ;)

Alex

Fortgeschrittener

Beiträge: 372

Registrierungsdatum: 23.06.2011

Wohnort: /home/alex

Danksagungen: 117

  • Private Nachricht senden

11

22.08.2011, 18:47

Okey danke ;)
alexthinking.com - yet another computer weblog

Zitat

Chuck Norris knows the state of schroedinger's cat.

cedi

Profi

Beiträge: 702

Danksagungen: 78

  • Private Nachricht senden

12

22.08.2011, 20:14

hey super gemacht Pat :)
Mir wurde das MVC mal eingeprügelt :D Ein bekannter hat es mir so reingeprügelt, dass ich seitdem versuche so viel und so gut wie möglich nach MVC zu Programmieren.
Die GUI ist bei mir deshalb immer eine eigene Klasse, die nur die GUI beherbergt. Ansonsten war die GUI immer ein wildes durcheinander. :D

aber echt gutes Tut :)
Hilft sicher vielen hier.

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Patrick (08.06.2012)

Alex

Fortgeschrittener

Beiträge: 372

Registrierungsdatum: 23.06.2011

Wohnort: /home/alex

Danksagungen: 117

  • Private Nachricht senden

13

23.08.2011, 01:41

Spricht eigentlich was dagegen, dass das Model in der Lage ist, z. B. xml-artigen Output zu erzeugen?

So mach ich das jetzt nämlich weil das noch eine relativ elegante und auf jeden Fall performantere Lösung zulässt :)
alexthinking.com - yet another computer weblog

Zitat

Chuck Norris knows the state of schroedinger's cat.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Alex« (23.08.2011, 06:12)


cedi

Profi

Beiträge: 702

Danksagungen: 78

  • Private Nachricht senden

14

23.08.2011, 11:33

wie meinst du das mit xml artigen Output?

Alex

Fortgeschrittener

Beiträge: 372

Registrierungsdatum: 23.06.2011

Wohnort: /home/alex

Danksagungen: 117

  • Private Nachricht senden

15

23.08.2011, 13:04

Dass die Models nicht wie im Bsp. oben über das Template ausgegeben werden, sondern dass jedes Model eine Funktion wie getXml() hat..

PHP-Quelltext

1
2
3
4
5
$article->addTitle("Beispielblogeintrag");
$article->addContent($laengerer_inhalt);
$article->addAuthor("ich");

echo $article->getXml();


Output:

Quellcode

1
2
3
4
5
<blogeintrag>
 <title>Beispielblogeintrag</title>
 <content><!-- Inhalt von $laengerer_inhalt --></content>
 <author>ich</author>
</blogeintrag>
alexthinking.com - yet another computer weblog

Zitat

Chuck Norris knows the state of schroedinger's cat.

cedi

Profi

Beiträge: 702

Danksagungen: 78

  • Private Nachricht senden

16

23.08.2011, 13:05

achsoo :D
ok. verstanden

Simon

Profi

Beiträge: 725

Registrierungsdatum: 14.06.2011

Danksagungen: 210

  • Private Nachricht senden

17

23.08.2011, 21:19

Rein theoretisch spricht eigentlich nichts dagegen.

Solange damit nur Inhalte des Models übertragen werden, ist es ja nur ein andere Weg, die Daten zu übertragen.