php.de

Zurück   php.de > Webentwicklung > Software-Design

Software-Design Diskussionen auf Profi-Niveau: PHP Lösungen auf konzeptioneller Ebene

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 08.04.2010, 15:29  
Neuer Benutzer
 
Registriert seit: 08.04.2010
Beiträge: 4
PHP-Kenntnisse:
Fortgeschritten
literal befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von dr.e. Beitrag anzeigen
Komplexe Logik hat in Domänen-Objekten nichts verloren! Das muss Teil der Business-Schicht sein, die mit Hilfe der Domänen-Objekte die relevante Geschäfts-Logik abbildet.
Da krempelt es mir die Fußnägel hoch!

Deine Vorstellung von einem Domain Model verletzt wesentliche Prinzipien der sauberen objektorientierten Softwarearchitektur.

Deine "Business-Schicht" muss intensiv auf den Zustand der "Domänen-Objekte" zugreifen (vermutlich über getter/setter). Das ist ein schönes Beispiel für den "code smell" feature envy und führt zu viel Redundanz und Abhängigkeit.

Oder anders ausgedrückt: Du arbeitest genau entgegengesetzt der Faustregel "tell don't ask":
Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.

Erst wenn die "Domänen-Objekte" (Entities) selbst den Großteil der Logik enthalten, lassen sie sich vernünftig kapseln. Viel "boilerplate code" für getter und setter fällt weg, und sie lassen sich später erweitern/ändern, ohne dass die "Business-Schicht" (Service Layer) umgekrempelt werden muss.
Der Service Layer ist dann nur noch für die großen Zusammenhänge verantwortlich, die den Fokus der Entities übersteigen und stellt ein konsistentes Interface gegenüber der Applikationsschicht zur Verfügung.

Martin Fowler hat es hier schön zusammengefasst: MF Bliki: AnemicDomainModel.

PS: Dass es oft problematisch ist, ein Domain Model mit "reichen", "aktiven" Entities mit einem ORM nach ActiveRecord-Manier zu vereinen, steht auf einem anderen Blatt...
U. a. deshalb bevorzuge ich den DataMapper-Ansatz, der nicht nur die Persistenz für die Entities transparent macht, sondern auch die enge Bindung zwischen DB-Tabelle und Entity aufhebt. Doctrine 2 scheint mir da auf einem guten Weg zu sein (Doctrine 1.x verfolgt den ActiveRecord-Ansatz, Doctrine 2 ist ein kompletter re-write im DataMapper-Schema und aktuell im Alpha-Stadium).
literal ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 10.04.2010, 00:03  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hallo literal,

Herzlich Willkommen im PHP.de-Forum!

Zitat:
Deine Vorstellung von einem Domain Model verletzt wesentliche Prinzipien der sauberen objektorientierten Softwarearchitektur.
Da bin ich anderer Meinung.

Zitat:
Deine "Business-Schicht" muss intensiv auf den Zustand der "Domänen-Objekte" zugreifen (vermutlich über getter/setter). Das ist ein schönes Beispiel für den "code smell" feature envy und führt zu viel Redundanz und Abhängigkeit.
Meine Aussage ist nicht, dass ein Domänen-Objekt dumm sein muss, in vielen Fällen ist es sogar sinnvoll, dass dieses eine gewisse Intelligenz hinsichtlich seiner Natur und Repräsentation besitzt. Nehmen wir an, du modellierst in deiner Applikation zwei Währungen (Euro und Punkte (z.B. für ein Bonus-System)). So sollte beispielswiese die Währung Euro die Intelligenz besitzten in Punkte umgewandelt zu werden oder es muss auf einfache Weise möglich sein, Punkte- und Euro-Werte zusammenzuzählen und anschließend den Wert in Punkten auszugeben.
Nicht sinnig ist allerdings die Idee, die Incentivierung eines Bonus-System komplett im Currency-Objekt, das die Bonus-Punkte repräsentiert, abzuhandeln, auch wenn dieses die relevanten Informationen dafür hätte. Weiter ist es ebenfalls nicht vorteilhaft, diese Logik in ein Domänen-Objekt User zu verfrachten, da man von dort bequem auf alle seine Einkäufe zurückgreifen kann.
Es hat ferner auch nichts damit zu tun, dass das zwangsläufig zu Redundanz führt, denn eine gut strukturierte Software wird genau das vermeiden. Sofern die Business-Schicht eine Granularität erreicht, die komplexe Berechnung (z.B. die genannte Incentivierung) als granular zu behandelnden Service zur Verfügung stellt, kann diese bequem an den relevaten Stellen der Software verwendet werden.
Abhängigkeiten sind IMHO ein Thema, das hier recht wenig Bedeutung hat. Eine Anwendung wird immer eine explizite Abhängigkeit zu seinem Domänen Modell haben. Das ist weder Willkür noch eine zu monierende Tatsache, es ist einfach das Wesen eines solchen Modells und dient der Strukturierung und der starken Typisierung einer Anwendung. Sicher kann man sich über die getter/setter-Geschichte streiten, wenn man lieber C#'s Properties mag oder den puristischen Ansatz verfolgt, dass quasi-öffentliche Attribute auch nicht nach der JAVA-Bean-Definition getter/setter bedürfen. Nicht streitbar ist jedoch, dass diese Vorgehensweise zwangsweise zu unerwünschten Abhängigkeiten führt.

Zitat:
Martin Fowler hat es hier schön zusammengefasst: MF Bliki: AnemicDomainModel.
Martin Fowler kritisiert den Ansatz der "funktionslosen" Domänen-Objekte - korrekt - jedoch ist der ebenfalls kein Freund von Domänen-Objekte, die sich direkt um die Persistenz desselben kümmern. Das wiederum ist ein ebenso weit verbereitetes "Problem". Nochmal: meine Aussage ist nicht, dass es keine Logik in Domänen-Objekten geben darf, ich möchte lediglich zu Ausdruck bringen, dass sehr wohl zu überlegen ist, wie die Domäne modelliert wird / werden sollte und die Gesamt-Architektur der Software geschnitten ist. Setzt man auf granulare Services, macht die oben beschriebene Art und Weise sicher Sinn.
In diesem Thread ging es jedoch um Applikationen, die im Allgemeinen ohnehin relativ wenig echte Domänen-Logik beinhalten, sondern mehr oder weniger eine "Datenbank-Verwaltungs-Oberfläche" mit etwas Präsentations-Logik darstellen. Hier ist es IMHO deshalb sehr schwierig, von falscher Modellierung der Domäne zu sprechen. Vielmehr ist es wichtig, vor zu starker Bindung von Domänen-Objekten zur Datenquelle zu warnen, denn das M des MVC-Pattern wird nur allzuoft missinterpretiert.

Sofern du das Thema Domänen-Logik weiter ausführen möchtest - sehr gerne -, kann ich den Thread auch teilen.
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Alt 13.04.2010, 14:40  
Neuer Benutzer
 
Registriert seit: 08.04.2010
Beiträge: 4
PHP-Kenntnisse:
Fortgeschritten
literal befindet sich auf einem aufstrebenden Ast
Standard

Hallo dr.e.,

von mir aus kannst du gern einen neuen Thread abspalten.

Man redet bei diesem Thema natürlich gern aneinander vorbei, weil Begriffe wie "Domain Model" in der Literatur unterschiedlich definiert sind und dann noch von jedem Entwickler mit dem Hintergrund konkreter Projekterfahrung eingeordnet und bewertet werden.

Hinzu kommt, und darauf können wir uns sicherlich einigen, dass es keine allgemein richtige Anwendungs-Architektur gibt, sondern dass diese immer auch fallabhängig ist. Auch Fowler schreibt ja zum Beispiel, dass er begründete Fälle sieht, auf ein Domain Model (in seinem Sinne) ganz zu verzichten.

Wenn du mit diesen beiden Punkten übereinstimmst, wirst du vermutlich auch einräumen, dass deine ursprüngliche Aussage, an der ich mich gestört habe, zumindest in ihrer Absolutheit ("X hat in Y nichts verloren! Das muss ...") suboptimal ist, und evtl. den weniger bewanderten Leser auf die schiefe Bahn bringen könnte.


Zitat:
Zitat von dr.e. Beitrag anzeigen
Martin Fowler kritisiert den Ansatz der "funktionslosen" Domänen-Objekte - korrekt - jedoch ist der ebenfalls kein Freund von Domänen-Objekte, die sich direkt um die Persistenz desselben kümmern.
1. Ich finde es ziemlich eindeutig, dass er auch funktions-arme Domain-Objekte kritisiert.

2. Die Persistenz hat damit nichts zu tun. Sie soll natürlich nicht im Domänen-Objekt implementiert sein.
Sie ist ja einfach ein anderer Aspekt (im Sinne von Aspektorientierter Programmierung, oder "Concern" wie in "Separation of Concerns"), der die Domänen-Objekte nichts angehen sollte. Deshalb sind ja auch ORMs nach dem Datamapper-Pattern (siehe meinen letzten Post) so charmant, weil sie die Instrumente der AOP nutzen, um non-invasiv die Domänen-Objekte zu persistieren, ohne das diese überhaupt davon wissen müssen.


Zitat:
Zitat von dr.e. Beitrag anzeigen
Nicht sinnig ist allerdings die Idee, die Incentivierung eines Bonus-System komplett im Currency-Objekt, das die Bonus-Punkte repräsentiert, abzuhandeln, auch wenn dieses die relevanten Informationen dafür hätte. Weiter ist es ebenfalls nicht vorteilhaft, diese Logik in ein Domänen-Objekt User zu verfrachten, da man von dort bequem auf alle seine Einkäufe zurückgreifen kann.
Da stimme ich dir zu. Das "Single Responsibility Principle" verbietet dies. Das ist aber überhaupt kein Argument dafür, die Logik des Incentive-Programms in eine übergeordnete Schicht zu packen, die wie ein Gott über die Domänen-Objekte wacht und über getter/setter an deren Implementation gekoppelt ist (und so habe ich deinen Ansatz bisher verstanden).

Als ad-hoc Lösung (sicher bei genauer Betrachtung Mist, mal sollte sich für sowas Zeit nehmen): Ein Domänen-Objekt IncentiveBenefit hinzufügen, das der User besitzen kann. Zusätzlich ein Interface IIncentiveProgramm definieren, dessen konkrete Implementationen die Berechnung durchführen. Eine Implementation von IIncentiveProgramm wird an das IncentiveBenefit-Objekt übergeben (Strategy Pattern).
Die Bonus-Punkte teilen ihren Wert dem IncentiveBenefit-Objekt mit, und dieses macht damit, was es will.
So bleibt die Logik bei den Daten und alles bleibt modular, sprich änderbar und wiederverwendbar.


Zitat:
Zitat von dr.e. Beitrag anzeigen
Es hat ferner auch nichts damit zu tun, dass das zwangsläufig zu Redundanz führt, denn eine gut strukturierte Software wird genau das vermeiden.
Es ist redunant, wenn ein Fremder (irgendein Service, Manager, was-weiß-ich aus der Logik-Schicht) etwas über die Properties eines Domänen-Objekts weiß und mit diesen arbeitet/rechnet. Dann gibt es zwei Orte, an denen das Wissen über das Domänen-Objekt sich manifestiert und auch zwei Stellen, an denen es ggf. geändert werden muss.

Nun aber mal ein Beispiel (vereinfacht, bitte nicht an Praxis messen). Nehmen wir einen Online-Shop, weil der einiges an Logik erfordert und nicht nur ein besseres DB-Front-end ist.

Zu angebotenen Artikeln sind die Versandkosten zu berechnen.

Du würdest es vielleicht so machen:
PHP-Code:
/**
 * Teil der "Business-Logik"-Schicht
 */
class ShippingCostCalculator
{
    
/**
     * @var ICarrier
     */
    
private $carrier;

    
// ...

    /**
     * @param IItem Domänen-Objekt
     */
    
private function calcualteItemShippingCostIItem $item )
    {
        
$grossWeight $item->getGrossWeight();
        
$packageDimensions $item->getPackageDimensions();
        return 
$this->carrier->calcualteShippingCost($grossWeight$packageDimensions);
    }
    
    
// ...

* Nun gibt es vielleicht Artikel, für die Verpackungsmaß oder Gewicht nicht hinterlegt sind.

* Vielleicht kommt irgendwann die Möglichkeit hinzu, für einzelne Artikel alternativ eine Versandkosten-Pauschale vorzugeben.

* Vielleicht geben wir Verpackungsmaß und Gewicht irgendwann ganz auf, weil der Händler, der die Software nutzt, es nicht schafft, diese Werte richtig zu erfassen und zu pflegen.

* Vielleicht werden irgendwann auch digitale Güter vertrieben, für die es gar keine Versandkosten, geschweige denn Maß und Gewicht gibt.

Dies alles müsste man im ShippingCostCalculator abbilden. Jede interne Änderung bei den Artikeln müsste auch hier nachvollzogen werden. Genau diese Art von Abhängigkeit ist kein Kavaliersdelikt, sondern macht aus Software einen nicht mehr wartbaren Schrotthaufen.

Überlässt man jedoch die Berechnung der Versandkosten dem Artikel selbst (der sich ggf. seinerseits an ein Versanddienstleister-Objekt wendet), muss kein Außenstehender mehr wissen, dass ein Artikel Maß und Gewicht hat. Die getter für diese Eigenschaften fallen weg.

Digitale und physische Güter könnte man via Polymorphie abbilden. Der digitale Artikel hätte dann in der Tat gar keine Properties für Maß und Gewicht mehr.



Zitat:
Zitat von dr.e. Beitrag anzeigen
Abhängigkeiten sind IMHO ein Thema, das hier recht wenig Bedeutung hat. Eine Anwendung wird immer eine explizite Abhängigkeit zu seinem Domänen Modell haben.
Es ging mir eigentlich um die Abhängigkeiten zwischen Domänen-Objekten und dem, was du Business-Schicht nennst.

Die Abhängigkeit der Applikation (ich meine jetzt V und C aus MVC) zum Domain Model (im Fowler-Sinne, also lauter autonome Objekte voller Verhalten) kann man durch einen Service-Layer zwischen den beiden reduzieren. Der Service-Layer stellt - in prozeduraler Manier - Aktionen und Daten aus dem Domain Model zur Verfügung. So wie es z. B. ein Web-Service auch tut, nur eben innerhalb der Anwendung. Wenn man es so konstruiert, stimmt deine Aussage ("Anwendung ... immer ... explizite Abhängigkeit ... Domänen Modell") nicht mehr ganz.


Zitat:
Zitat von dr.e. Beitrag anzeigen
Sicher kann man sich über die getter/setter-Geschichte streiten, wenn man lieber C#'s Properties mag oder den puristischen Ansatz verfolgt, dass quasi-öffentliche Attribute auch nicht nach der JAVA-Bean-Definition getter/setter bedürfen.
Wie man es macht, ist doch egal. Die breite Fraktion der Kritiker richtet sich generell gegen den Zugriff auf die Eingeschaften eines Objekts von außen.
Wenn man getter/setter oder Property-Zugriff braucht, heißt das bis auf wenige Ausnahmen, dass man in seiner Architektur ein Problem hat.
Falls du das anders siehst, ist das vielleicht noch einen weiteren Thread wert...


Zitat:
Zitat von dr.e. Beitrag anzeigen
Vielmehr ist es wichtig, vor zu starker Bindung von Domänen-Objekten zur Datenquelle zu warnen, denn das M des MVC-Pattern wird nur allzuoft missinterpretiert.
Das kann ich nur unterstreichen. Darum finde ich das Active Record Pattern ja auch so problematisch.

Geändert von literal (16.04.2010 um 11:46 Uhr). Grund: Edith: Noch mal durchgelesen, PHP-Beispiel war fehlerhaft
literal ist offline   Mit Zitat antworten
Alt 16.04.2010, 11:30  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hallo Literal,

ich hatte leider noch keine Zeit zum antworten, würde die Diskussion aber gerne weiter führen. Du liest von mir...!
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Alt 04.05.2010, 20:50  
Neuer Benutzer
 
Registriert seit: 08.04.2010
Beiträge: 4
PHP-Kenntnisse:
Fortgeschritten
literal befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von dr.e. Beitrag anzeigen
ich hatte leider noch keine Zeit zum antworten, würde die Diskussion aber gerne weiter führen. Du liest von mir...!
Und? Nach zwei Wochen kann man ja mal eine kleine Erinnerung loslassen...
literal ist offline   Mit Zitat antworten
Alt 04.05.2010, 22:44  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hi,

korrekt, die Antwort steht noch aus, das wird aber leider noch ein wenig auf sich warten lassen müssen. Sobald ich ein paar Minuten habe (leider laufen aktuell mehrere Projekte parallel...), werde ich mein Versprechen natürlich einhalten. Indianer-Ehrenwort!
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Alt 04.05.2010, 22:48  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

[OT]

Zitat:
Indianer-Ehrenwort!
Die hier?
Dailymotion - Apache - a Music video
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist gerade online   Mit Zitat antworten
Alt 05.05.2010, 15:37  
Erfahrener Benutzer
 
Benutzerbild von lstegelitz
 
Registriert seit: 07.09.2009
Beiträge: 4.005
PHP-Kenntnisse:
Fortgeschritten
lstegelitz ist einfach richtig nettlstegelitz ist einfach richtig nettlstegelitz ist einfach richtig nettlstegelitz ist einfach richtig nett
Standard

Zitat:
Zitat von nikosch Beitrag anzeigen
ROFL *tränenausdenaugenwisch*

Wo holst du so Dinger immer her?
__________________
Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.
lstegelitz ist offline   Mit Zitat antworten
Alt 05.05.2010, 15:43  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Bin ich mal übers Chaosradio (worüber? Na Apacheeee) drauf gestoßen. Den Song hatte man noch in irgendwelchen versteckten Hirnwindungen. Aber das Video kannte ich bis dahin auch nicht. Aber den Schnauzbart des Sängers, sein gnadenlos gutes Keyboardspiel und die apachenhaften Bewegungen der „Indianerinneinenininnen“ fand ich doch zu sehenswert. Und jetzt alle locker die Hüften kreisen lassen
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist gerade online   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php model datenbank, doctrine2, entity erweitern, php models, doctrine 2 service layer, softwarearchitektur php fowler, domain model datenbank, datenbank abstraktion, model datenbank php, datenbankabstraktion, doctrine webservice, business schucht warnungen, mvc mehrere datenbanken in einem model php, datenbankabstrakion, domänenobjekte doctrine, datenbankastraktionsframework, pattern setter übergeordnete properties, doctrine 2 abhängigkeit, doctrine 2 setters, doctrine 2 liest falsche daten aus der db, mvc domain model php beispiel

Alle Zeitangaben in WEZ +2. Es ist jetzt 00:37 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum