SlideShare ist ein Scribd-Unternehmen logo
SOLID PRINCIPLES
Designgrundlagen objektorientierter Systeme
–Fred Brooks, The Mythical Man Month (Jänner 1975)
„All successful software gets changed.“
JPA
lokale Beans
ohne Interface
alles Remote
CDI
konkrete CMPs
abstrakte CMPs
Java Server Pages
Java Server Faces
MVC 1.0
JPA
lokale Beans
ohne Interface
alles Remote
CDI
konkrete CMPs
abstrakte CMPs
Java Server Pages
Java Server Faces
MVC 1.0Technologie darf
dem Design nicht
im Weg stehen!
The Single Responsibility Principle
A class should have only one reason to change.
Ein Anwendungsfall
public void erstelleProjekt(String projektName, String projektManager) {
if (projektName == null || "".equals(projektName)) {
throw new IllegalArgumentException("argument projektName darf nicht null oder leer sein");
}
if (projektManager == null || "".equals(projektManager)) {
throw new IllegalArgumentException("argument projektManager darf nicht null oder leer sein");
}
TypedQuery<User> query = entityManager.createQuery("select u from User u where u.name=:name", User.class);
query.setParameter("name", projektManager);
try {
User user = query.getSingleResult();
Projekt projekt = new Projekt(projektName);
projekt.setProjektManager(user);
entityManager.persist(projekt);
} catch (EntityNotFoundException e) {
throw new ProAdmException("projekt konnte nicht erstellt werden.");
}
}
Ein Anwendungsfall
public void erstelleProjekt(String projektName, String projektManager) {
if (projektName == null || "".equals(projektName)) {
throw new IllegalArgumentException("argument projektName darf nicht null oder leer sein");
}
if (projektManager == null || "".equals(projektManager)) {
throw new IllegalArgumentException("argument projektManager darf nicht null oder leer sein");
}
TypedQuery<User> query = entityManager.createQuery("select u from User u where u.name=:name", User.class);
query.setParameter("name", projektManager);
try {
User user = query.getSingleResult();
Projekt projekt = new Projekt(projektName);
projekt.setProjektManager(user);
entityManager.persist(projekt);
} catch (EntityNotFoundException e) {
throw new ProAdmException("projekt konnte nicht erstellt werden.");
}
}
Format & Fehlermeldung
Ein Anwendungsfall
@Inject
private SolidValidator validator;
public void erstelleProjekt(String projektName, String projektManager) {
validator.validateProjektName(projektName);
validator.validateProjektManagerName(projektManager);
TypedQuery<User> query = entityManager.createQuery("select u from User u where u.name=:name", User.class);
query.setParameter("name", projektManager);
try {
User user = query.getSingleResult();
Projekt projekt = new Projekt(projektName);
projekt.setProjektManager(user);
entityManager.persist(projekt);
} catch (EntityNotFoundException e) {
throw new ProAdmException("projekt konnte nicht erstellt werden.");
}
}
Ein Anwendungsfall
@Inject
private SolidValidator validator;
public void erstelleProjekt(String projektName, String projektManager) {
validator.validateProjektName(projektName);
validator.validateProjektManagerName(projektManager);
TypedQuery<User> query = entityManager.createQuery("select u from User u where u.name=:name", User.class);
query.setParameter("name", projektManager);
try {
User user = query.getSingleResult();
Projekt projekt = new Projekt(projektName);
projekt.setProjektManager(user);
entityManager.persist(projekt);
} catch (EntityNotFoundException e) {
throw new ProAdmException("projekt konnte nicht erstellt werden.");
}
}
JPA, JPA-QL & ExceptionHandling
Ein Anwendungsfall
@Inject
private SolidValidator validator;
@Inject
private BenutzerRepository users;
public void erstelleProjekt(String projektName, String projektManager) {
validator.validateProjektName(projektName);
validator.validateProjektManagerName(projektManager);
Benutzer user = users.getProjektManager(projektManager);
Projekt projekt = new Projekt(projektName);
projekt.setProjektManager(user);
entityManager.persist(projekt);
}
Ein Anwendungsfall
@Inject
private SolidValidator validator;
@Inject
private BenutzerRepository users;
public void erstelleProjekt(String projektName, String projektManager) {
validator.validateProjektName(projektName);
validator.validateProjektManagerName(projektManager);
Benutzer user = users.getProjektManager(projektManager);
Projekt projekt = new Projekt(projektName);
projekt.setProjektManager(user);
entityManager.persist(projekt);
}
falsches
Abstraktionslevel
Ein Anwendungsfall
@Inject
private SolidValidator validator;
@Inject
private BenutzerRepository users;
@Inject
private ProjektRepository projects;
public void erstelleProjekt(String projektName, String projektManager) {
validator.validateProjektName(projektName);
validator.validateProjektManagerName(projektManager);
Benutzer user = users.getProjektManager(projektManager);
Projekt projekt = new Projekt(projektName);
projekt.setProjektManager(user);
projects.saveProjekt(projekt);
}
Hinweise
Viele Methoden verwenden
das selbe
Feld?
Hinweise
Viele Methoden verwenden
das selbe
Feld?
private
Hinweise
Viele Methoden verwenden
das selbe
Feld?
Technologie &
Fachlichkeit
in derselben Klasse?
The Open/Closed Principle
Software entities should be open for extension but closed for modification.
Ein Anwendungsfall
Client Server
Ein Anwendungsfall
Client Server
Welche Methoden darf ich verwenden?
Ein Anwendungsfall
Client Server
Welche Methoden darf ich verwenden?
Welche Methoden werden eigentlich benötigt?
Ein Anwendungsfall
ClientInterfaceClient
Server
Ein Anwendungsfall
ClientInterfaceClient
Server
gehören
zusammen
Ein Anwendungsfall
ClientInterfaceClient
Server
gehören
zusammen
bestimmt die Funktion
Ein Anwendungsfall
ClientInterfaceClient
Server
gehören
zusammen
bestimmt die Funktion
closed for
modification
Ein Anwendungsfall
ClientInterfaceClient
Server
gehören
zusammen
bestimmt die Funktion
closed for
modification
open for
extension
Ein Code Beispiel
public enum Typ {
ARBEITSPAKET, MEILENSTEIN
}
…
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete){
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if(Typ.MEILENSTEIN == arbeitspaket.getTyp()){
return arbeitspaket;
}
}
return null;
}
Ein Code Beispiel
public enum Typ {
ARBEITSPAKET, MEILENSTEIN
}
…
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete){
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if(Typ.MEILENSTEIN == arbeitspaket.getTyp()){
return arbeitspaket;
}
}
return null;
}
Neue Anforderung: ProjektStart undProjektEnde, beides Meilensteine
Ein Code Beispiel
public enum Typ {
ARBEITSPAKET, MEILENSTEIN
}
…
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete){
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if(Typ.MEILENSTEIN == arbeitspaket.getTyp()){
return arbeitspaket;
}
}
return null;
}
Neue Anforderung: ProjektStart undProjektEnde, beides Meilensteine
gute Idee
Ein Code Beispiel
public enum Typ {
ARBEITSPAKET, MEILENSTEIN
}
…
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete){
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if(Typ.MEILENSTEIN == arbeitspaket.getTyp()){
return arbeitspaket;
}
}
return null;
}
Neue Anforderung: ProjektStart undProjektEnde, beides Meilensteine
gute Idee
hier ein Problem
Ein Code Beispiel
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete) {
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if (arbeitspaket.getTyp().isMeilenstein()) {
return arbeitspaket;
}
}
return null;
}
Ein Code Beispiel
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete) {
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if (arbeitspaket.getTyp().isMeilenstein()) {
return arbeitspaket;
}
}
return null;
}
public interface ArbeitspaketTyp {
boolean isMeilenstein();
boolean isArbeitspaket();
}
Ein Code Beispiel
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete) {
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if (arbeitspaket.getTyp().isMeilenstein()) {
return arbeitspaket;
}
}
return null;
}
public interface ArbeitspaketTyp {
boolean isMeilenstein();
boolean isArbeitspaket();
}
public enum Typ implements ArbeitspaketTyp{
ARBEITSPAKET {
@Override
public boolean isArbeitspaket() {
return true;
}
},
PROJEKTSTART {
@Override
public boolean isMeilenstein() {
return true;
}
},
PROJEKTENDE {
@Override
public boolean isMeilenstein() {
return true;
}
},
MEILENSTEIN {
@Override
public boolean isMeilenstein() {
return true;
}
};
public boolean isMeilenstein() {
return false;
}
public boolean isArbeitspaket() {
return false;
}
}
Ein Code Beispiel
public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete) {
for (Arbeitspaket arbeitspaket : arbeitspakete) {
if (arbeitspaket.getTyp().isMeilenstein()) {
return arbeitspaket;
}
}
return null;
}
public interface ArbeitspaketTyp {
boolean isMeilenstein();
boolean isArbeitspaket();
}
public enum Typ implements ArbeitspaketTyp{
ARBEITSPAKET {
@Override
public boolean isArbeitspaket() {
return true;
}
},
PROJEKTSTART {
@Override
public boolean isMeilenstein() {
return true;
}
},
PROJEKTENDE {
@Override
public boolean isMeilenstein() {
return true;
}
},
MEILENSTEIN {
@Override
public boolean isMeilenstein() {
return true;
}
};
public boolean isMeilenstein() {
return false;
}
public boolean isArbeitspaket() {
return false;
}
}
Closed for Modification,
Open for Extension
Hinweise
Das Hinzufügen oder Entfernen
einer Funktion muss
in vielen Klassen
nachgezogen werden.
Hinweise
Schnittstellen
entsprechen den Anforderungen
des Dienstanbieters
und nicht des Benutzers!
Das Hinzufügen oder Entfernen
einer Funktion muss
in vielen Klassen
nachgezogen werden.
The Liskov Substitution Principle
Subtypes must be substitutable for their base types
Ein Anwendungsfall
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Ein Anwendungsfall
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Neue Anforderung: Wir benötigen
eine Klasse „Meilensteine“
Der erste Versuch
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Meilenstein
Der erste Versuch
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Meilenstein
Darf Beginn- und Enddatum
eines Meilensteins
voneinander abweichen?
Darf Beginn- und Enddatum
eines Meilensteins
voneinander abweichen?
Der zweite Versuch
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Meilenstein
+setDuration(int)
Darf Beginn- und Enddatum
eines Meilensteins
voneinander abweichen?
Der zweite Versuch
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Meilenstein
+setDuration(int)
public class Meilenstein extends Arbeitspaket{
public void setDuration(int days){
throw new ProAdmException("unsupported operation.");
}
}
Darf Beginn- und Enddatum
eines Meilensteins
voneinander abweichen?
Der zweite Versuch
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Meilenstein
+setDuration(int)
public class Meilenstein extends Arbeitspaket{
public void setDuration(int days){
throw new ProAdmException("unsupported operation.");
}
}
public class Meilenstein extends Arbeitspaket{
public void setDuration(int days){
// ignore
}
}
FAIL!
Darf Beginn- und Enddatum
eines Meilensteins
voneinander abweichen?
Der zweite Versuch
Arbeitspaket
+getEndDate() : Date
+setDuration(int)
Meilenstein
+setDuration(int)
public class Meilenstein extends Arbeitspaket{
public void setDuration(int days){
throw new ProAdmException("unsupported operation.");
}
}
public class Meilenstein extends Arbeitspaket{
public void setDuration(int days){
// ignore
}
}
FAIL!
FAIL!
Der dritte Versuch
Arbeitspaket
+setDuration(int)
Meilenstein
Phase
+getEndDate() : Date
Der dritte Versuch
Arbeitspaket
+setDuration(int)
Meilenstein
Phase
+getEndDate() : Date
identisches Verhalten
Der dritte Versuch
Arbeitspaket
+setDuration(int)
Meilenstein
Phase
+getEndDate() : Date
identisches Verhalten
unterschiedliches Verhalten
Der dritte Versuch
Arbeitspaket
+setDuration(int)
Meilenstein
Phase
+getEndDate() : Date
identisches Verhalten
unterschiedliches Verhalten
Subtypes are substitutable
for their base types
Hinweise
Das Verhalten der Elternklasse(n)
führt zu Fehlern.
Hinweise
Das Verhalten der Elternklasse(n)
führt zu Fehlern.
IsA-Beziehung (extends)
zwingt mich Methoden zu
überschreiben.
The Interface Segregation Principle
Clients should not be forced to depend on methods they do not use.
Ein Anwendungsfall
Security
User
Projekt+getRoles() : Role[]
+getProjekte() : Projekt[]
Ein Anwendungsfall
Security
User
Projekt+getRoles() : Role[]
+getProjekte() : Projekt[]
unnötige Kopplung!
Ein Anwendungsfall
Security
User
Projekt+getRoles() : Role[]
+getProjekte() : Projekt[]
unnötige Kopplung!
unnötige Kopplung!
Ein Anwendungsfall
UserImpl
+getProjekte() : Projekt[]
ProjektManager
Security
User
Projekt+getRoles() : Role[]
Ein Anwendungsfall
UserImpl
+getProjekte() : Projekt[]
ProjektManager
Security
User
Projekt+getRoles() : Role[]
FAIL!
Variante 1: Interfaces
Security
User
Projekt+getRoles() : Role[]
ProjektUser
+getProjekte() : Projekt[]
ProjektManager
Variante 2: Delegierung
Security
User
Projekt
+getRoles() : Role[]
+getProjekte() : Projekt[]
ProjektManager
Variante 3: Vererbung
Security
User
Projekt
+getRoles() : Role[]
+getProjekte() : Projekt[]
ProjektManager
Hinweise
Ich muss Methoden implementieren
die in der konkreten Klasse gar
keine Funktion erfüllen.
Hinweise
Ich muss Methoden implementieren
die in der konkreten Klasse gar
keine Funktion erfüllen.
Ich muss Module importieren
die in meiner Anwendung
gar keine Funktion erfüllen.
The Dependency-Inversion Principle
High Level Modules should not depend on low-level modules. Both should
depend on abstractions.
Abstractions should not depend on details. Details should depend upon
abstractions.
Schichten
UseCase Layer
Service Layer
Utility Layer
Schichten
UseCase Layer
Service Layer
Utility Layer
High Level
„Erstelle Meilenstein“
Schichten
UseCase Layer
Service Layer
Utility Layer
High Level
„Erstelle Meilenstein“
Low Level
„SQL INSERT“
Invertierte Schichten
Service Layer
Utility Layer
UseCase
Service
Interface
Service
Interface
UseCase Layer
Invertierte Schichten
Service Layer
Utility Layer
UseCase
Service
Interface
Service
Interface
UseCase Layer
Abstractions
Invertierte Schichten
Service Layer
Utility Layer
UseCase
Service
Interface
Service
Interface
UseCase Layer
Abstractions
Details
Invertierte Schichten
Service Layer
Utility Layer
UseCase
Service
Interface
Service
Interface
UseCase Layer High
Low
Clean Architecture
High
Low
Clean Architecture
High
Lowui, db, web
Clean Architecture
High
Lowui, db, web
online, backoffice, batch
Clean Architecture
High
Lowui, db, web
online, backoffice, batch
domain services, entities
Clean Architecture
fachlich High
Lowui, db, web
online, backoffice, batch
domain services, entities
Clean Architecture
fachlich
technisch
High
Lowui, db, web
online, backoffice, batch
domain services, entities
Clean Architecture
Abhängigkeiten
fachlich
technisch
High
Lowui, db, web
online, backoffice, batch
domain services, entities
Hinweise
Ich kann
nicht Testen wenn
System X nicht zur Verfügung steht.
Hinweise
Ich kann
nicht Testen wenn
System X nicht zur Verfügung steht.
Ich kann
die Fachlichkeit
nicht erkennen und erhalten.
Vielen Dank
mario.rodler@gmx.net

Weitere ähnliche Inhalte

Andere mochten auch

Die SOLID-Prinzipien
Die SOLID-PrinzipienDie SOLID-Prinzipien
Die SOLID-Prinzipien
Trivadis
 
Trivadis TechEvent 2016 cgroups im Einsatz von Florian Feicht
Trivadis TechEvent 2016 cgroups im Einsatz von Florian FeichtTrivadis TechEvent 2016 cgroups im Einsatz von Florian Feicht
Trivadis TechEvent 2016 cgroups im Einsatz von Florian Feicht
Trivadis
 
Mit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauenMit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauen
Sven Günther
 
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
GFU Cyrus AG
 
SOLID Design Principles
SOLID Design PrinciplesSOLID Design Principles
SOLID Design Principles
Andreas Enbohm
 
6 3 tier architecture php
6 3 tier architecture php6 3 tier architecture php
6 3 tier architecture php
cefour
 
OOP Principles
OOP PrinciplesOOP Principles
OOP Principles
WebcsonsultsEU
 
The SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design PatternsThe SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design Patterns
Hayim Makabee
 

Andere mochten auch (8)

Die SOLID-Prinzipien
Die SOLID-PrinzipienDie SOLID-Prinzipien
Die SOLID-Prinzipien
 
Trivadis TechEvent 2016 cgroups im Einsatz von Florian Feicht
Trivadis TechEvent 2016 cgroups im Einsatz von Florian FeichtTrivadis TechEvent 2016 cgroups im Einsatz von Florian Feicht
Trivadis TechEvent 2016 cgroups im Einsatz von Florian Feicht
 
Mit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauenMit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauen
 
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
 
SOLID Design Principles
SOLID Design PrinciplesSOLID Design Principles
SOLID Design Principles
 
6 3 tier architecture php
6 3 tier architecture php6 3 tier architecture php
6 3 tier architecture php
 
OOP Principles
OOP PrinciplesOOP Principles
OOP Principles
 
The SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design PatternsThe SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design Patterns
 

Ähnlich wie SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
GFU Cyrus AG
 
TypeScript
TypeScriptTypeScript
TypeScript
Jens Siebert
 
Mehr Dynamik Durch Skriptsprachen
Mehr Dynamik Durch SkriptsprachenMehr Dynamik Durch Skriptsprachen
Mehr Dynamik Durch Skriptsprachenjlink
 
Workshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GAWorkshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GA
Oliver Belikan
 
Python builds mit ant
Python builds mit antPython builds mit ant
Python builds mit ant
roskakori
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPAmh0708
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfallen
inovex GmbH
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklung
jlink
 
Angular von 0 auf 100
Angular von 0 auf 100Angular von 0 auf 100
Angular von 0 auf 100
Yvette Teiken
 
Typescript
TypescriptTypescript
Typescript
Sebastian Springer
 
Warum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser machtWarum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser macht
Sebastian Springer
 
Automatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit SeleniumAutomatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit SeleniumBenjamin Schmid
 
Java Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s StapelnJava Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s Stapeln
gedoplan
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
Sebastian Springer
 
TypeScript
TypeScriptTypeScript
TypeScript
Jens Siebert
 
Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistence
gedoplan
 
Einführung in die funktionale Programmierung
Einführung in die funktionale ProgrammierungEinführung in die funktionale Programmierung
Einführung in die funktionale Programmierung
Digicomp Academy AG
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
jlink
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7
msebel
 
Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!
gedoplan
 

Ähnlich wie SOLID Prinzipien, Designgrundlagen objektorientierter Systeme (20)

Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
TypeScript
TypeScriptTypeScript
TypeScript
 
Mehr Dynamik Durch Skriptsprachen
Mehr Dynamik Durch SkriptsprachenMehr Dynamik Durch Skriptsprachen
Mehr Dynamik Durch Skriptsprachen
 
Workshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GAWorkshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GA
 
Python builds mit ant
Python builds mit antPython builds mit ant
Python builds mit ant
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfallen
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklung
 
Angular von 0 auf 100
Angular von 0 auf 100Angular von 0 auf 100
Angular von 0 auf 100
 
Typescript
TypescriptTypescript
Typescript
 
Warum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser machtWarum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser macht
 
Automatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit SeleniumAutomatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit Selenium
 
Java Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s StapelnJava Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s Stapeln
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
TypeScript
TypeScriptTypeScript
TypeScript
 
Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistence
 
Einführung in die funktionale Programmierung
Einführung in die funktionale ProgrammierungEinführung in die funktionale Programmierung
Einführung in die funktionale Programmierung
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7
 
Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!
 

SOLID Prinzipien, Designgrundlagen objektorientierter Systeme