Hier im Forum bekommt ihr bei euren fragen schnelle hilfe.Hier geht es rund um das Web SeitenProgrammieren.Alles rund ums Javascript,Html,Php,Css und Sql.Auf fast allen Fragen haben wir eine Antwort.
Der Soforthilfe-chat verspricht das ,was sein Name sagt. Hier sind Leute Online die sofort ihre hilfe anbieten.Seht in der OnlineListe nach und wenn einer Online ist werdet ihr auch antwort bekommen. Admine ,Moderatoren und Helfer sind unsere Spezialisten in Sachen Web Programierung

Sie sind hier : sebastian1012.bplaced.net/ homepage-neu / kreuz-und-quer / index.php

Random Themen, Tutorials und co

24.09.2019 21:36:32

Gänsefüßchen oder Hochkomma?

Im Web liest man recht oft, dass PHP-Ausgaben, die in Hochkommata eingeschlossen werden, etwas schneller gehen als die Variante in Gänsefüßchen. Eigentlich ist die Gänsefüßchen-Variante aus meiner Sicht „richtiger“ von der Syntax her, da Strings in vielen Programmiersprachen in eben diesen Zeichen eingeschlossen werden. Dort sind Singlequotes (Hochkommata) für den Datentyp char (ein einzelnes Zeichen) zuständig. Aber nicht zuletzt auf Wunsch der in den Kommentaren zur Einbettung oder Konkatenierung von Variablen in Strings möchte ich diesem Phänomen einen eigenen Beitrag widmen.

Nur, damit jeder weiß, worum es hier gehen soll:

// Doublequote-Variante echo "Hallo, der aktuelle Timestamp ist ".time().".";   //Singlequote-Variante echo 'Hallo, der aktuelle Timestamp ist '.time().'.';

Im Benchmark selbst wird ein längerer String mit mehr Variablen verwendet, damit ein signifikantes Ergebnis zustandekommt.

Das Ergebnis widerspricht vielleicht vielen Meinungen, die man im Internet so liest, aber die beziehen sich vermutlich auf frühere PHP-Versionen. In diesem Test wurde PHP 5.1 verwendet.

Datei Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
var_out_of_string.php 132.810973 s 13.281 ms 100 %
var_out_of_string_ singlequote.php 136.205855 s 13.621 ms 103 % (+ 3%)

Tatsächlich ist die Singlequote-Variante hier etwas langsamer. Ich selbst nutze schon lange Doublequotes, eben aus oben genannten Gründen, wie es bei anderen Programmiersprachen gehandhabt wird, weniger wegen der besseren Performance. Über die Gründe, warum Doublequotes etwas schneller sind, mag ich nicht zu mutmaßen – oder anders gesagt: ich habe keine Ahnung ????

Diese minimalen Geschwindigkeitsvorteile sollten aber nicht zum Umschreiben vorhandener Anwendungen führen. Lediglich für die Zukunft kann man sich durchaus auf die Doublequote-Variante besinnen.

Zum Selbsttest und Nachvollziehen der Ergebnisse gibts hier noch die Quellcodes und die Benchmark-Ergebnisse.

Die abschließende Hoffnung, die ich in vielen meiner Beiträge äußere: Ich hoffe, dass ich ihr Weltbild mit diesen Äußerungen nicht verdreht habe ????

PS: Ich habe es nochmal mit dem Komma als Konkatenierungszeichen probiert. Hier die Ergebnisse dazu:

Datei Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
var_out_of_string_ komma.php 132.790944 s 13.279 ms 100 %
var_out_of_string.php 138.629340 s 13.863 ms 104 % (+ 4%)

Das Komma ist demzufolge tatsächlich etwas schneller als der Punkt. Auch zu diesem „Nachtest“ gibts natürlich die Quelltexte und die Benchmarkergebnisse. Die Unterschiede zu den Zeiten in der oberen Tabelle sind darin begründet, dass ich zum Nachtest den Rechner bereits länger hab laufen lassen (den halben Arbeitstag etwa) und dadurch der Speicher schon etwas voller war. Die jeweiligen Unterschiede in den Ausführungszeiten pro Tabelle sind aber unter gleichen Bedingungen erfolgt.

php

10.11.2019 04:39:44

JavaScript- und CSS-Dateien parallel downloaden

Um den HTML-Code schlank zu halten, doppelten Code zu vermeiden und Browser-Caching optimal einsetzen zu können, lagern viele Entwickler JavaScript- und CSS-Code in eigene Dateien aus und referenzieren diese Dateien anschließend im HTML-Code mit dem <script>- bzw. <link>-Tag. Doch sollte einiges beachtet werden.

Zuerst ist zu sagen, dass auf CSS-Dateien stets im <head> der Seite referenziert werden sollte und auf JavaScript am Ende des Bodys. Das ist deshalb gut, weil der Browser dann sofort alle CSS-Regeln hat und sofort mit der Formatierung der HTML-Elemente beginnen kann. Ansonsten wartet der Browser mit dem Rendering der Seite bis alle CSS-Dateien geladen sind.
JavaScript-Dateien sollten aus dem Grund direkt vor </body> eingefügt werden, da mit JavaScript HTML-Elemente erzeugt werden können, z.B. durch document.write() oder document.createElement(). Dadurch wird der HTML-Baum verändert. Deshalb muss der Browser mit dem Rendern des folgenden HTML-Codes warten bis die JavaScript-Datei geladen ist (denn der Browser weiß ja vorher nicht, was in der JS-Datei gemacht wird).
Mehr dazu, warum CSS im Head eingebunden werden sollte, gibt es bei Google Page Speed und im Yahoo Developer Network.

Nun kommt es aber manchmal vor, dass man noch einzelne kleine Code-Anweisungen nicht auslagern kann, beispielsweise wenn per PHP noch eine Variable eingefügt werden muss. Man hat dabei zwei Möglichkeiten:

  1. Dynamische CSS- bzw. JS-Datei per PHP-Script erstellen und Variable als GET-Parameter übergeben
  2. CSS- bzw. JS-Code mit dem Parameter direkt in den HTML-Code unterbringen

zu 1.: Diese Variante ist sehr schlecht, da mit der Änderung des Parameters sich der Dateiname der Ressource ändert. Dadurch muss die gesamte Datei erneut geladen werden, denn der Browser kann nicht auf die Datei aus dem Browser-Cache zugreifen.
zu 2.: erstmal noch kurz, was genau mit parametrisierten CSS- und JS-Anweisungen gemeint ist:

<style type="text/css"> .klasse { width: <?php echo $breite; ?> } </style> <link rel="stylesheet" href="restliches_CSS.css" type="text/css" />   <script type="text/javascript"> var elemente = "<?php implode(",",$elementeArray); ?>"; </script> <script src="restliches-Javascript.js" type="text/javascript"></script>

Diese Variante ist besser, da der größte Teil der Ressource aus dem Browser-Cache geladen werden kann. Aber es gilt folgendes zu beachten:
Wie oben gesagt, beginnt der Browser erst mit dem Rendering, sobald er alle CSS-Dateien und -regeln geladen hat. Deshalb sollten die parametrisierten CSS-Regeln, die im HTML-Code stehen möglichst auch im <head> stehen. Es ist aber zu beachten, dass JavaScript-Code zwischen 2 externen Ressourcen die Parallelisierung verhindert. Deshalb sollten stets alle externen JS-Dateien direkt hintereinander eingebunden werden. Erfolgt zwischen den einzelnen Referenzierungen zu CSS-Dateien oder JS-Dateien ein JS-Befehl, kann der Download nicht parallel erfolgen.

Beispiel (ganz schlecht):

<head> <link rel="stylesheet" type="text/css" href="stylesheet1.css" /> <script type="text/javascript" src="scriptfile1.js" /> <script type="text/javascript" src="scriptfile2.js" /> <link rel="stylesheet" type="text/css" href="stylesheet2.css" /> <link rel="stylesheet" type="text/css" href="stylesheet3.css" /> </head>

Hier wird der Download der Dateien stylesheet2.css und stylesheet3.css blockiert, weil die JS-Dateien dazwischen den HTML-Baum verändern könnten.

Beispiel (auch schlecht):

<head> <link rel="stylesheet" type="text/css" href="stylesheet1.css" /> <script type="text/javascript">  document.write("Hello world!"); </script> <link rel="stylesheet" type="text/css" href="stylesheet2.css" /> <link rel="stylesheet" type="text/css" href="stylesheet3.css" /> </head>

Zuerst wird die Ausführung des Inline-Style-Befehls durch stylesheet1.css verzögert. Anschließend verhindert die Inline-Anweisung wiederum, dass die Stylesheets parallel heruntergeladen werden können.

Beispiel (gut):

<head> <link rel="stylesheet" type="text/css" href="stylesheet1.css" /> <link rel="stylesheet" type="text/css" href="stylesheet2.css" /> <link rel="stylesheet" type="text/css" href="stylesheet3.css" /> <script type="text/javascript">    document.write("Hello world!"); </script> </head>

Zuerst alle externen Ressourcen einbinden. Alle werden parallel heruntergeladen. Anschließend das Inline-Script. Natürlich sollte das JavaScript möglichst weit unten in den Body geschrieben werden, da es genauso das Laden von Bildern verzögert.
Alle Beispiele stammen von hier.

Folgende Tipps kann ich demzufolge geben:

  • alle CSS-Datei-Referenzierungen per <link>-tag in den <head> direkt hintereinander schreiben
  • alle <script>-Tags direkt vor </body> (wenn möglich)
  • möglichst keine JS-Anweisungen (inline oder extern) zwischen CSS-Referenzierungen
  • keine JS-Inline-Anweisungen zwischen mehreren Referenzierungen auf JS-Dateien

Interessant in diesem Zusammenhang ist auch der Beitrag von Rakesh Pai namens Download JavaScript Files in Parallel. Er geht dabei auf das HTML-Attribut defer ein, das schon lange im Internet Explorer und seit Version 3.1 auch im Firefox implementiert ist. Damit umgeht man die Blockierung anderer Ressourcen durch JavaScript, da das defer einfach dem Browser mitteilt, dass das Script nicht sofort geladen werden muss, sondern erst, wenn der gesamte Body geladen ist. Dadurch brauchen dann andere Ressourcen nämlich auch nicht blockiert zu werden. Dadurch bräuchten die JS-Referenzierungen dann auch nicht mehr zwingend ganz am Ende des Bodys stehen.

javascript

24.09.2019 06:37:48

Vom Kleinen aufs Große schließen

Jede Operation in MySQL (wie überall anders auch) kostet etwas Zeit. In der Praxis ist die Antwortzeit eines der wichtigsten Kriterien für Software. Um so mehr sollte man schauen, dass man die Abfragen optimiert, wo es nur geht.

Wenn die Tabellen ihrer Datenbank normalisiert sind, benötigt man für eine Abfrage oft Joins. Oft benötigt man allerdings nicht alle Datensätze einer Tabelle sondern schränkt die Ergebnismenge über LIMIT ein. Wie sollte nun vorgegangen werden, damit eine solche Operation möglichst fix geht?

Vieles kann man über Indizes lösen, allerdings gibt es manchmal einen einfacheren Weg: Wir gehen einfach so vor, wie ein Mensch vorgehen würde beim „Joinen“.

Beispielauftrag: Finden sie die 10 Artikel aus unserem Shop, die am häufigsten angeklickt wurden. Holen sie neben dem Namen des Artikels auch ein Artikelbild (zu jedem Artikel kann es 0 bis unendlich geben) und die Kategorie (ein Artikel hat genau eine Kategorie). Wir haben also 3 Tabellen: Artikel, Bilder und Kategorien.

Man könnte nun diese Query anwenden:

SELECT name,bildID,kategoriename  FROM artikel  INNER JOIN kategorien ON artikel.kategorien_ID=kategorien.ID  LEFT JOIN bilder ON artikel.ID=bilder.artikel_ID  GROUP BY artikel.ID  ORDER BY klicks DESC LIMIT 10

Der Left JOIN ist nötig, da wir auch Artikel haben, die kein Bild haben und die müssen ja auch berücksichtigt werden. Das GROUP BY ist wichtig, da wir Artikel mit mehreren Bildern haben, wir aber nur einen Datensatz pro Artikel erhalten wollen (und nicht den gleichen Artikel mit unterschiedlichen Bildern).
Was muss das DBMS nun tun? Es muss alle Datensätze der einzelnen Tabellen laut den Bedingungen verknüpfen zu einer temporären Zwischentabelle. Anschließend werden alle Datensätze nach Klicks sortiert und nach der Anzeigen-ID gruppiert. Und erst dann werden die 10 Artikel genommen mit den meisten Klicks. Die restlichen Tausenden Einträge, die mühsam gejoint und sortiert wurden, sind überflüssig. Sollte man unnötige Dinge machen lassen?? Natürlich nicht.

Wie also würde ein Mensch vorgehen, wenn er diese 3 Tabellen vor sich hätte? Er würde sich zuerst die 10 Artikel mit den meisten Klicks suchen und anschließend nur zu diesen 10 Kategorie und Bilder joinen.

SELECT name,bildID,kategoriename FROM  (SELECT name,ID,kategorien_ID FROM artikel   ORDER BY klicks DESC LIMIT 10) t INNER JOIN kategorien ON t.kategorien_ID=kategorien.ID  LEFT JOIN bilder ON t.ID=bilder.artikel_ID  GROUP BY t.ID ORDER BY NULL

Nun wird das gleiche Ergebnis ausgegeben, aber in meinem Beispiel (ich hatte noch eine zusätzliche Where-Bedingung) hat es eine Beschleunigung von ca 5 Sekunden auf 0,1 Sekunden gebracht. Das ORDER BY NULL ist übrigens nötig, damit MySQL die Reihenfolge des Ergebnisses der Subquery nicht mehr verwirft, sondern so beibehält, die die Datensätze aus der Subquery zurückkommen.

Wichtig zu erwähnen ist sicherlich noch, dass für diese Art der Optimierung der Einsatz von Subqueries möglich sein muss. Das ist bei MySQL ab Version 4 der Fall.

datenbank

24.09.2019 06:37:26

Auslesen der zuletzt eingefügten ID (auto increment)

Recht häufig benötigt man nach einer INSERT-Operation auf eine Tabelle mit einer automatisch inkrementierten ID als Primärschlüssel den durch diese Operation erzeugten Auto-Increment-Wert. Beispielsweise dafür, um anschließend weitere Operationen mit diesem Datensatz vorzunehmen oder die ID in anderen Tabellen als Fremdschlüssel zu verwenden. Zwei unterschiedliche Wege diese ID herauszufinden sollen in diesem Beitrag verglichen werden.

Denis hat vor einiger Zeit in den Themenvorschlägen vorgeschlagen, dieses Thema einmal näher zu untersuchen und dabei folgende zwei Wege vorgeschlagen.

1. Per SQL-Abfrage
Hierbei wird nach der INSERT-Query noch eine weitere Query an MySQL abgesendet, die einen Datensatz zurückgibt, der allein die ID enthält:

mysql_query("INSERT INTO tabelle (spalte1,spalte2,...) VALUES ('wert1','wert2',...)"); $rs = mysql_query("SELECT LAST_INSERT_ID()"); $id = mysql_result($rs,0);

2. Per PHP
Eine andere Möglichkeit ist die Abfrage durch PHP erledigen zu lassen. Dies geschieht über den Befehl mysql_insert_id().

mysql_query("INSERT INTO tabelle (spalte1,spalte2,...) VALUES ('wert1','wert2',...)"); $id = mysql_insert_id();

Grundsätzlich erzeugen beide Varianten also gleiche Lösungen. Es fällt aber auf, dass man im Fall 1 zusätzlich noch das Result Set auslesen muss, um an den Wert zu gelangen.
Die Ergebnisse sehen aber folgendermaßen aus:

Datei Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
result_mysql_insert_id.php 6.168871 s 6.169 ms 100 %
result_last_insert_id.php 6.178885 s 6.179 ms 100 %

Es ist zu erkennen, dass beide Varianten gleich schnell sind. Hinsichtlich der Performance gibt es also keine Unterschiede.
Die Gründe kann ich nicht 100%ig verifizieren, jedoch könnte ich mir vorstellen, dass mysql_insert_id() intern exakt die gleiche SQL-Abfrage ausführt und letzten Endes bei beiden Wegen exakt dasselbe getan wird.
Ich werde weiterhin mysql_insert_id() bevorzugen, weil man dafür einfach eine Zeile weniger benötigt, aber das sei jedem selbst überlassen. Wer nach Lines of Code bezahlt wird, sollte natürlich LAST_INSERT_ID() abfragen ????

Die verwendeten Scripte und die Ergebnisse gibts natürlich zum Download.

Das war also mal ein Beitrag, der euch nicht dazu bringen wird, gleich alle Scripte zu überarbeiten. Ich hoffe aber trotzdem, dass er informativ ist und ihr euch zukünftig nicht mehr den Kopf zerbrechen müsst. ????

datenbank

24.09.2019 06:37:17

Event-getriebene Systeme, Teil 1

In klassischen Anwendungen mit normalisierter Datenbank wird für Entitäten stets deren aktueller Zustand gespeichert. Das bedeutet im Umkehrschluss, dass der alte Zustand stets zugunsten des neuen überschrieben wird.
Im Gegensatz dazu gibt es event-getriebene Systeme (event sourced systems), bei denen nur Domain-Events, also die Datenänderung von Entitäten, gespeichert werden, nicht die tatsächlichen Werte von Entitäten. Dies kann durchaus Vorteile bezüglich der Flexibilität gegenüber zukünftigen Änderungswünschen haben. Dieser Beitrag erklärt, wie ein eventgetriebenes System funktioniert und welche Vor- und Nachteile es bietet.

Eventgetriebenes System am Beispiel erklärt

Beispiel: Wir haben ein User-Objekt (= Entität) mit den Feldern ID, username, password, email.
Zur Speicherung der Events, die User-Attribute verändern, nutzen wir eine relationale Datenbank mit der Tabelle „user-events“:

CREATE TABLE `user-events` (  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,  `user_id` INT(10) UNSIGNED NOT NULL,  `field` VARCHAR(255) NOT NULL,  `value` VARCHAR(255) NOT NULL,  PRIMARY KEY (`id`),  KEY `user_id` (`user_id`) )

Angenommen unsere Beispiel-Anwendung bietet die Möglichkeit einen Nutzer über die Oberfläche anzulegen. Dazu werden einfach in die Tabelle user-events die Änderungen hinzugefügt:

id user_id field value time
1 1 username Hans 2015-01-01 12:00
2 1 password abcde 2015-01-01 12:00
3 1 email hans@example.org 2015-01-01 12:00

Wenn in der Zwischenzeit Daten geändert werden, wird einfach die Datenänderung hinzugefügt:

id user_id field value time
1 1 username Hans 2015-01-01 12:00
2 1 password abcde 2015-01-01 12:00
3 1 email hans@example.org 2015-01-01 12:00
4 1 email hansi@domain.com 2015-01-02 10:00

In einer anderen Funktion unserer Beispiel-Anwendung soll ein Newsletter an die Nutzer verschickt werden. Dazu werden die aktuellen Daten jedes Nutzers benötigt.
Das kann z.B. folgendermaßen umgesetzt werden:
Es gibt ein UserRepository, das an den Controller „SendNewsletter“ per Dependency Injection übergeben wird. Dieses Repository enthält die Methode findAllUsers(), die alle dem System bekannten Nutzer in Form von User-Objekten mit den aktuellen Usernamen und E-Mail-Adressen zurückliefert. Diese User-Objekte kann der Controller „SendNewsletter“ dann weiter verarbeiten.
Zur Erklärung ist hier der (unvollständige) Code der UserRepository-Klasse:

class UserRepository {   public function findAllUsers() {     $sql = "SELECT evt.user_ID, evt.field, evt.value              FROM (                 SELECT MAX(ID) AS maxID                 FROM `user-events`                 GROUP BY user_id, field             ) AS newest              INNER JOIN `user-events` evt ON newest.maxID=evt.ID";       $users = [];     foreach ($this->dbh->query($sql) as $row) {       if(!isset($users[$row['user_ID']])) {         $users[$row['user_ID']] = new User();       }         $users[$row['user_ID']]->$row['field'] = $row['value'];     }       return $users;   } }

Wir können demzufolge den aktuellen Stand der User-Objekte aus den aufgezeichneten Events jederzeit wiederherstellen.

Vorteil: Flexibilität für neue Funktionen

Irgendwann kommt nun der Product Owner auf die Idee, eine Hinweismeldung einzublenden für Nutzer, die Ihr Passwort in den letzten 3 Monaten nicht geändert haben. Kein Problem, denn wir haben ja die Events gespeichert und wissen, wann jeder User zuletzt sein Passwort geändert hat. Hätten wir nur die einzelnen User-Attribute username, password und email in der Datenbank gespeichert, hätten wir schon hier ein Problem, da der Zeitpunkt der letzten Passwortänderung nicht aufgezeichnet wurde.

An einem anderen Tag möchte der Product Owner eine Übersicht aller Nutzer, die irgendwann mal eine E-Mail-Adresse mit der Endung @example.org angegeben hatten. Kein Problem, denn wir haben ja die komplette Historie. Mit einem klassischen Datenbankschema mit den Spalten username, password und email hätten wir auch hier ein unlösbares Problem, da die Informationen mit jeder Änderung überschrieben werden.

Vorteil: Nachvollziehbarkeit

Ein weiterer Vorteil ist, dass in einem event-gesteuerten System ganz einfach nachvollzogen werden kann, was passiert ist, damit der aktuelle Zustand eingetreten ist. Ein Audit Log ist also fest in das Konzept eingebaut.
Im Umkehrschluss kann ein eventgesteuertes System auch ganz einfach in den Zustand zu einem gegebenen Zeitpunkt wiederhergestellt werden, indem man die Events nur bis zu diesem Zeitpunkt berücksichtigt, wenn die Entitäts-Ojekte erstellt werden.

Faktisch ist das Speichern der einzelnen Events nichts Neues: Zum Beispiel in der Buchhaltung werden alle Geldein- und -ausgänge einzeln aufgezeichnet, sodass man jederzeit nachvollziehen kann, wie sich eine bestimmte Gesamtsumme ergeben hat. Auch im Bankwesen ist dies so: Es werden alle Transaktionen aufgezeichnet, die zum aktuellen Kontostand geführt haben.
Man kann aber eben nicht nur Geldtransaktionen in dieser Art abbilden sondern alle Zustandsänderungen. Ein anderes klassisches Beispiel ist ein Warenkorb. In einem eventgetriebenen System werden die einzelnen Transaktionen aufgezeichnet: Produkt 1 hinzugefügt, Produkt 2 hinzugefügt, Produkt 1 gelöscht. Und wenn man alle Events wieder abspielt, erhält man einen Warenkorb, in dem nur Produkt 2 liegt.

Der entscheidende Unterschied einer event-getriebenen Models gegenüber einem klassischen CRUD-Ansatz ist, dass man nie von Anfang an alle Funktionalitäten kennen kann, die sich in Zukunft mal jemand wünschen wird. Wenn aber jede Änderung des Systems aufgezeichnet wird und man nichts überschreibt oder gar löscht, können neue Funktionen jederzeit auch für Daten-Änderungen aus der Vergangenheit bereit gestellt werden.

Nachteile

Als erstes fällt natürlich auf, dass die Datenbank durch das Aufzeichnen aller Events wesentlich größer wird als bei einem CRUD-System. Ein wirklicher Nachteil ist das aber nicht, da die Daten ja nicht umsonst gespeichert werden, sondern ggf. früher oder später nochmal gebraucht werden.

Natürlich erkauft man sich die gewonnene Flexibilität mit der Auflösung der referenziellen Integrität in der Datenbank (denn Fremdschlüssel sind natürlich in diesem Fall nicht möglich).
Aber an dieser Stelle muss man sich überlegen, wozu eine Datenbank in einer Anwendung eigentlich dient: Sie ist ein Persistenzsystem, mit dem man Daten zwischen mehreren Aufrufen speichern und daraus Objekte wiederherstellen können soll. Welche Werte für bestimmte Datenbankfelder erlaubt sind, ist aber eine Business Rule, also Geschäfts-Logik. Demzufolge sind auch Fremdschlüssel eine Art Logik – und die hat in der Datenbank eigentlich nichts zu suchen.
Die Business Rules werden innerhalb der Anwendung umgesetzt und zwar entweder in den Setter-Methoden der Entitäts-Objekte oder über Value Objects, wobei Value Objects zu bevorzugen sind, da dadurch die Setter-Methode sich auf Ihre Single Responsibility – nämlich das Speichern des übergebenen Parameters – konzentrieren kann, während das Value Object sich um seine Single Responsibility – nämlich das Validieren eines Wertes gegenüber einer Regel – kümmern kann.

Fazit

Event-getriebene Systeme sind eine gute Alternative zum klassischen CRUD-Ansatz bei Anwendungen, bei denen sich Daten über die Zeit ändern und bei denen die Anforderungen nicht von Anfang an zu 100% feststehen bzw. bei denen neue Anforderungen später hinzukommen könnten. Für Anwendungen mit reiner Datenhaltung reicht hingegen ein CRUD-System aus.

PS: Faktisch habe ich in diesem User-Beispiel ein wenig getrickst, da ich die Datenänderungen aufgezeichnet habe und nicht die Events, die zu den Datenänderungen geführt haben. Aber dazu mehr im nächsten Beitrag…

datenbank