Ein spannendes Interview mit Stefan Lieser von der Initiative „Clean Code Developer“ gibt es in der einhundertzweiten Episode des Anwendungsentwickler-Podcasts.
Podcast: Play in new window | Download (Duration: 1:07:13 — 24.4MB)
Abonnieren: Apple Podcasts | Spotify | RSS
Inhalt
Hier sind einige der Fragen, die wir im Laufe des Gesprächs durchgegangen sind:
- Wie ist dein Name und wo arbeitest du (falls gewünscht)?
- Wie bist du zur Informatik bzw. Softwareentwicklung gekommen?
- Welche Ausbildung bzw. welches Studium hast du im Bereich der Informatik absolviert?
- Mit welcher/n Programmiersprache/n arbeitest du im Alltag?
- Was ist deine Lieblingsprogrammiersprache und warum?
- Bildest du selbst Entwickler-Nachwuchs aus und wenn ja, wie ist das Vorgehen?
- Was ist das letzte Fachbuch mit Bezug zur Programmierung, das du gelesen hast?
- Was ist dein absolutes Lieblingsbuch mit Bezug zur Programmierung und warum?
- Welche Quellen kannst du für die Aus- und Weiterbildung im Bereich Programmierung empfehlen und warum?
- Wer braucht Microservices?
- Wie sollte man beim Entwurf einer Software vorgehen? Welche Modellierungswerkzeuge sollte man einsetzen?
- Was ist Flow Design?
- Was ist die Initiative „Clean Code Developer“?
- Was ist der Sinn des CCD-Armbandes?
- Welches Prinzip findest du am wichtigsten bzw. welches bietet den größten Mehrwert?
- Welche Praktik findest du am wichtigsten bzw. welche bietet den größten Mehrwert?
- Werden die Ideen hinter CCD deiner Erfahrung nach schon großflächig in den Unternehmen eingesetzt oder ist hier noch viel Aufklärungs-/Überzeugungsarbeit zu leisten?
- Sollten bereits Auszubildende/Studenten mit CCD anfangen oder ist das eher etwas für „fertige“ Entwickler/-innen?
- Wie können auch Azubis/Studenten schon CCD in ihren Alltag integrieren bzw. womit sollten sie beginnen?
- Was können (gerade junge) Entwickler/-innen tun, wenn ihr Unternehmen die Ideen hinter CCD nicht unterstützt?
- Muss CCD in Unternehmen immer „von oben“ mitgetragen werden oder können Entwickler auch selbst damit anfangen?
- Wo kann man mehr über CCD erfahren? Gibt es z.B. Kurse, Bücher, Konferenzen usw.?
- Wo können die Hörer mehr über dich erfahren bzw. dich kontaktieren?
Literaturempfehlungen
- Auf Clean Code* basiert eigentlich das gesamte Gespräch mit Stefan. Daher darf es natürlich nicht auf der Buchliste fehlen!
* - Außerdem hat Stefan noch Refactoring* empfohlen, um „alten“ Code Schritt für Schritt besser zu machen.
* - Um dabei gleich in Richtung etablierter Patterns zu arbeiten, ist noch Refactoring to Patterns* zu empfehlen.
* - Und ein weiterer Klassiker, den ich persönlich auch jedem Entwickler empfehlen kann, wurde auch genannt: Working Effectively with Legacy Code*.
*
Links
- Permalink zu dieser Podcast-Episode
- RSS-Feed des Podcasts
- Die Initiative „Clean Code Developer“
- Trainings & Beratung rund um Clean Code Development sowie Übungsaufgaben
- Refactoring von Legacy Code
- Kostenloser Online Kurs zum Thema Unit Tests mit NUnit, über 2h Videos
- Cheatsheet zu Flow Design
Hi Stefan,
Ich hab einen scheinbaren Widerspruch entdeckt, zwischen den Vorstellungen in OOP und den Dependency Injection.
In Ihrem Audiocast zum Thema OOP gehen Sie auf die Notwendigkeit ein, dass instanzierte Objekte immer gültige Membervariablen ( genauer Begriff fehlt mir im Moment ) haben müssen. Konkret ging es darum NULL-Exceptions zu verhindern in den man ungültige Werte im Objekt hat.
Mein Beispiel: Datenbank-Klasse
Nun steh ich vor einem Problem. Wenn ich vorab alles im Konstruktor organisiere, kann ich im erzeugten Objekt gleich meine SQL-Anfrage beim instanzieren übergeben. Im Objekt sind damit keine ungültigen Membervariablen.
Wenn ich aber das Dependency Injection anwenden möchte und mein Objekt außerhalb erzeuge, so kann ich die SQL-Anfrage nicht schon bei der Instanzierung mitgeben, denn ich will ja das Datenbank-Objekt dem Konstruktor einer Anderen Klasse ( z.b. Worker ) übegeben, die mit dem Datenbank-Objekt arbeiten soll.
Jetzt ist es notwendig in der Datenbankklasse, statt im Konstruktor eine eigen Methode zu definieren, die das SQL-Statement entgegennimmt. Damit hab ich aber ein Ungültiges Objekt erzeugt, bevor es in meiner Worker-Klasse verwendet wird.
Hab ich hier eine grundsätzlichen Denkfehler? 🙂
Hallo Marcel,
warum bekommt deine Datenbank-Klasse denn EINE SQL-Abfrage übergeben? Diese Frage würde ich mir stellen. Denn dann ist sie ja nicht wiederverwendbar. Ich würde – ohne deinen Code zu kennen – erwarten, dass die Klasse beliebige Statements entgegennehmen und ausführen kann. Und dann dürften diese gar nicht in Instanzvariablen abgelegt werden, sondern sind nur während des Methodenaufrufs als Parameter gültig.
Aber selbst in deinem Fall könntest du doch die Datenbank-Klasse mit dem SQL-String erzeugen (gültig) und dann das Objekt als Parameter im Konstruktur an die Klasse weitergeben, die es nutzen soll. Die Instantiierungsreihenfolge dreht sich nur um: SQL -> DB-Objekt -> Fachobjekt.
Viele Grüße!
Stefan
Ich glaub ich bin da weniger Methodisch herran gegangen sondern mehr praktisch oder besser bequem, was den Code anging. Ich wollte halt so wenig wie möglich schreiben um eine Datenbankabfrage mit SQL zu erledigen. Ich nutze in PHP PDO, was selbst schon eine Klasse ist. Hier wird bzw. kann auch ein Objekt erzeugt werden. Mir was das ganze drumrum einfach zu viel, also Parameter setzen und immer wieder das gleiche ausführen bevor die eigentlich eAbfrage kommt. Mein Grundgedanke in dem Moment, wo ich die Klasse erstellt hab war „was kann ich die Klasse machen lassen und was brauch ich maximal für meine Standardabfragen“ Da blieb dann nurnoch der SQL-String und die optionale Parameterliste ( für Prepare Statements ) übrig.
Ich les aber schon aus Deiner Antwort raus, dass ich sowieso meinen grundsätzlichen Denkansatz falsch betrachtet hab. Alternativ zur Instanzierung ist es also besser die Klasse bzw Ihre Methoden statisch aufzurufen?
In der „Worker“-Klasse entsteht natürlich erst der String als SQL-Statment.
Welche Vorgehensweise würdest Du vorschlagen um vorab zu untersuchen was und ob etwas in einen Konstruktor kommt. So genommen wäre es scheinbar besser Nichts in den Konstruktor zu lassen, wenn man nie weiss, ob man die daraus ein Objekt erzeugt, dass man von außen einer anderen Klasse übergeben will.
Praxis:
Ich fand das hier bisher grad recht übersichtlich. ( Innerhalb von Worker )
$db = new DBService( „SELECT * FROM hallo“ );
print_r( $db -> getResult() );
Ansonsten wäre es immer so, Ohne Konstruktor:
$db = new DBService();
print_r ( $db -> getResult( „SELECT * FROM hallo“ ) ) ;
oder:
$db = new DBService();
$db -> stm( „SELECT * FROM hallo“ );
print_r ( $db -> getResult() ) ;
Vielen Dank für Ihre Rückmeldung! Obwohl alles irgendwie funktioniert hab ich das Gefühl ich stecke noch voll am Anfang fest. 🙂
Ach so, fast vergessen. Es ist nur EINE SQL-Abfrage, da ich das Objekt immer wieder für jede Abfrage neu erzeugt hatte. Ich hab mir da wohl mal was abgeschaut aus C#.
Allg. sollte ich noch sagen, das ich über sehr viele Jahre nur Prozedural und Mit Funktionen Programmiert hatte. Das hat mich sehr sehr viele Jahre ( über 25 ) geprägt. Ich lernen zwar gut das „Wie“ bei OOP aber mir fehlt oft das „Warum“
Version 2 würde ich bevorzugen. DB-Objekt einmal erstellen (und dann z.B. im Test durch ein Mock-Objekt ersetzen) und SQL bei jeder Abfrage mitgeben. Wenn es immer derselbe String ist, kannst du den ja in der Worker-Klasse als Attribut/Konstante ablegen. Aber auch das ist eigentlich doof. Warum muss deine Worker-Klasse SQL zusammenbauen? Die Domäne sollte von der Datenbank gar nichts wissen. Besser:
HalloLeser
mit ImplementierungDbHalloLeser
, die MethodefindeAlleHallos()
anbietet.DbHalloLeser
enthält SQL und DB-Kram.HalloLeser
im Konstruktor rein -> im Test einen Mock.$leser->findeAlleHallos()
auf ohne zu wissen, dass das gegen die Datenbank geht.