| 

.NET C# Java Javascript Exception

3
Hallo,

ich arbeite an meinem MVC PHP Framework. Nun wollte ich wissen ob ich die Entität jeweils im Model definieren oder aber eine eigene Klasse erstellen soll?

Als Beispiel, soll ich es so machen:
class User_Model extends Model {
private $name;
public getName() {}
public setName($var) {}
public getAllUsers() {}
public getUser() {}
public saveUser(User_Model $user) {}
}


oder so:
class User_Model extends Model {
public getAllUsers() {}
public getUser() {}
public saveUser(Entity $user) {}
}

class User extends Entity {
private $name;
public getName() {}
public setName($var) {}
}


Mir schwebt die zweite Variante vor, da ich die Logik um die Daten zu Verarbeiten im Model von meinen Businessobjekten resp. Entitäten separiert habe. Ist die zweite Variante überhaupt noch MVC-konform? Was meint ihr? Wäre froh um Support von euch Cracks... :)

Gruss
News:
01.05.2013
rjgamer 31 3
4 Antworten
0
*nicht-crack sagt*: Also ich bin ein großer freund vom Active Record Pattern und danach würde dein Beispielcode etwa so aussehen:

class Model {
public static function getAll() {}
public static function find(id) {}
public save() {}
}

class User_Model extends Model {
private $name;
public function getName() {}
public function setName($var) {}
public function someBusinessLogicMethod() {}
}


Noch schöner wäre es natürlich, wenn die getter und setter dynamisch erzeugt werden würden...

Irgendwie musst du dazu noch das Mapping von Model-Name auf Tabelle lösen, falls du (wovon ich ausgehe) deine Model-Objekte in einer Datenbank speichern willst. Dafür könnte die get_called_class() hilfreich sein...

So wie ich MVC interpretiere, macht es keine Aussage dazu wie Entitäten verwaltet werden sollen, sondern nur, dass eben die Daten, die Eingaben und die Darstellung separiert werden müssen. Also wären, meiner Meinung nach, beide Ansätze (und vielleicht noch ein paar mehr) MVC-Konform.
02.05.2013
phg 1,6k 3
0
Danke für deine Antwort. Ich wollte eigentlich diesen Ansatz angehen. Leider bin ich aber nicht der Freund von statischen Methoden (it's evil).

Wäre es möglich die getAll und find Methoden in einem Repository auszuführen? Als Beispiel:
class User_Model extends Model {
private $name;
private $repository;
public function __construct($data = array(), $repository) {}
public function getName() {}
public function setName($var) {}
public function someBusinessLogicMethod() {}
public function save() {}
}

class User_Repository extends Repository {
public function __construct($db) {}
public function getAll() {}
public function getOneById($id) {}
public function save(User_Model $user) {}
}

// User repository erstellen
$db = $this->framework->getDatabase();
$user_repo = new User_Repository($db);

// User auslesen, bearbeiten und speichern
$user = $user_rep->getOneById(1337);
$user->setName('Alfred');
$user->save();

// Neuen User erstellen und speichern
$user2 = new User_Model(array('name' => 'Jimmy'), $user_repo);
$user2->save();


Das Model definiert das Businessobjekt und ist nicht mehr die direkte Schnittstelle zur Datenbankschicht. Dazwischen gibt es nun das Repository. Verletze ich mit diesem Ansatz das MVC Pattern? Eigentlich sollte es ja dann PMVC heissen, oder nicht? :)

Gruss
02.05.2013
rjgamer 31 3
Das MVC macht keine Aussage woher die Daten im Model kommen sondern nur, dass die Daten (und ggf. die BL) im Model sind. Für die Datenhaltung musst du dir ein anderes Pattern suchen oder selbst was überlegen ;)
Was mich persönlich an obigem Ansatz stört ist, dass für Laden und Speichern zwei verschiedene Objekte zuständig sind. Sauberer fände ich es nur Daten und BL im Model zu halten und alles DB-Spezifische über Repository-Klassen zu machen.
Das hätte noch den Vorteil, dass die selbe Model-Klasse auch mit anderen Datenquellen (z.B. Webservice) ohne Anpassung verwendet werden kann.
phg 02.05.2013
Hi,

geb dir vollkommen Recht. Hab unten mal ein Beispiel geschrieben wie aktuell mein Framework funktioniert. Und zwar wird das Model eig. als Repository missbraucht.
rjgamer 03.05.2013
0
Aktuell sieht meine MVC Framework wie folgt aus:

Entity
class Entity {
public function get($name) {}
public function set($name, $value) {}
public function has($name) {}
}


Model
class User_Model extends Model {

// Returns entity
public function getOne($id) {
$sql = 'SELECT * FROM user WHERE user_id = :id';
return $this->db->prepare($sql)
->bindValue(':id', intval($id), Type::INTEGER)
->fetchOne();
}

public function save(Entity $user) {}
}


Controller
class User_Controller extends Controller
// Create user model
$user_model = new User_Model($this->fw->getDatabase());

// Get entity
$user = $user_model->getOne();
$user->set('name', 'Michael');

// Save entity
$user_model->save($user);
}


Die Daten werden als Objekt der generischen Entity Klasse erzeugt (über einen PDO Wrapper) und dann im Controller verändert etc. Funktioniert eigentlich alles perfekt. Nur wird aus meiner Sicht das Model jeweils als Repository misbraucht. Korrekt oder falsch?
03.05.2013
rjgamer 31 3
Ich glaube dein Code-Beispiel ist etwas zu kurz...

So wie ich den Code verstehe, ist deine Klasse User_Model das Repository und die Rückgabe des Datenbank-Wrappers bzw. eine Instanz der Entity-Klasse das eigentliche Model. Das Model soll ja die Daten enthalten, aber in deinem Beispiel ist im User_Model nur Code zum Laden/Speichern zu sehen und die Daten sind in der Entity-Instanz...

Mich persönlich würde noch stören, dass ich jedem Konstruktor eine Instanz vom Framework bzw. der Datenbank mitgeben muss. Das würde ich durch Singelton und/oder Factory umgehen... Denk mal drüber nach ;)
phg 04.05.2013
Hi,

ja, deine Erklärung ist genau richtig. Die Framework Klasse ist eine Factory aber halt kein Singelton. Singelton und statische Methoden will ich vermeiden.

Dann hab ich also die Models als Repository missbraucht?
rjgamer 04.05.2013
Ehm nicht missbraucht, eher falsch benannt.
Wenn du User_Model in User_Repository umbenennst (und Model in Repository) und Entity in Model dann würde das, zumindest nach dem bisher gezeigtem Code, passen. In deinem User_Model stehen keine Attribute, sondern nur Laden und Speichern... Die Daten des Users sind in dem Objekt, das User_Model#getOne zurückgibt.

Wie erzeugst du einen neuen User in der DB mit deinem Framework?

phg 05.05.2013
0
du hast da paar seltsame sachen dabei
$user_model = new User_Model($this->fw->getDatabase());
warum kümmert sich der controller um die datenbank ist doch aufgabe des models woher die daten kommen

wenn du nen neues user objekt erzeugst warum rufst du dann nicht ne statische factory funktion auf die dir das userobjekt zurück gibt vonmiraus mit der datenbank oder was auch immer

warum versuchst du zwanghaft statische sachen zu vermeiden wie beispielsweise beziehungen haben doch nix im objekt verloren

der sinn von repository ist mir nicht klar das sind sachen des models

du mischst verschiedene ansätze

public function save(User_Model $user) {}

warum speichert sich das model objekt nicht selber dafür ist es doch ein objekt

warum muss man einem objekt ein objekt übergeben das alle infos enthält um sich selbst zu speichern

mal vereinfacht

controller:
..
$model = User::factory(array('name'=>'michael');
$model->save(); was gemacht wird entscheidet das model

oder
$model = User::findOne(array('name'=>'michael');
$model->set('name','alex');
$model->save();

$modelArray = User::findAll(array('name'=>'michael');
$modelArray[0]->set('name','alex');

ka was für funktionen du brauchst saveAll usw

class model
public $values; // bsp zum speichern der werte kannst dann über magic getter und setter holen mit der attribut verknüpfung

private $dbm;
public static function::factory() {
...
$modelObject = new user()
//set some magic and return $modelObject
}
public function save() ..
public static function find() {
$dbm = dbm::getInstance(user::$dbm)
die restliche magic sollte nen db mapper übernehmen
wenn du anfängst im model sql reinzuhauen brauchst das ganze ja ned
}

class user
static $attributes = array('id','name',....)
static $dbm = 'xy';
static $dbmConfig = array('table'=>'user','primary'=>'user_id');
static $relation = array( .. )
static $validations = array( .. )

//noch userspezifische sachen die ins model gehören normal ist das model aber hauptsächlich beschreibend
public function validatePassword($pwtocheck) für login zumbeispiel das prüft ob das übergebene pw dem des mdoel objects gleicht
public function sendEmail($text) ...





wäre jetzt ein ansatz anhand deines beispiels soll jetzt nicht zu forsch sein aber ohne static nen oop ansatz find ich lächerlich
02.05.2014
di3 1

Stelle deine Php-Frage jetzt!