Solider Rahmen Framework-Designprinzipien David Tanzer [email protected] http://davidtanzer.net Solider Rahmen – David Tanzer Copyright © 2012 David Tanzer 1 Framework Design [email protected] Framework? Library? Framework/Library Egal Code, den andere verwenden „Unbekannte“ Nutzer 5 Kriterien / Themenbereiche → 2 „große“ → detaillierter → 3 „kleinere“ Lesbarkeit Working Memory Capacity „Arbeitsspeicher“ begrenzt Kurzlebig Ablenkugen vs. Konzentration 3-5 3-5 Einträge im Arbeitsspeicher Mehr Kapazität durch Blockbildung Sensory Data Sensory Data Sensory Memory Sensory Data Working Memory Sensory Memory Sensory Data Working Memory Sensory Memory Long-term Memory Blöcke bilden helfen! „Nachladen“ aus Langzeitgedächtnis minimieren! Parameterlisten new User( „David“, „Tanzer“, „[email protected]“, „secret“, Roles.USER); Method Chaining add(new Label("id") .setMarkupId("mid") .setVisible(true) .setEnabled(false) ); Wicket public void setId( String id) { this.id = id; } Component public void setId( String id) { this.id = id; } Component public void setId( String id) { this.id = id; return this; } Abgeleitete Klassen? Benannte Parameter Oder zumindest Objekt-Initialisierung (properties)? persistUser( new User(){{ userName="david"; password="secret"; }}); Double Brace Initialization Probleme? Equals! collection copyFrom: 1 to: 10 Smalltalk „Methode“: copyFrom:to: SRP Single Responsibility Principle Jede Einheit (Klasse) ist nur für genau eine Sache zuständig Für eine Einheit (Klasse) gibt es nur einen Grund, diese zu ändern Kurze Klassen! Einfacher zu verstehen / lesen SLA Single Level of Abstraction Alle Anweisungen einer Methode sind auf dem selben Abstraktionsgrad Kurze Methoden! Einfacher zu verstehen/lesen readFile() { //open file, init //read lines //parse read data //close file //handle errors } 2 - Anwenderfreundlichkeit Anwenderfreundlichkeit „Schreibbarkeit“ vgl. „Lesbarkeit“ DRY Don't repeat yourself myactivity.xml <Button android:id= "@+id/button" /> Android Wicket: Ähnliches Problem ID muss systemweit eindeutig sein! myactivity.xml <Button android:id= "@+id/button" n o t t u b _ y t /> i v i t c mya Android myactivity.xml <Button android:id= "@+id/button" n o t t u b _ y t /> i v i t c mya Android MyActivity.java setContentView( R.layout.myactivity); MyActivity.java setContentView( R.layout.myactivity); Button button = (Button)findViewById( R.id. myactivity_button); Java T t = new T(); Java T t = new T(); Go t := new(T) Auto Complete Niemand liest die Doku Niemand will sich Methodenlisten merken Working Memory Capacity! query.setP JPA query.setP get JSXP2 (alt) Zugriff auf Element: getElement<Name>() get el. JSXP2 (neu) +Methoden aus java.lang.Object Fehler finden Fehlerfindung für Anwender vereinfachen! Java: Statisch typisierte Sprache Viele Infos zur Übersetzungszeit verfügbar → Compiler hat diese „Erwartungen“ an das Programm → so formulieren, dass Compiler sie versteht Java! Erwartungen in Java formulieren! (oder C#, C++, …) → Code generieren myactivity.activity.xml <Button android:id= „@+id/button“/> resdroid Einfaches Resourcen-Handling für Android myactivity.activity.xml myactivity_activity.xml <Button android:id= „@+id/myactivity_ button“ resdroid myactivity.activity.xml MyactivityActivityBase protected Button button; resdroid MyactivityActivityBase MyactivityActivity button. setOnClickListener( …); resdroid Code Generieren: Nicht die einzige Möglichkeit, bei der Fehlersuche zu unterstützen Testbarkeit → Einfachheit, Mocks zu verwenden → Dependency Injection unterstützen 3 - Dichtheit „Dichtheit“ „Law of leaky abstractions“ „All non-trivial abstractions, to some degree, are leaky.“ Abstraktion nicht perfekt → Der abstrahierte Gegenstand „tropft“ durch Wissen über Abstraktion UND abstrahierten Gegenstand notwendig setOutputMarkup PlaceholderTag (boolean) Wicket Verstehen dieser Methode: Wissen über Ajax, JS und HTTP notwendig mock.Setup( foo => foo.DoSomething( It.IsAny<string>()) ).Returns(true); moq – Mocking Framework für .NET Intellisense für Methoden durch Lambda mock.Protected() .Setup<int> ("Execute") .Returns(5); Protected-Methoden: Identifiziert über Strings kein Intellisense! nicht Refactoring-safe! Warum? → Spezifika des .NET-Framework 4 - Erweiterbarkeit Erweiterbarkeit Einfachheit SLA – Single Level of Abstraction SRP – Single Responsibility Principle ISP – Interface Segregation Principle IOC Inversion of Control z.B. Dependency Injection „Dichtheit“ verletzen getRequest() Wicket getRequest(). getContainerRequest() Context.get() .getRequest() JSXP2 Weitere Möglichkeit: Lambda, Closures → Beispiel Accumulator Generator Schreiben Sie eine Funktion, die - Eine Zahl n als Parameter bekommt - Als Ergebnis eine Funktion hat, die n um eine Zahl i inkrementiert (defun foo (n) (lambda (i) (incf n i))) Common Lisp Closure (lexical variable) function foo(n) { return function(i) { return n += i; } } Javascript Java? Nicht (vernünftig) lösbar! Was hat das mit Erweiterbarkeit zu tun? function map(fn, a) { for(i=0;i<a.length; i++) { a[i]=fn(a[i]); } } function reduce(fn, a, init) { var r=init; for(i=0;i<a.length; i++) r = fn(r, a[i]); return r; } MapReduce Verarbeiten großer Datenmengen Google! Parallelisierbar 5 - Knappheit Knappheit „Succinctness is Power“ Wicket: → 3 XHTML-Dateien → 3 Java-Klassen (+ inner classes) (defop said req (aform [onlink "click here" (pr "you said: " (arg _ "foo"))] (input "foo") (submit))) Working Memory Capacity! Programmierer muss Programm „laden“ → sich genügend Details merken, um weiterarbeiten zu können → kürzer = einfacher Codezeilen / Stunde Unabhängig von Programmiersprache Fehler / Codezeile Fehlersuche Kürzeres Programm: Weniger Zeilen können von Fehler betroffen sein while file.gets print if \ ~/third/ \ .. ~/fifth/ end Ruby Kürze nicht immer gut Hier: „versteckte“ Funktionalität Geschmackssache? file.gets speichert => „$_“ „~“ matched „$_“ while line=file.gets puts line \ if line=~/third/ \ .. line=~/fifth/ end Ruby Themen waren: → Lesbarkeit → Anwenderfreundlichkeit („Schreibbarkeit“) → Dichtheit → Erweiterbarkeit → Knappheit Fragen? Vielen Dank! [email protected] Solider Rahmen – David Tanzer Copyright © 2012 David Tanzer 94 Links „Law of leaky abstractions“: http://www.joelonsoftware.com/articles/LeakyAbstractions.html „Succinctness is Power“: http://www.paulgraham.com/power.html „Revenge of the Nerds“: http://paulgraham.com/icad.html „Can Your Programming Language Do This“: http://www.joelonsoftware.com/items/2006/08/01.html „Four-fold Increase in Productivity and Quality“: http://www.erlang.se/publications/Ulf_Wiger.pdf „Partial Classes helfen dem SLA“: http://ralfw.blogspot.com/2009/07/partial-classes-helfen-dem-single-level.html Frameworks / Libraries Wicket: http://wicket.apache.org resdroid: http://davidtanzer.net/resdroid, https://github.com/dtanzer/resdroid JSXP: http://jsxp.org Jiowa Webview: http://jiowa.de/produkte/jiowa-webview-technology.html moq: http://code.google.com/p/moq/ Erlaubnis d. Fotografen liegt vor „Man Standing with Four Paths to Choose“ Fotograf: Eyetoeye Design http://www.istockphoto.com/ stock-photo-18244228-man-standing-with-four-paths-to-choose.php Erlaubnis d. Fotografen liegt vor „puzzle“ Fotograf: Muharrem Oner http://www.istockphoto.com/stock-photo-19133767-puzzle.php „Businessman falling“ Fotograf: James Group Studios „Files in a archive“ Fotograf: Alex Nikada http://www.istockphoto.com/ stock-photo-16822421-files-in-a-archive.php http://www.istockphoto.com/ stock-photo-6090065-businessman-falling.php „Toxic Waste“ Fotograf: Pictureworld / Photodiem http://www.istockphoto.com/stock-photo-18776438-toxic-waste.php Fotograf: David Tanzer „Missing Cube“ Fotograf: kyoshino http://www.istockphoto.com/ stock-photo-14165473-missing-cube.php „Taxes evasion“ Fotograf: aluxum http://www.istockphoto.com/ stock-photo-16212643-taxes-evasion.php Fotografin: Beate Tanzer Fotograf: David Tanzer Fotografin: Beate Tanzer Fotograf: David Tanzer Fotograf: David Tanzer