SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

78
SOLID PRINCIPLES Designgrundlagen objektorientierter Systeme

Transcript of SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Page 1: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

SOLID PRINCIPLESDesigngrundlagen objektorientierter Systeme

Page 2: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

–Fred Brooks, The Mythical Man Month (Jänner 1975)

„All successful software gets changed.“

Page 3: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

JPA

lokale Beans

ohne Interface

alles Remote

CDIkonkrete CMPs

abstrakte CMPs

Java Server Pages

Java Server Faces

MVC 1.0

Page 4: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

JPA

lokale Beans

ohne Interface

alles Remote

CDIkonkrete CMPs

abstrakte CMPs

Java Server Pages

Java Server Faces

MVC 1.0Technologie darf

dem Design nicht

im Weg stehen!

Page 5: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

The Single Responsibility Principle

A class should have only one reason to change.

Page 6: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfallpublic 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.");}

}

Page 7: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfallpublic 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

Page 8: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall@Injectprivate 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.");}

}

Page 9: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall@Injectprivate 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

Page 10: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall@Injectprivate SolidValidator validator;

@Injectprivate 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);}

Page 11: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall@Injectprivate SolidValidator validator;

@Injectprivate 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

Page 12: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall@Injectprivate SolidValidator validator;

@Injectprivate BenutzerRepository users;

@Injectprivate 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);}

Page 13: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Viele Methoden verwenden das selbe

Feld?

Page 14: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Viele Methoden verwenden das selbe

Feld?

private

Page 15: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Viele Methoden verwenden das selbe

Feld?

Technologie & Fachlichkeit

in derselben Klasse?

Page 16: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

The Open/Closed Principle

Software entities should be open for extension but closed for modification.

Page 17: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

Client Server

Page 18: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

Client Server

Welche Methoden darf ich verwenden?

Page 19: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

Client Server

Welche Methoden darf ich verwenden?

Welche Methoden werden eigentlich benötigt?

Page 20: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

ClientInterfaceClient

Server

Page 21: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

ClientInterfaceClient

Server

gehören zusammen

Page 22: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

ClientInterfaceClient

Server

gehören zusammen

bestimmt die Funktion

Page 23: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

ClientInterfaceClient

Server

gehören zusammen

bestimmt die Funktion

closed formodification

Page 24: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

ClientInterfaceClient

Server

gehören zusammen

bestimmt die Funktion

closed formodification

open forextension

Page 25: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Code Beispielpublic enum Typ {

ARBEITSPAKET, MEILENSTEIN}

public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete){for (Arbeitspaket arbeitspaket : arbeitspakete) {

if(Typ.MEILENSTEIN == arbeitspaket.getTyp()){return arbeitspaket;

}}return null;

}

Page 26: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Code Beispielpublic 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 und ProjektEnde, beides Meilensteine

Page 27: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Code Beispielpublic 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 und ProjektEnde, beides Meilensteine

gute Idee

Page 28: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Code Beispielpublic 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 und ProjektEnde, beides Meilensteine

gute Idee

hier ein Problem

Page 29: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Code Beispiel

public Arbeitspaket findeErstenMeilenstein(List<Arbeitspaket> arbeitspakete) {for (Arbeitspaket arbeitspaket : arbeitspakete) {

if (arbeitspaket.getTyp().isMeilenstein()) {return arbeitspaket;

}}return null;

}

Page 30: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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();

}

Page 31: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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 {

@Overridepublic boolean isArbeitspaket() {

return true;}

},PROJEKTSTART {

@Overridepublic boolean isMeilenstein() {

return true;}

},PROJEKTENDE {

@Overridepublic boolean isMeilenstein() {

return true;}

},MEILENSTEIN {

@Overridepublic boolean isMeilenstein() {

return true;}

};

public boolean isMeilenstein() {return false;

}

public boolean isArbeitspaket() {return false;

}}

Page 32: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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 {

@Overridepublic boolean isArbeitspaket() {

return true;}

},PROJEKTSTART {

@Overridepublic boolean isMeilenstein() {

return true;}

},PROJEKTENDE {

@Overridepublic boolean isMeilenstein() {

return true;}

},MEILENSTEIN {

@Overridepublic boolean isMeilenstein() {

return true;}

};

public boolean isMeilenstein() {return false;

}

public boolean isArbeitspaket() {return false;

}}

Closed fo

r Modification

,

Open for

Extensi

on

Page 33: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Das Hinzufügen oder Entfernen einer Funktion muss

in vielen Klassen nachgezogen werden.

Page 34: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

HinweiseSchnittstellen

entsprechen den Anforderungen des Dienstanbieters

und nicht des Benutzers!

Das Hinzufügen oder Entfernen einer Funktion muss

in vielen Klassen nachgezogen werden.

Page 35: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

The Liskov Substitution Principle

Subtypes must be substitutable for their base types

Page 36: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

Arbeitspaket+getEndDate() : Date +setDuration(int)

Page 37: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

Arbeitspaket+getEndDate() : Date +setDuration(int)

Neue Anforderung: Wir benötigen

eine Klasse „Meilensteine“

Page 38: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Der erste Versuch

Arbeitspaket+getEndDate() : Date +setDuration(int)

Meilenstein

Page 39: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Der erste Versuch

Arbeitspaket+getEndDate() : Date +setDuration(int)

Meilenstein

Darf Beginn- und Enddatum eines Meilensteins

voneinander abweichen?

Page 40: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Darf Beginn- und Enddatum eines Meilensteins

voneinander abweichen?

Der zweite Versuch

Arbeitspaket+getEndDate() : Date +setDuration(int)

Meilenstein+setDuration(int)

Page 41: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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.");}

}

Page 42: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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!

Page 43: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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!

Page 44: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Der dritte Versuch

Arbeitspaket

+setDuration(int)

Meilenstein

Phase

+getEndDate() : Date

Page 45: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Der dritte Versuch

Arbeitspaket

+setDuration(int)

Meilenstein

Phase

+getEndDate() : Date

identisches Verhalten

Page 46: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Der dritte Versuch

Arbeitspaket

+setDuration(int)

Meilenstein

Phase

+getEndDate() : Date

identisches Verhalten

unterschiedliches Verhalten

Page 47: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Der dritte Versuch

Arbeitspaket

+setDuration(int)

Meilenstein

Phase

+getEndDate() : Date

identisches Verhalten

unterschiedliches Verhalten

Subtypes are substitu

table

for their base types

Page 48: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Das Verhalten der Elternklasse(n) führt zu Fehlern.

Page 49: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Das Verhalten der Elternklasse(n) führt zu Fehlern.

IsA-Beziehung (extends) zwingt mich Methoden zu

überschreiben.

Page 50: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

The Interface Segregation Principle

Clients should not be forced to depend on methods they do not use.

Page 51: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

SecurityUser

Projekt+getRoles() : Role[] +getProjekte() : Projekt[]

Page 52: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

SecurityUser

Projekt+getRoles() : Role[] +getProjekte() : Projekt[]

unnötige Kopplung!

Page 53: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

SecurityUser

Projekt+getRoles() : Role[] +getProjekte() : Projekt[]

unnötige Kopplung!

unnötige Kopplung!

Page 54: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

UserImpl

+getProjekte() : Projekt[]

ProjektManager

SecurityUser

Projekt+getRoles() : Role[]

Page 55: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Ein Anwendungsfall

UserImpl

+getProjekte() : Projekt[]

ProjektManager

SecurityUser

Projekt+getRoles() : Role[] FAIL!

Page 56: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Variante 1: Interfaces

SecurityUser

Projekt+getRoles() : Role[]

ProjektUser

+getProjekte() : Projekt[]

ProjektManager

Page 57: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Variante 2: Delegierung

SecurityUser

Projekt

+getRoles() : Role[]

+getProjekte() : Projekt[]

ProjektManager

Page 58: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Variante 3: Vererbung

SecurityUser

Projekt

+getRoles() : Role[]

+getProjekte() : Projekt[]

ProjektManager

Page 59: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Ich muss Methoden implementieren die in der konkreten Klasse gar

keine Funktion erfüllen.

Page 60: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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.

Page 61: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

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.

Page 62: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Schichten

UseCase Layer

Service Layer

Utility Layer

Page 63: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Schichten

UseCase Layer

Service Layer

Utility Layer

High Level „Erstelle Meilenstein“

Page 64: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Schichten

UseCase Layer

Service Layer

Utility Layer

High Level „Erstelle Meilenstein“

Low Level „SQL INSERT“

Page 65: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Invertierte Schichten

Service Layer

Utility Layer

UseCase Service

Interface

Service Interface

UseCase Layer

Page 66: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Invertierte Schichten

Service Layer

Utility Layer

UseCase Service

Interface

Service Interface

UseCase Layer Abstractions

Page 67: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Invertierte Schichten

Service Layer

Utility Layer

UseCase Service

Interface

Service Interface

UseCase Layer Abstractions

Details

Page 68: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Invertierte Schichten

Service Layer

Utility Layer

UseCase Service

Interface

Service Interface

UseCase Layer High

Low

Page 69: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Clean Architecture

High

Low

Page 70: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Clean Architecture

High

Lowui, db, web

Page 71: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Clean Architecture

High

Lowui, db, web

online, backoffice, batch

Page 72: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Clean Architecture

High

Lowui, db, web

online, backoffice, batch

domain services, entities

Page 73: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Clean Architecture

fachlich High

Lowui, db, web

online, backoffice, batch

domain services, entities

Page 74: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Clean Architecture

fachlich

technisch

High

Lowui, db, web

online, backoffice, batch

domain services, entities

Page 75: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Clean Architecture

Abhängigkeiten

fachlich

technisch

High

Lowui, db, web

online, backoffice, batch

domain services, entities

Page 76: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Ich kann nicht Testen wenn

System X nicht zur Verfügung steht.

Page 77: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Hinweise

Ich kann nicht Testen wenn

System X nicht zur Verfügung steht.

Ich kann die Fachlichkeit

nicht erkennen und erhalten.

Page 78: SOLID Prinzipien, Designgrundlagen objektorientierter Systeme

Vielen Dank

[email protected]