dedlfix: OOP Konflikt

Beitrag lesen

echo $begrüßung;

Also die einzelnen Klassen zu unterteilen in M, V und C ist mit denk ich verständlich geworden.
Wie ich aber das ganze jetzt Modul-/Klassenübergreifend machen kann ist mir nicht klar.

Fehler zu machen, wenn man das erste Mal mit einer Technik in Berührung kommt, ist ganz natürlich. Aus deinen Ausführungen entnehme ich aber, dass dir noch grundlegende Implementierungsdetails unbekannt sind. Ein Controller entscheidet nicht, was auszuführen ist, sondern kümmert sich nur um das Wie. Die Was-Entscheidung obliegt dem Router. Der ermittelt, welche Action eines Controllers aufzurufen ist. Ein Controller kann mehrere Aufgaben eines Themengebiets bündeln. Die Abarbeitung dieser Teilaufgaben obliegt den Actions, was nichts anderes als öffentliche Methoden des Controllers sind. Nichtöffentliche Methoden können Hilfsfunktionen für eine oder mehrere Actions ausführen. Der Routing-Prozess ist Teil des Front Controllers. Der Front Controller ist aber kein direkter Bestandteil des MVC-Patterns, auch wenn er das Wort Controller im Namen führt. Das MVC-Pattern wird jedoch gern mit einen Front Controller verbunden, denn irgendwer muss ja die Actions der MVC-Controller aufrufen.

Eine einzelne Klasse würde ich jetzt so aufbauen.
Ordnerstruktur:

Board
Board -> boardController.php
Board -> Model -> boardModel.php
Board -> View -> boardView.php

Ich sehe hier wieder die 1:1:1-Zuordnung. Vermutlich wird das Board aber mehrere Arten der Darstellung haben. Anzeige der Themenbereiche, Anzeige der Überschriften der Beiträge eines Themas, Anzeige eines Beitrags inklusive Antworten, Formular für einen neuen Beitrags, Formular für eine Antwort. Die beiden Formular-Ansichten unterscheiden sich vermutlich nur geringfügig, weswegen man sie sicher in einer View unterbringen kann. Alle anderen sind aber besser in jeweils einer eigenen View aufgehoben, sonst hat man eine schlecht wartbare Riesenview.

Die Verzeichnisstruktur wüede ich andersrum aufbauen (was auch üblicher ist). Alle (MVC-)Controller (den Front Controller also nicht) in ein Controllers-Verzeichnis, alle Models in ein Models-Verzeichnis und die Views ebenso. Innerhalb des Views-Verzeichnisses kann man ja dann die Board-spezifischen Views in ein Unter-Verzeichnis einsortieren.

Auch das Model kann man verschieden gestalten. Zum einen könnte es ein Model pro Tabelle im DBMS geben. Für das Board braucht es dann mehrere Models, beispielsweise eins für die Themen und eins für die Beiträge. Zum anderen kann man auch nur ein Model für das Board erstellen und über eine Methode die Themen anfordern, über eine andere die Beiträge. Wo das Model die Daten herholt ist dem Controller egal, oder besser: das muss dem Controller egal sein. Je weniger er über die Interna des Models Bescheid weiß, desto besser lassen sich diese bei Bedarf ändern, ohne dass das einen Änderungsaufwand an anderen Stellen des Gesamtkunstwerkes nach sich zieht.

model.php:

Soweit so gut.

boardController.php

Der aber nicht mehr.

class boardController{

const A_FROM_DATE = 1;

public function __construct(array $params){

$model = new boardModel();

if($params['whatToDo']==A_FROM_DATE){
      $this->viewBoard($model->getArticlesFromDate($params['condition']), "articles");
    }
  }

Der Controller erfüllt mehrere Aufgaben rund um das Board. Diese kommen jede in eine eigene Action. Wenn alle das Model brauchen, so kann man es durchaus im Constructor initialisieren und in einer Objektvariable ablegen. Die konkrete Datenabfrage muss aber die jeweilige Action selbst machen, denn jede braucht ja unterschiedliche Daten.

// Verwaltet die Anzeige
  public function viewBoard($articles='',$what=''){
    $view = new boardView($articles);

$view->showBoardHeader();

$numberOfArticles=count($articles);
    foreach($articles as $s){
      $view -> toDo($what);
    }

$view->showBoardFooter();
  }
}

Des Controllers Aufgabe ist eigentlich auch nicht, die Ausgabe zusammenzustellen. Er soll lediglich die passenden (Roh-)Daten an die View liefern, die sich um den Rest kümmert. Dazu gehört auch das Iterieren über die Datenmenge. Das wird zweifellos und sinnvollerweise für die Ausgabe benötigt, aber letztlich liegt das in der Hand der View, ob sie das macht und wenn ja, wie sie das tut, denn nur sie weiß, wie die Daten für die Ausgabe am besten zu durchlaufen sind.

boardView.php

Die kommentiere ich nicht extra, denn in meinen obigen Ausführungen stehen (so hoffe ich) genug Hinweise dazu. Nur so viel: Vergiss nicht die kontextgerechte Behandlung der Ausgabewerte (Stichwort: htmlspecialchars()). Auch das ist Aufgabe der View.

oder sollte das alles eher so aussehen:

Ah ja, hier hast du es ja in der üblichen Strukturierweise angeordnet. Besser so, zuzüglich der obigen Anmerkungen.

Bei einem Request für den Newsletter würde folgendes passieren:
Der in der index.php inkludierte FrontController würde den NewsletterController aufrufen welcher die Anfrage an das NewsletterModel weiterleitet, und die Daten danach an NewsletterView übergibt. Die Ausgabe würde der Front Controller an View.php weitergeben welche ebenfalls in der index.php inkludiert ist.

Wenn View.php die grundsätzliche Struktur der Webseiten enthält und der NewsletterController (oder besser: eine seiner Views) nur noch den einzufügenden HTML-Teil liefert, dann ist das eine mögliche Herangehensweise.

Ich hab mir das ZendFramework angeguck tund auch runtergeladen aber leider ist mir aus der Ordnerstruktur kein M, V, C nachvollziehbar. Sagen wir so - zu kompliziert und es heißt halt nicht Model, View, Controller.

Der zweite Code-Sample-Kasten von Create Your Project aus dem Quickstart zeigt eine der möglichen Verzeichnisstrukturen. Das Verzeichnis tests ist erstmal uninteressant, in library stehen die Dateien des Zend Framworks und weiterer allgemeiner Bibliotheken, die keinen spezifischen Bezug zu deiner Anwendung haben. Das Verzeichnis public ist das DocumentRoot des Webservers. Wenn man http://domain.example.com/ aufruft, muss man dorthin kommen. Die anderen Verzeichnisse liegen alle neben dem DocumentRoot und sind somit nicht direkt per HTTP-Request erreichbar. Als weiterer Inhalt des public-Verzeichnisses kommen statische Ressourcen wie CSS-Dateien und Bilder in Frage. In der public/index.php residiert nur wenig Code, der den Aufruf des Bootstraps vorbereitet und erledigt.

Das wichtigste Verzeichnis ist application, da findest du neben Bootstrap und einem Verzeichnis für Konfigurationsdaten die Verzeichnisse für Controller, Models und Views. Da Index- und ErrorController recht einfach sind, gibt es für die beiden auch nur jeweils eine View, ansonsten lägen in index und error (passend jeweils zum Namen des Controllers) mehr Dateien. Es gibt auch noch ein Verzeichnis helpers, in dem für die Ausgabe benötigte Hilfsfunktionen abgelegt werden können. Eine Datenmenge zum Beispiel als Liste darzustellen, muss man nicht in jeder View <ul><li>... inklusive Schleife notieren, man übergibt besser die Daten einer Helper-Funktion, die die Listendarstellung erzeugt.

Das Models-Verzeichnis ist leer. Das muss so sein. Es gibt auch keine Basisklasse für Models im Zend Framework. Die Aufgaben eines Models sind stark von der Geschäftslogik der Anwendung abhängig und zu individuell, um eine für viele Zwecke verwendbare gemeinsame Grundlage zu erstellen. Ein einfaches Model besteht aus einer Klasse mit einer Methode, die (etwas untertrieben) vielleicht zwei Zahlen zusammenrechnet. Es gibt aber sehr wohl Hilfsmittel für die Models, beispielsweise Klassen, die sich mit Datenbankzugriff oder Webservices beschäftigen. Auf diese Hilfsmittel kann ein Model zugreifen, um seine Aufgabe zu erledigen.

echo "$verabschiedung $name";