1. It is hard to change because every change affects too many other parts
of the system. (Rigidity - Starr)
2. When you ma...
A B X
• Basistechnologien (.Net, Java, Ruby, …)
• Basisdatentypen (int, string, char…)
• Datenhaltungsklassen und Transferobjekt...
User Interface
Business Layer
Data Access Layer
Cross
Cutting
Concerns
User Interface
Business Layer
Data Access Layer
Cross
Cutting
Concerns
A B Xb
?
public class A
{
IB b;
public A(IB b)
{
this.b = b;
}
}
User Interface
Business Layer
Data Access Layer
Cross
Cutting
Concerns
Robert C. Martin
(Uncle Bob)
The SOLID principles are not rules. They are not laws.
They are not perfect truths. They are ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
Klient
Leistungs-
träger
High-Level Low-Level
High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
Klient
Leistungs-
träger
High-Level Low-Level
…
…
…
High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
Person Bauer
High-Level Low-Level
Süßer
Apfel
Person
Boskoop
Bauer
High-Level Low-Level
Süßer
Apfel
GetBoskoop!
High-Level Klassen sollen nicht von Low-Level Klassen ab...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
Person
Boskoop
Bauer
High-Level Low-Level
Süßer
Apfel
GetBoskoop
High-Level Klassen sollen nicht von Low-Level Klassen abh...
Person Obsthändler
Pink Lady
Bauer
Boskoop
Bauer
Granny
Smith Bauer
High-Level Low-Level
Süßer
Apfel
High-Level Klassen so...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
Person Obsthändler
Pink Lady
Bauer
Boskoop
Bauer
Granny
Smith Bauer
High-Level Low-Level
Süßer
Apfel
Abstraktionen sollen ...
Person Obsthändler
High-Level Low-Level
Süßer
Apfel
Abstraktionen sollen nicht von Details abhängig sein, sondern Details ...
Person IObsthändler
Low-Level
GetApfel
Obsthändler
B
Obsthändler
A
Obsthändler
C
Süßer
Apfel
Abstraktionen sollen nicht vo...
Was ist Inversion of Control???
Person IObsthändler
Low-Level
GetApfel
Obsthändler
B
Obsthändler
A
Obsthändler
C
Süßer
Apf...
ohne IoC mit IoC
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
Flow
Inversion
Publisher Subscriber
Flow
Inversion
Subscriber
Subscriber
Publisher
Publisher
Publisher Event Aggregator Subscriber
Flow
Inversion
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
Request Factory Typdefinition
Creation
Inversion
Request Typdefinition
Subscriber
Subscriber
Request IoC Container Typdefinitionen
Creation
Inversion
public class StudentContext : DbContext
{
public StudentContext() : base()
{}
public DbSet<StudentEntity> Students { get; ...
public class StudentContext : DbContext, IStudentContext
{
public StudentContext() : base()
{}
public DbSet<StudentEntity>...
Creation
Inversion
public class StudentManagementViewModel
{
StudentContext context;
public StudentEntity Student { get; s...
Creation
Inversion
public class StudentManagementViewModel
{
IStudentContext context;
public StudentEntity Student { get; ...
Creation
Inversion
public class StudentManagementViewModel
{
IStudentContext context;
public StudentEntity Student { get; ...
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
public class StudentContext : DbContext, IStudentContext
{
public StudentContext() : base()
{}
public DbSet<StudentEntity>...
public class IStudentRepository
{
IQueryable<StudentEntity> Students { get; set; }
}
Interface
Inversion
public class Stud...
[Table("StudentInfo")]
public class StudentEntity
{
public StudentEntity() { }
[Key]
public int SID { get; set; }
[Column(...
public class Student
{
public int SID { get; set; }
public string Name { get; set; }
public DateTime BirthDate { get; set;...
Interface
Inversion
public class StudentManagementViewModel
{
IStudentContext context;
public StudentEntity Student { get;...
Interface
Inversion
public class StudentManagementViewModel
{
IStudentRepository repository;
public Student Student { get;...
var student = this.repository.Students.Single(s => s.StudentName == name);
Student student = this.repository.Students.Sing...
Interface
Inversion
internal class StudentsFromDatabase : IManageStudents, DbSet {...}
public class IStudentRepository
{
I...
Header Interfaces
public interface IManageStudents : IQueryable<Student>
{
Student Create();
Student GetStudent(string nam...
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
User Interface
Business Layer
Data Access Layer
Cross
Cutting
Concerns
Quelle: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
Application
Services
Domain
Services
Domain
Model
Us...
•
•
•
•
„The real problem is that programmers have spent far too
much time worrying about efficiency in the wrong places and
at th...
Der Code bestimmt
die Lösung.
Der Konsument
bestimmen den
Code.
DevDay 2016: Hendrik Lösch - Lose gekoppelt wie nie: DI vs. IoC
DevDay 2016: Hendrik Lösch - Lose gekoppelt wie nie: DI vs. IoC
DevDay 2016: Hendrik Lösch - Lose gekoppelt wie nie: DI vs. IoC
Nächste SlideShare
Wird geladen in …5
×

DevDay 2016: Hendrik Lösch - Lose gekoppelt wie nie: DI vs. IoC

2.493 Aufrufe

Veröffentlicht am

Dependency Injection, Service Locator, Inversion of Control, Dependency Inversion Principle, … Viele Begriffe die irgendwie das Gleiche zu sagen scheinen und sich dann doch wieder unterscheiden. Sicher ist nur, dass es sich um lose Kopplung handelt. Dass wir dank dieser ominösen Begriffe wartbare Software erstellen können, die leichter zu erweitern ist und sich darüber hinaus auch noch gut testen lässt.
Der Vortrag griff die zuvor genannten Begriffe auf und erläuterte ihre Zusammenhänge. Dabei war das Ziel mit altbekannten Vorurteilen aufzuräumen und bei der Entscheidung zu helfen wo Softwarebestandteile wirklich entkoppelt werden sollten und welche Antipatterns sich beim Praxiseinsatz ergeben können. Dabei sahen wir diverse Beispiele des Einsatzes der SOLID Prinzipien und warum Dependency Injection allein eben nicht zu besserer Software führt.

Veröffentlicht in: Technologie
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
2.493
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
2.333
Aktionen
Geteilt
0
Downloads
4
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

DevDay 2016: Hendrik Lösch - Lose gekoppelt wie nie: DI vs. IoC

  1. 1. 1. It is hard to change because every change affects too many other parts of the system. (Rigidity - Starr) 2. When you make a change, unexpected parts of the system break. (Fragility - Zerbrechlich) 3. It is hard to reuse in another application because it cannot be disentangled from the current application. (Immobility - Unbeweglich) Quelle: http://www.objectmentor.com/resources/articles/dip.pdf
  2. 2. A B X
  3. 3. • Basistechnologien (.Net, Java, Ruby, …) • Basisdatentypen (int, string, char…) • Datenhaltungsklassen und Transferobjekte • Domänen spezifische Algorithmen und Datenbanken • UI Logik • … beständig unbeständig
  4. 4. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  5. 5. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  6. 6. A B Xb ?
  7. 7. public class A { IB b; public A(IB b) { this.b = b; } }
  8. 8. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  9. 9. Robert C. Martin (Uncle Bob) The SOLID principles are not rules. They are not laws. They are not perfect truths. They are statements on the order of “An apple a day keeps the doctor away.” This is a good principle, it is good advice, but it’s not a pure truth, nor is it a rule. “ ” Quelle: https://sites.google.com/site/unclebobconsultingllc/getting-a-solid-start
  10. 10. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D
  11. 11. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Eine Klasse sollte nur eine Verantwortlichkeit haben. Quelle: http://www.clean-code-developer.de/
  12. 12. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Eine Klasse sollte offen für Erweiterungen, jedoch geschlossen für Modifikationen sein. Quelle: http://www.clean-code-developer.de/
  13. 13. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Abgeleitete Klassen sollten sich so verhalten wie es von ihren Basistypen erwartet wird. Quelle: http://www.clean-code-developer.de/
  14. 14. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Interfaces sollten nur die Funktionalität wiederspiegeln die ihre Klienten erwarten. Quelle: http://www.clean-code-developer.de/
  15. 15. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. Quelle: Wikipedia.org
  16. 16. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Interfaces.
  17. 17. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Klient Leistungs- träger High-Level Low-Level
  18. 18. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Klient Leistungs- träger High-Level Low-Level … … …
  19. 19. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Person Bauer High-Level Low-Level Süßer Apfel
  20. 20. Person Boskoop Bauer High-Level Low-Level Süßer Apfel GetBoskoop! High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
  21. 21. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Interfaces.
  22. 22. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Interfaces.
  23. 23. Person Boskoop Bauer High-Level Low-Level Süßer Apfel GetBoskoop High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen… !
  24. 24. Person Obsthändler Pink Lady Bauer Boskoop Bauer Granny Smith Bauer High-Level Low-Level Süßer Apfel High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen…
  25. 25. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen.
  26. 26. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen.
  27. 27. Person Obsthändler Pink Lady Bauer Boskoop Bauer Granny Smith Bauer High-Level Low-Level Süßer Apfel Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. GetBoskoop!
  28. 28. Person Obsthändler High-Level Low-Level Süßer Apfel Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. GetApfel Pink Lady Bauer Boskoop Bauer Granny Smith Bauer
  29. 29. Person IObsthändler Low-Level GetApfel Obsthändler B Obsthändler A Obsthändler C Süßer Apfel Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. High-Level
  30. 30. Was ist Inversion of Control??? Person IObsthändler Low-Level GetApfel Obsthändler B Obsthändler A Obsthändler C Süßer Apfel
  31. 31. ohne IoC mit IoC
  32. 32. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  33. 33. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  34. 34. Flow Inversion
  35. 35. Publisher Subscriber Flow Inversion
  36. 36. Subscriber Subscriber Publisher Publisher Publisher Event Aggregator Subscriber Flow Inversion
  37. 37. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  38. 38. Request Factory Typdefinition Creation Inversion Request Typdefinition
  39. 39. Subscriber Subscriber Request IoC Container Typdefinitionen Creation Inversion
  40. 40. public class StudentContext : DbContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } Creation Inversion
  41. 41. public class StudentContext : DbContext, IStudentContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Creation Inversion
  42. 42. Creation Inversion public class StudentManagementViewModel { StudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel() { this.context = new StudentContext(); } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  43. 43. Creation Inversion public class StudentManagementViewModel { IStudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel() { this.context = ServiceLocator.Create<IStudentContext>(); } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  44. 44. Creation Inversion public class StudentManagementViewModel { IStudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel(IStudentContext context) { this.context = context; } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  45. 45. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  46. 46. public class StudentContext : DbContext, IStudentContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Interface Inversion
  47. 47. public class IStudentRepository { IQueryable<StudentEntity> Students { get; set; } } Interface Inversion public class StudentContext : DbContext, IStudentRepository { public StudentContext() : base() { // ... } private DbSet<StudentEntity> students; public IQueryable<StudentEntity> Students { get{ return this.students} } }
  48. 48. [Table("StudentInfo")] public class StudentEntity { public StudentEntity() { } [Key] public int SID { get; set; } [Column("Name", TypeName = "ntext")] [MaxLength(20)] public string StudentName { get; set; } [Column("BDate", TypeName = "datetime")] public DateTime BirthDate { get; set; } [NotMapped] public int? Age { get;} } Interface Inversion
  49. 49. public class Student { public int SID { get; set; } public string Name { get; set; } public DateTime BirthDate { get; set; } public int? Age { get; } } Interface Inversion public class IStudentRepository { IQueryable<Student> Students { get; set; } } [Table("StudentInfo")] public class StudentEntity { [Key] public int SID { get; set; } [Column("Name", TypeName = "ntext")] [MaxLength(20)] public string StudentName { get; set; } [Column("BDate", TypeName = "datetime")] public DateTime BirthDate { get; set; } }
  50. 50. Interface Inversion public class StudentManagementViewModel { IStudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel(IStudentContext context) { this.context = context; } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  51. 51. Interface Inversion public class StudentManagementViewModel { IStudentRepository repository; public Student Student { get; set; } public StudentManagementViewModel(IStudentRepository repository) { this.repository = repository; } public void ShowStudent(string name) { this.Student = this.repository.Students.FirstOrDefault<Student> (s => s.StudentName == name); } }
  52. 52. var student = this.repository.Students.Single(s => s.StudentName == name); Student student = this.repository.Students.Single(s => s.StudentName == name); Student stud = this.repository.Students.Single(s => s.StudentName == name); Interface Inversion
  53. 53. Interface Inversion internal class StudentsFromDatabase : IManageStudents, DbSet {...} public class IStudentRepository { IQueryable<Student> Students { get; set; } } public interface IManageStudents : IQueryable<Student> { Student Create(); void Add(Student student); ... } Siehe auch: cessor.de this.Student = this.students.FirstOrDefault(s => s.StudentName == name);
  54. 54. Header Interfaces public interface IManageStudents : IQueryable<Student> { Student Create(); Student GetStudent(string name) void Add(Student student); ... } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Role Interfaces Interface Inversion
  55. 55. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  56. 56. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  57. 57. Quelle: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ Application Services Domain Services Domain Model User Interface File DB Web Service
  58. 58. • • • •
  59. 59. „The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.“ Quelle: https://en.wikiquote.org/wiki/Donald_Knuth Donald Knuth
  60. 60. Der Code bestimmt die Lösung. Der Konsument bestimmen den Code.

×