Wiederverwendbarkeit von Klasse

Hallo,

vor einiger Zeit war ja eine längere Diskussion über die
Wiederverwendbarkeit von Klassen hier im Gange.
Dazu würde ich gerne noch eine Frage stellen:

Wenn ich mir z.B. eine Klasse schreibe, die in einem Projekt für das
Speichern von Datensätzen in eine DB zuständig sein soll... eine
Wiederverwendbarkeit dieser Klasse in einem anderen Projekt wäre ja
dann eigentlich nur gegeben, wenn die Klasse so abstrakt ist, dass man
damit jede noch so verschiedene SQL-Inserts / Updates damit
verarbeiten könnte ... also eine Klasse die z.B. Formulardaten aus
einem dann x-beliebigen Formular entgegennimmt und die entsprechende
MySQL-Zieltabelle - und die Verarbeitung übernimmt, inkl. möglicher
Doppeltprüfung, Verarbeitung und Speichern von Binärdaten ... sehe ich
das richtig? Alles anderes wäre doch im Sinne der Wiederverwendbarkeit
nicht besonders sinnvoll, oder?

Und: hat jemand so eine Klasse im Einsatz?

Danke

Markus
markus.libers [ Mo, 01 Oktober 2007 12:04 ] [ ID #1833611 ]

Re: Wiederverwendbarkeit von Klasse

markus.libers [at] googlemail.com schrieb:
> vor einiger Zeit war ja eine längere Diskussion über die
> Wiederverwendbarkeit von Klassen hier im Gange.
> Dazu würde ich gerne noch eine Frage stellen:
>
> Wenn ich mir z.B. eine Klasse schreibe, die in einem Projekt für das
> Speichern von Datensätzen in eine DB zuständig sein soll... eine

Meinst du ein OR-Mapper? Da gibt es fertige Lösungen dafür, wo dir
manche Andere auch einen Link zum weiterlesen geben können (ich kenne
leider keinen, nutze lieber eigene Lösungen).

> Wiederverwendbarkeit dieser Klasse in einem anderen Projekt wäre ja
> dann eigentlich nur gegeben, wenn die Klasse so abstrakt ist, dass man
> damit jede noch so verschiedene SQL-Inserts / Updates damit
> verarbeiten könnte ... also eine Klasse die z.B. Formulardaten aus
> einem dann x-beliebigen Formular entgegennimmt und die entsprechende
> MySQL-Zieltabelle - und die Verarbeitung übernimmt, inkl. möglicher
> Doppeltprüfung, Verarbeitung und Speichern von Binärdaten ... sehe ich
> das richtig? Alles anderes wäre doch im Sinne der Wiederverwendbarkeit
> nicht besonders sinnvoll, oder?
>
> Und: hat jemand so eine Klasse im Einsatz?

Ich habe mir eine solche Klasse selbst geschrieben, allerdings mit
größeren Einschränkungen. Vor allem sehe ich meine Klasse als
Hilfsmittel für die Vereinfachung des Zugriffs und Manipulation
einzelner Datensätze und nicht zur Ablösung sämtlicher SQL Statements
eines Projektes.

Einschränkungen bei mir:
- Zugriff nur auf einzelne Datensätze möglich
- Nur auf eine Tabelle pro Zugriff beschränkt, keine Joins möglich
- Zugriff nur über die Primärschlüssel möglich
- Nur mit Hilfe meiner Connection und einzelne weiterer Klassen verwendbar

Daher ist die Wiederverwendbarkeit für mich sehr groß, da ich diese
Klassen für alle Projekte einsetzen kann. Für alle Anderen aber eher
weniger interessant, da die Lösung nicht als Ersatz von SQL Statements
zu sehen ist und nur in meiner Umgebung (andere Klassen) einsetzbar ist.

Hier etwas komplett flexibles selbst zu bauen dürfte sehr schwer werden
und übersteigt mit Sicherheit den Nutzen für dich als einzelne Person.
Daher solltest entweder was flexibles fertiges nutzen oder wie ich etwas
eigenes aber dafür sehr eingeschränktes schreiben. Alles andere dürfte
etwas mehr Zeit kosten.

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Mo, 01 Oktober 2007 12:13 ] [ ID #1833612 ]

Re: Wiederverwendbarkeit von Klasse

markus.libers [at] googlemail.com schrieb:
....

> Wenn ich mir z.B. eine Klasse schreibe, die in einem Projekt für das
> Speichern von Datensätzen in eine DB zuständig sein soll... eine
> Wiederverwendbarkeit dieser Klasse in einem anderen Projekt wäre ja
> dann eigentlich nur gegeben, wenn die Klasse so abstrakt ist, dass man
> damit jede noch so verschiedene SQL-Inserts / Updates damit
> verarbeiten könnte

Nö.
Die /Daten/ sind meist bei verschiednen Projekten meist nicht Kongruent.
Deshalb gibt es für die Datenklassen ein ORM.

Die allgemeinen und wiederverwendbaren Klassen benutzen dann nur die
Schnittstelle dieser Objekte:

interface DataClass
{
public function isChanged(); // hat sich was geändert
public function write($connection); // In die DB schreiben
public function read($connection,$where); // Aus der DB lesen
...
// Infos über die Datenbanktabelle
public function getPK(); //Spaltenname des Primary-keys
public function getCollums(); //Alle Spaltennamen
...
// Standard infos über die Daten
public function getID(); //Wert der Primary-keys
...
}

> ... also eine Klasse die z.B. Formulardaten aus
> einem dann x-beliebigen Formular entgegennimmt und die entsprechende
> MySQL-Zieltabelle - und die Verarbeitung übernimmt, inkl. möglicher
> Doppeltprüfung, Verarbeitung und Speichern von Binärdaten ... sehe ich
> das richtig? Alles anderes wäre doch im Sinne der Wiederverwendbarkeit
> nicht besonders sinnvoll, oder?

Die Validierung findet nicht in den ORM-Klassen statt. Dort wird nur
sehr rudimentär geprüft. Ob z.B ein Wert NULL sein darf oder nicht.

Nach der erfolgreichen Validatorprüfung wird das POST-Array der
ORM-Instanz übergeben. Dieses sucht sich selber die richtigen Parameter
aus dem Array.

D.H die Validaroren/Formularklassen haben nichts mit der Datenbank zu
tun. Die benötigen nach erfolgreicher validierung nur ein Objekt welches
Interface DataTool implementiert.

interface DataTool
{
public function setFromArray();
}

> Und: hat jemand so eine Klasse im Einsatz?

Ja.
Ich generiere die ORM-Klassen direkt mit einem Script aus der Datenbank.
Es gibt auch fertige Gereatoren für das Mapping. In Java währe das z.B
Hibernate. Aber mir persönlich ist das zu Bloatig und unfexibel.
Harald Stowasser [ Mo, 01 Oktober 2007 14:15 ] [ ID #1833616 ]

Re: Wiederverwendbarkeit von Klasse

Harald Stowasser schrieb:
> Die /Daten/ sind meist bei verschiednen Projekten meist nicht Kongruent.
> Deshalb gibt es für die Datenklassen ein ORM.
>
> Die allgemeinen und wiederverwendbaren Klassen benutzen dann nur die
> Schnittstelle dieser Objekte:

das heißt dieser OR-Mapper muss bei jeder Klasse die Methoden zum
Speichern, Laden, Löschen und Einfügen des Datensatzes implementieren,
da er auf Schnittstellen aufbaut?

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Mo, 01 Oktober 2007 14:31 ] [ ID #1833617 ]

Re: Wiederverwendbarkeit von Klasse

Christoph Herrmann schrieb:
> Harald Stowasser schrieb:
>> Die /Daten/ sind meist bei verschiednen Projekten meist nicht Kongruent.
>> Deshalb gibt es für die Datenklassen ein ORM.
>>
>> Die allgemeinen und wiederverwendbaren Klassen benutzen dann nur die
>> Schnittstelle dieser Objekte:
>
> das heißt dieser OR-Mapper muss bei jeder Klasse die Methoden zum
> Speichern, Laden, Löschen und Einfügen des Datensatzes implementieren,
> da er auf Schnittstellen aufbaut?

Ja. Wobei ich mich an ein paar Konventionen halte. Und so macht mein
ORM-Generator diese Funktionen automatisch. Die tippe ich nicht selber ein.

Außerdem kann man ja auf grundlegende Funktionen zurückgreifen.
Die funktion fürs Laden aus der DB wird z.B. komplett vererbt:

public function getFromSql( &$result, $offset = 0 ) {
if ( $offset == 0 ) {
$anz = count( $result );
if ( $anz == $this->getSQLCOUNTER( ) ) {
$this->daten = $result;;
} elseif ( $anz > $this->getSQLCOUNTER( ) ) {
$this->daten = array_slice( &$result,
0, $this->getSQLCOUNTER( ));
} else {
throw new EDbObject( 10019, $anz );
}
} else {
$this->daten = array_slice( &$result,
$offset, $this->getSQLCOUNTER( ) );
if ( count( $this->daten ) !== $this->getSQLCOUNTER( ) ) {
throw new EDbObject( 10020 );
}
}
}

DataClass::getSQLCOUNTER gibt z.B. immer die Anzahl der Spalten einer
Ergebniss-tabelle zurück.
Harald Stowasser [ Mo, 01 Oktober 2007 14:52 ] [ ID #1833621 ]

Re: Wiederverwendbarkeit von Klasse

Harald Stowasser schrieb:
> Ja. Wobei ich mich an ein paar Konventionen halte. Und so macht mein
> ORM-Generator diese Funktionen automatisch. Die tippe ich nicht selber ein.

ehrlich gesagt finde ich da meine eigene Lösung einfacher. Aber wird
wohl daran liegen, dass diese auch viel weniger bietet. :)

[OT]
Für alle die es interessiert (Meinungen sind immer willkommen):

Für eine neue Tabelle mache ich einfach eine neue Klasse die von der
Basisklasse erbt:
class ErrorDatabase extends AbstractDatabase

Diese muss das statische Attribut beinhalten für die spätere
Tabellenbeschreibung:
private static $description = null;

Im Konstruktor werden die Primärschlüssel definiert, falls es kein neuer
Datensatz ist und der Name der Tabelle in der Datenbank (zum Laden,
Löschen und Manipulieren eines vorhandenen Datensatzes):
public function __construct($id = null)
{
parent::__construct('error');
if(isset($id))
{
$this->addPrimaryKey('id', $id);
}
}

Und eine Methode muss überschrieben und erweitert werden, welche die
Tabellenstruktur definiert:
public function getDescription()
{
if(isset(self::$description) == false)
{
self::$description = parent::getDescription();

self::$description->addColumn('id', 'Numeric', 'INTEGER
UNSIGNED', array('AUTO_INCREMENT' => true));
self::$description->addPrimaryKey('id');
...
}
return self::$description;
}

Und die komplette Funktionalität kommt von der Basisklasse.

Datensatz einfügen:
$database = new ErrorDatabase();

$database->set('type', $type);
$database->set('file', $file);
$database->set('line', $line);

try
{
$database->insert();
} catch(StatementException $exception)
{

}

Datensatz ändern:
$database = new ErrorDatabase(1);

$database->set('file', $new_file);

try
{
$database->update();
} catch(StatementException $exception)
{

}
[/OT]

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Mo, 01 Oktober 2007 15:05 ] [ ID #1833622 ]

Re: Wiederverwendbarkeit von Klasse

markus.libers [at] googlemail.com wrote:
> Wenn ich mir z.B. eine Klasse schreibe, die in einem Projekt für das
> Speichern von Datensätzen in eine DB zuständig sein soll... eine
> Wiederverwendbarkeit dieser Klasse in einem anderen Projekt wäre ja
> dann eigentlich nur gegeben, wenn die Klasse so abstrakt ist, dass man
> damit jede noch so verschiedene SQL-Inserts / Updates damit
> verarbeiten könnte ...

Eine "eierlegende" Wollmilchsau gibt es eigentlich nur in ORM. Diese zu
nutzen ist eine grundlegende Entscheidung, ich nutze diese nicht, da
ich in bestehende Projekte sowas nicht einbinden will und mein
"Denkweise" besser mit meinem Programmcode zusammenpasst.

Jede Klasse ist folglich "in sich" mit ein paar MEthoden ausgestattet,
die sinnvollerweise store(), delete(), init() usw. heissen.

Da jedes Objekt in einer Datenbank repräsentiert wird, muss ich
Anpassungen machen, was nun beim Löschen genau passiert. Für die
"berüchtigten" Relationen sorgt eine gesonderte Klasse für Datenbanke=
n,
die die entsprechenden Objekte übernimmt und die Relationen entfernt.

Durch diese "Verkettungen" der Klassen, wird alles gelöscht.

Beim Initialisieren sieht es dann wiederum ein wenig düster aus, da
werden eher je nach Anwendungsfall entsprechende Statements in den
Klassen über MEthoden initilisiert und einer weiteren Klasse, die für=

die Darstellung der Daten ist übergeben (das ist so eine Art Lister
Klasse, die es ermöglicht, relativ einfach Tabellen webgerecht
darzustellen, so mit Sortierungen von Spalten etc.

Das, und das ist meine Meinung, noch weiter zu abstrahieren, ginge
wohl, aber ich halte das für ein Problem der Lesbarkeit. Je abstrakter =

umso mehr schlägt meine Vergesslichkeit zu: Wer weiss welcher genialer =

Strukturgedanke nachts um 3 Uhr schlägt von dem morgens um 11 Uhr
nichts mehr vorhanden ist und man nur noch ein svn checkout -1 Day
machen kann/muss.

> also eine Klasse die z.B. Formulardaten aus
> einem dann x-beliebigen Formular entgegennimmt und die entsprechende
> MySQL-Zieltabelle - und die Verarbeitung übernimmt, inkl. möglicher=

> Doppeltprüfung, Verarbeitung und Speichern von Binärdaten

Nun, ich habe mir vor etlichen Jahren die, so meine ich, genialste
Klasse geschrieben die es gibt. Die bearbeitet Formulardaten mit Hilfe
von 3 Zeilen komplett, mit Eingabevalidierung, Fehlerausgabe, zur Not
über XAJax usw. usf. Alles was mein Formular verarbeiten muss, bleibt
in dieser Klasse, erst wenn alles meinen Vorgaben entspricht, gehen die
Daten ans Objekt über. Das Geheimnis dieser Klasse, liegt zur Zeit in
einer XML-Definitionsdatei für das komplette Formular, einer CSS und
ein wenig Disziplin. Das macht dann aus einem FOrmular mit z.B. 30
Formularfeldern ein einfaches:

$form=3Dnew xmlform();
$form->buildform("formular", $errorvalue, $formvalues);

Und beim Prüfen ein simples
$formvalues=3D$form->pcheckall("formularname");

if( $errorvalue=3D$form->getinputerror() ){
// es liegen Fehler vor...
} else {
// alles paletti...
}

Da ich Formulare mit meistens dem 3-4fachen Anzahl der Eingabefelder
habe (Konfigurationen über RegTabs), ist das schon eine nette
Arbeitserleichterung. Das nenne ich dann Wiederverwendbarkeit ;-)

> ... sehe ich
> das richtig? Alles anderes wäre doch im Sinne der Wiederverwendbarkei=
t
> nicht besonders sinnvoll, oder?

Was ist schon Sinnvoll? Wenn das mit dem Programmieren alles soooo
einfach wäre, wie das sämtliche Theorien belegen, warum dann noch
Programmfehler und Softwareentwickler?

Je komplexer und abstrakter du der Meinung bist programmieren zu
wollen/zu können, desto problematischer wird es dann, wenn du gezielt
Erweiterungen einbauen willst, die nicht im Plan des Entwicklers deiner
Komponenten sind.
Aus diesem Grunde mag ich z.B. PEAR nicht wirklich, weil dort zuviel
miteinander verzahnt wird. Was auf der einen Seite ja genau diese
Wiederverwendbarkeit darstellen (soll), ist genau dieser Hemmschuh, mit
dem ich mich herumquäle: =DCbersicht und Verständnis der Funktionswei=
se.

Verstehe mich nicht falsch: Wenn alles einwandfrei funktioniert, ist
das alles blendend und toll. Aber wehe du kommst an den Punkt, wo
irgendwas, irgendwie nicht funktioniert oder nicht ganz deinen Wünschen=

entspricht...
Rainer Hinz [ Mo, 01 Oktober 2007 20:16 ] [ ID #1833628 ]

Re: Wiederverwendbarkeit von Klasse

> Wenn ich mir z.B. eine Klasse schreibe, die in einem Projekt für das
> Speichern von Datensätzen in eine DB zuständig sein soll... eine
> Wiederverwendbarkeit dieser Klasse in einem anderen Projekt wäre ja
> dann eigentlich nur gegeben, wenn die Klasse so abstrakt ist, dass man
> damit jede noch so verschiedene SQL-Inserts / Updates damit
> verarbeiten könnte ... also eine Klasse die z.B. Formulardaten aus
> einem dann x-beliebigen Formular entgegennimmt und die entsprechende
> MySQL-Zieltabelle - und die Verarbeitung übernimmt, inkl. möglicher
> Doppeltprüfung, Verarbeitung und Speichern von Binärdaten ... sehe ich
> das richtig? Alles anderes wäre doch im Sinne der Wiederverwendbarkeit
> nicht besonders sinnvoll, oder?
>
> Und: hat jemand so eine Klasse im Einsatz?

Ja. Ich habe eine generische Klasse Table mit den Methoden write, update
und delete. Für write gibst Du ihr ein assoziatives Array, für update
ein assoziatives array + ID und für delete nur eine ID. Damit habe ich
80% der schreibenden Datenbankgeschichten abgefackelt, denn was macht
man schon sonst den ganzen Tag mit Datenbanken.
Als Erweiterung gibt es noch TableList, für reine Listen wie Geschlecht,
Land, akademischer Grad etc. pp mit vereinfachten Methoden (addValue(),
resolveId() z. B.)

Formular & Validierung macht eine eigenständige Formularklasse mit
Validatoren. Schliesslich braucht man ja auch ab und zu ein paar
nicht-Datenbankformulare wie Feedback usw. usf.
Von der gibt es eine Kindklasse DBForm, die eine generische Tabelle
frisst und nette Methoden wie DBForm::addList(TableList $list) hat; die
baut sich dann aus der entsprechenden Listentabelle ein Dropdown.

Damit habe ich vermutlich ein schnelleres, performanteres, stabileres
und wartungsfreundlicheres Schema als irgendwelches ORM und MCV-Glomp.

Wenn ich es für nötig halte, schreibe ich mir noch quasi-Models für z.
B. Zeugs wie User mit speziellen Methoden wie getAccessRights() or
hasRight().

Ich habe es gerade noch nicht veröffentlicht, aber bereits im Einsatz.
Falls Du Interesse hast...
--
Mein Zeugs:
http://www.hadanite-marasek.de/classes.php
http://www.objektivsuche.de/
Hadanite Marasek [ Mo, 01 Oktober 2007 19:15 ] [ ID #1833631 ]
PHP » de.comp.lang.php.misc » Wiederverwendbarkeit von Klasse

Vorheriges Thema: S: Projektmanagementtool
Nächstes Thema: Require bzw. Include bei mir fehlerhaft