Prinzipien objektorientierten Designs
{{#if: SOLID
| Vorlage:Hinweisbaustein | {{#ifeq: 0 | 0 | }}}}
Prinzipien objektorientierten Designs sind Prinzipien, die zu gutem objektorientierten Design führen sollen. Sie wurden neben anderen von Robert C. Martin, Bertrand Meyer und Barbara Liskov publiziert und propagiert. Viele Techniken der Objektorientierung wie Entwurfsmuster, Domain-driven Design oder Dependency Injection basieren auf diesen Prinzipien objektorientierten Designs.
Für eine Gruppe dieser Prinzipien wurde von Robert C. Martin das Akronym “SOLID” geprägt. Diese Prinzipien gemeinsam angewandt führt laut Robert C. Martin zu einer höheren Wartbarkeit und somit Lebensdauer von Software. Diese Prinzipien sind das “Single Responsibility Prinzip”, das “Open-Closed Prinzip”, das “Liskovsches Substitutionsprinzip”, das “Interface Segregation Prinzip” und das “Dependency Inversion Prinzip”.
Darüber hinaus gibt es noch eine Reihe weiterer mehr oder weniger bekannter Prinzipien objektorientierten Designs wie Design by contract oder das Gesetz von Demeter. Eine Sonderstellung unter den Prinzipien objektorientierten Designs haben die sogenannten Packaging Prinzipien, da diese sich alle mit der Gruppierung von Klassen zu Packages beschäftigen.
SOLID-Prinzipien
Single-Responsibility-Prinzip
{{#if: Single-Responsibility-Prinzip|{{#ifexist:Single-Responsibility-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Single-Responsibility-Prinzip besagt, dass jede Klasse nur eine einzige Verantwortung haben solle. Verantwortung wird hierbei als „Grund zur Änderung“ definiert:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|There should never be more than one reason for a class to change.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|There should never be more than one reason for a class to change.}}“
| {{#invoke:Text|quoteUnquoted| There should never be more than one reason for a class to change. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|There should never be more than one reason for a class to change.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Es sollte nie mehr als einen Grund dafür geben, eine Klasse zu ändern.Robert C. MartinAgile Software Development: Principles, Patterns, and Practices || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Es sollte nie mehr als einen Grund dafür geben, eine Klasse zu ändern.Robert C. MartinAgile Software Development: Principles, Patterns, and Practices || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Es sollte nie mehr als einen Grund dafür geben, eine Klasse zu ändern.
|
„Es sollte nie mehr als einen Grund dafür geben, eine Klasse zu ändern.“{{#if: Robert C. MartinAgile Software Development: Principles, Patterns, and Practices || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Agile Software Development: Principles, Patterns, and Practices
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: There should never be more than one reason for a class to change. | {{
#if: | {{#if: There should never be more than one reason for a class to change. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Agile Software Development: Principles, Patterns, and Practices |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Es sollte nie mehr als einen Grund dafür geben, eine Klasse zu ändern. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}} Mehr als eine Verantwortung für eine Klasse führt zu mehreren Bereichen, in denen zukünftige Änderungen notwendig werden können. Die Wahrscheinlichkeit, dass die Klasse zu einem späteren Zeitpunkt geändert werden muss, steigt zusammen mit dem Risiko, sich bei solchen Änderungen subtile Fehler einzuhandeln. Dieses Prinzip führt in der Regel zu Klassen mit hoher Kohäsion, in denen alle Methoden einen starken gemeinsamen Bezug haben.
Open-Closed-Prinzip
{{#if: Open-Closed-Prinzip|{{#ifexist:Open-Closed-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Open-Closed-Prinzip besagt, dass Software-Einheiten (hier Module, Klassen, Methoden usw.) Erweiterungen möglich machen sollen (dafür offen sein), aber ohne dabei ihr Verhalten zu ändern (ihr Sourcecode und ihre Schnittstelle sollte sich nicht ändern). Es wurde 1988 von Bertrand Meyer folgendermaßen formuliert:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Modules should be both open (for extension) and closed (for modification).}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Modules should be both open (for extension) and closed (for modification).}}“
| {{#invoke:Text|quoteUnquoted| Modules should be both open (for extension) and closed (for modification). | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Modules should be both open (for extension) and closed (for modification).}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Module sollten sowohl offen (für Erweiterungen), als auch geschlossen (für Modifikationen) sein.Bertrand MeyerObject Oriented Software Construction || <ref name="meyer">{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Module sollten sowohl offen (für Erweiterungen), als auch geschlossen (für Modifikationen) sein.Bertrand MeyerObject Oriented Software Construction || <ref name="meyer">{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Module sollten sowohl offen (für Erweiterungen), als auch geschlossen (für Modifikationen) sein.
|
„Module sollten sowohl offen (für Erweiterungen), als auch geschlossen (für Modifikationen) sein.“{{#if: Bertrand MeyerObject Oriented Software Construction || <ref name="meyer">{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Object Oriented Software Construction
|}}}}
{{#if: <ref name="meyer">{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref name="meyer">{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Modules should be both open (for extension) and closed (for modification). | {{
#if: | {{#if: Modules should be both open (for extension) and closed (for modification). |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Bertrand Meyer |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Object Oriented Software Construction |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Module sollten sowohl offen (für Erweiterungen), als auch geschlossen (für Modifikationen) sein. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}} Eine Erweiterung im Sinne des Open-Closed-Prinzips ist beispielsweise die Vererbung. Diese verändert das vorhandene Verhalten einer Klasse nicht, erweitert sie aber um zusätzliche Funktionen oder Daten. Überschriebene Methoden verändern auch nicht das Verhalten der Basisklasse, sondern nur das der abgeleiteten Klasse. Folgt man weiter dem Liskovschen Substitutionsprinzip, verändern auch überschriebene Methoden nicht das Verhalten, sondern nur die Algorithmen.
Liskovsches Substitutionsprinzip
{{#if: Liskovsches Substitutionsprinzip|{{#ifexist:Liskovsches Substitutionsprinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Liskovsche Substitutionsprinzip (LSP) oder Ersetzbarkeitsprinzip fordert, dass eine Instanz einer abgeleiteten Klasse sich so verhalten muss, dass jemand, der meint, ein Objekt der Basisklasse vor sich zu haben, nicht durch unerwartetes Verhalten überrascht wird, wenn es sich dabei tatsächlich um ein Objekt eines Subtyps handelt. Es wurde 1993 von Barbara Liskov und Jeannette Wing formuliert.<ref>Barbara H. Liskov, Jeannette M. Wing: Family Values: A Behavioral Notion of Subtyping. Pittsburgh 1993.</ref> In einem nachfolgenden Artikel wurde es folgendermaßen formuliert:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Let <math>q(x)</math> be a property provable about objects <math>x</math> of type <math>T</math>. Then <math>q(y)</math> should be true for objects <math>y</math> of type <math>S</math> where <math>S</math> is a subtype of <math>T</math>.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Let <math>q(x)</math> be a property provable about objects <math>x</math> of type <math>T</math>. Then <math>q(y)</math> should be true for objects <math>y</math> of type <math>S</math> where <math>S</math> is a subtype of <math>T</math>.}}“
| {{#invoke:Text|quoteUnquoted| Let <math>q(x)</math> be a property provable about objects <math>x</math> of type <math>T</math>. Then <math>q(y)</math> should be true for objects <math>y</math> of type <math>S</math> where <math>S</math> is a subtype of <math>T</math>. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Let <math>q(x)</math> be a property provable about objects <math>x</math> of type <math>T</math>. Then <math>q(y)</math> should be true for objects <math>y</math> of type <math>S</math> where <math>S</math> is a subtype of <math>T</math>.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Sei <math>q(x)</math> eine Eigenschaft des Objektes <math>x</math> vom Typ <math>T</math>, dann sollte <math>q(y)</math> für alle Objekte <math>y</math> des Typs <math>S</math> gelten, wobei <math>S</math> ein Subtyp von <math>T</math> ist.Barbara H. Liskov, Jeannette M. WingBehavioral Subtyping Using Invariants and Constraints || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Sei <math>q(x)</math> eine Eigenschaft des Objektes <math>x</math> vom Typ <math>T</math>, dann sollte <math>q(y)</math> für alle Objekte <math>y</math> des Typs <math>S</math> gelten, wobei <math>S</math> ein Subtyp von <math>T</math> ist.Barbara H. Liskov, Jeannette M. WingBehavioral Subtyping Using Invariants and Constraints || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Sei <math>q(x)</math> eine Eigenschaft des Objektes <math>x</math> vom Typ <math>T</math>, dann sollte <math>q(y)</math> für alle Objekte <math>y</math> des Typs <math>S</math> gelten, wobei <math>S</math> ein Subtyp von <math>T</math> ist.
|
„Sei <math>q(x)</math> eine Eigenschaft des Objektes <math>x</math> vom Typ <math>T</math>, dann sollte <math>q(y)</math> für alle Objekte <math>y</math> des Typs <math>S</math> gelten, wobei <math>S</math> ein Subtyp von <math>T</math> ist.“{{#if: Barbara H. Liskov, Jeannette M. WingBehavioral Subtyping Using Invariants and Constraints || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Behavioral Subtyping Using Invariants and Constraints
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Let <math>q(x)</math> be a property provable about objects <math>x</math> of type <math>T</math>. Then <math>q(y)</math> should be true for objects <math>y</math> of type <math>S</math> where <math>S</math> is a subtype of <math>T</math>. | {{
#if: | {{#if: Let <math>q(x)</math> be a property provable about objects <math>x</math> of type <math>T</math>. Then <math>q(y)</math> should be true for objects <math>y</math> of type <math>S</math> where <math>S</math> is a subtype of <math>T</math>. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Barbara H. Liskov, Jeannette M. Wing |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Behavioral Subtyping Using Invariants and Constraints |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Sei <math>q(x)</math> eine Eigenschaft des Objektes <math>x</math> vom Typ <math>T</math>, dann sollte <math>q(y)</math> für alle Objekte <math>y</math> des Typs <math>S</math> gelten, wobei <math>S</math> ein Subtyp von <math>T</math> ist. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Damit ist garantiert, dass Operationen vom Typ Superklasse, die auf ein Objekt des Typs Subklasse angewendet werden, auch korrekt ausgeführt werden. Dann lässt sich stets bedenkenlos ein Objekt vom Typ Superklasse durch ein Objekt vom Typ Subklasse ersetzen.
Objektorientierte Programmiersprachen können eine Verletzung dieses Prinzips, die aufgrund der mit der Vererbung verbundenen Polymorphie auftreten kann, nicht von vornherein ausschließen. Häufig ist eine Verletzung des Prinzips nicht auf den ersten Blick offensichtlich.<ref name="LahresRayman.5.1">Lahres, Rayman: Praxisbuch Objektorientierung. Seiten 153–189, siehe Literatur</ref>
Interface-Segregation-Prinzip
{{#if: Interface-Segregation-Prinzip|{{#ifexist:Interface-Segregation-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Interface-Segregation-Prinzip dient dazu, zu große Interfaces aufzuteilen. Die Aufteilung soll gemäß den Anforderungen der Clients an die Interfaces gemacht werden – und zwar derart, dass die neuen Interfaces genau auf die Anforderungen der einzelnen Clients passen. Die Clients müssen also nur mit Interfaces agieren, die das und nur das können, was die Clients benötigen. Das Prinzip wurde von Robert C. Martin 1996 folgendermaßen formuliert:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Clients should not be forced to depend upon interfaces that they do not use.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Clients should not be forced to depend upon interfaces that they do not use.}}“
| {{#invoke:Text|quoteUnquoted| Clients should not be forced to depend upon interfaces that they do not use. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Clients should not be forced to depend upon interfaces that they do not use.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Clients sollten nicht dazu gezwungen werden, von Interfaces abzuhängen, die sie nicht verwenden.Robert C. MartinThe Interface Segregation Principle || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Clients sollten nicht dazu gezwungen werden, von Interfaces abzuhängen, die sie nicht verwenden.Robert C. MartinThe Interface Segregation Principle || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Clients sollten nicht dazu gezwungen werden, von Interfaces abzuhängen, die sie nicht verwenden.
|
„Clients sollten nicht dazu gezwungen werden, von Interfaces abzuhängen, die sie nicht verwenden.“{{#if: Robert C. MartinThe Interface Segregation Principle || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: The Interface Segregation Principle
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Clients should not be forced to depend upon interfaces that they do not use. | {{
#if: | {{#if: Clients should not be forced to depend upon interfaces that they do not use. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: The Interface Segregation Principle |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Clients sollten nicht dazu gezwungen werden, von Interfaces abzuhängen, die sie nicht verwenden. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}} Mit Hilfe des Interface-Segregation-Prinzips ist es möglich eine Software derart in entkoppelte und somit leichter refaktorisierbare Klassen aufzuteilen, dass zukünftige fachliche oder technische Anforderungen an die Software nur geringe Änderungen an der Software selbst benötigen.
Dependency-Inversion-Prinzip
{{#if: Dependency-Inversion-Prinzip|{{#ifexist:Dependency-Inversion-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Dependency-Inversion-Prinzip beschäftigt sich mit der Reduktion der Kopplung von Modulen. Es besagt, dass Abhängigkeiten immer von konkreteren Modulen niedriger Ebenen zu abstrakten Modulen höherer Ebenen gerichtet sein sollten. Es wurde von Robert C. Martin erstmals im Oktober 1994 beschrieben<ref>{{#invoke:Vorlage:Literatur|f}}</ref> und später folgendermaßen formuliert:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|A. High-level modules should not depend on low level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|A. High-level modules should not depend on low level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.}}“
| {{#invoke:Text|quoteUnquoted| A. High-level modules should not depend on low level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|A. High-level modules should not depend on low level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: A. Module hoher Ebenen sollten nicht von Modulen niedriger Ebenen abhängen. Beide sollten von Abstraktionen abhängen.
B. Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen.Robert C. MartinThe Dependency Inversion Principle || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: A. Module hoher Ebenen sollten nicht von Modulen niedriger Ebenen abhängen. Beide sollten von Abstraktionen abhängen.
B. Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen.Robert C. MartinThe Dependency Inversion Principle || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: A. Module hoher Ebenen sollten nicht von Modulen niedriger Ebenen abhängen. Beide sollten von Abstraktionen abhängen.
B. Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen.
„A. Module hoher Ebenen sollten nicht von Modulen niedriger Ebenen abhängen. Beide sollten von Abstraktionen abhängen.
B. Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen.“{{#if: Robert C. MartinThe Dependency Inversion Principle || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: The Dependency Inversion Principle
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: A. High-level modules should not depend on low level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions. | {{ #if: | {{#if: A. High-level modules should not depend on low level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions. | Vorlage:Zitat: Doppelangabe1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: The Dependency Inversion Principle |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: A. Module hoher Ebenen sollten nicht von Modulen niedriger Ebenen abhängen. Beide sollten von Abstraktionen abhängen.
B. Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}} Damit ist sichergestellt, dass die Abhängigkeitsbeziehungen immer in eine Richtung verlaufen, von den konkreten zu den abstrakten Modulen, von den abgeleiteten Klassen zu den Basisklassen. Damit werden die Abhängigkeiten zwischen den Modulen reduziert und insbesondere zyklische Abhängigkeiten vermieden.
Weitere Prinzipien
Neben der von Robert C. Martin propagierten SOLID-Gruppe von Prinzipien Objektorientierten Designs sind noch folgende Prinzipien als Prinzipien Objektorientierten Designs bekannt:
Gesetz von Demeter
{{#if: Gesetz von Demeter|{{#ifexist:Gesetz von Demeter|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Gesetz von Demeter (englisch: Law of Demeter, kurz: LoD) besagt im Wesentlichen, dass Objekte nur mit Objekten in ihrer unmittelbaren Umgebung kommunizieren sollen. Dadurch soll die Kopplung in einem Softwaresystem verringert und dadurch die Wartbarkeit erhöht werden.
Das Gesetz wurde von Karl J. Lieberherr und Ian Holland 1989 im Paper Assuring Good Style for Object-Oriented Programs folgendermaßen beschrieben:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|A supplier object to a method M is an object to which a message is sent in M. The preferred supplier objects to method M are: The immediate parts of self or the argument objects of M or the objects which are either objects created directly in M or objects in global variables.
Every supplier object to a method must be a preferred supplier.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|A supplier object to a method M is an object to which a message is sent in M. The preferred supplier objects to method M are: The immediate parts of self or the argument objects of M or the objects which are either objects created directly in M or objects in global variables.
Every supplier object to a method must be a preferred supplier.}}“
| {{#invoke:Text|quoteUnquoted| A supplier object to a method M is an object to which a message is sent in M. The preferred supplier objects to method M are: The immediate parts of self or the argument objects of M or the objects which are either objects created directly in M or objects in global variables.
Every supplier object to a method must be a preferred supplier. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|A supplier object to a method M is an object to which a message is sent in M. The preferred supplier objects to method M are: The immediate parts of self or the argument objects of M or the objects which are either objects created directly in M or objects in global variables.
Every supplier object to a method must be a preferred supplier.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Ein Anbieterobjekt der Methode M ist ein Objekt, an welches aus M eine Nachricht gesendet wird. Die bevorzugten Anbieterobjekte der Methode M sind: Die unmittelbaren Bestandteile des Objekts von M, Objekte, die M als Argumente übergeben wurden und Objekte, die entweder direkt in M erzeugt wurden oder sich in globalen Variablen befinden.
Jedes Anbieterobjekt einer Methode muss ein bevorzugtes Anbieterobjekt sein.Karl J. Lieberherr, I. HollandAssuring good style for object-oriented programs || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Ein Anbieterobjekt der Methode M ist ein Objekt, an welches aus M eine Nachricht gesendet wird. Die bevorzugten Anbieterobjekte der Methode M sind: Die unmittelbaren Bestandteile des Objekts von M, Objekte, die M als Argumente übergeben wurden und Objekte, die entweder direkt in M erzeugt wurden oder sich in globalen Variablen befinden.
Jedes Anbieterobjekt einer Methode muss ein bevorzugtes Anbieterobjekt sein.Karl J. Lieberherr, I. HollandAssuring good style for object-oriented programs || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Ein Anbieterobjekt der Methode M ist ein Objekt, an welches aus M eine Nachricht gesendet wird. Die bevorzugten Anbieterobjekte der Methode M sind: Die unmittelbaren Bestandteile des Objekts von M, Objekte, die M als Argumente übergeben wurden und Objekte, die entweder direkt in M erzeugt wurden oder sich in globalen Variablen befinden.
Jedes Anbieterobjekt einer Methode muss ein bevorzugtes Anbieterobjekt sein.
„Ein Anbieterobjekt der Methode M ist ein Objekt, an welches aus M eine Nachricht gesendet wird. Die bevorzugten Anbieterobjekte der Methode M sind: Die unmittelbaren Bestandteile des Objekts von M, Objekte, die M als Argumente übergeben wurden und Objekte, die entweder direkt in M erzeugt wurden oder sich in globalen Variablen befinden.
Jedes Anbieterobjekt einer Methode muss ein bevorzugtes Anbieterobjekt sein.“{{#if: Karl J. Lieberherr, I. HollandAssuring good style for object-oriented programs || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Assuring good style for object-oriented programs
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: A supplier object to a method M is an object to which a message is sent in M. The preferred supplier objects to method M are: The immediate parts of self or the argument objects of M or the objects which are either objects created directly in M or objects in global variables.
Every supplier object to a method must be a preferred supplier. | {{ #if: | {{#if: A supplier object to a method M is an object to which a message is sent in M. The preferred supplier objects to method M are: The immediate parts of self or the argument objects of M or the objects which are either objects created directly in M or objects in global variables.
Every supplier object to a method must be a preferred supplier. | Vorlage:Zitat: Doppelangabe1=Text=}}
}}| }}{{#if: | {{#if: Karl J. Lieberherr, I. Holland |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Assuring good style for object-oriented programs |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Ein Anbieterobjekt der Methode M ist ein Objekt, an welches aus M eine Nachricht gesendet wird. Die bevorzugten Anbieterobjekte der Methode M sind: Die unmittelbaren Bestandteile des Objekts von M, Objekte, die M als Argumente übergeben wurden und Objekte, die entweder direkt in M erzeugt wurden oder sich in globalen Variablen befinden.
Jedes Anbieterobjekt einer Methode muss ein bevorzugtes Anbieterobjekt sein. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Durch die formale Spezifikation lässt sich das Gesetz von Demeter leicht als automatisch geprüfte Softwaremetrik umsetzen. Es bietet sich somit zur Früherkennung von Kopplungsproblemen an.
Design by Contract
{{#if: Design by contract|{{#ifexist:Design by contract|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Design-by-contract-Prinzip, englisch für Entwurf gemäß Vertrag, auch Programming by Contract genannt, hat das reibungslose Zusammenspiel einzelner Programmmodule durch die Definition formaler „Verträge“ zur Verwendung von Schnittstellen, die über deren statische Definition hinausgehen zum Ziel. Entwickelt und eingeführt wurde es von Bertrand Meyer mit der Entwicklung der Programmiersprache Eiffel.
Das reibungslose Zusammenspiel der Programmmodule wird durch einen „Vertrag“ erreicht, der beispielsweise bei der Verwendung einer Methode einzuhalten ist. Dieser besteht aus
- Vorbedingungen (englisch precondition), also den Zusicherungen, die der Aufrufer einzuhalten hat
- Nachbedingungen (englisch postcondition), also den Zusicherungen, die der Aufgerufene einhalten wird, sowie den
- Invarianten (englisch class invariants), quasi dem Gesundheitszustand einer Klasse.
Der Einsatz des Design-by-Contract-Prinzips führt zu sicherer und weniger fehleranfälliger Software, da eine Verletzung des Vertrages zu einem sofortigen Fehler (Fail-Fast) bereits in der Softwareentwicklungsphase führt. Weiters kann die explizite Definition des Vertrages als Form der Dokumentation des Verhaltens des entsprechenden Moduls gesehen werden. Das wiederum führt zu einer besseren Erlernbarkeit und Wartbarkeit der Software.
Datenkapselung
{{#if: Datenkapselung (Programmierung)|{{#ifexist:Datenkapselung (Programmierung)|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Datenkapselung (engl. encapsulation), nach David Parnas auch bekannt als information hiding, ist nach Bertrand Meyer ein weiteres Prinzip objektorientierten Designs.<ref>{{#invoke:Vorlage:Literatur|f}}</ref> Es beschreibt das Verbergen von Daten oder Informationen vor dem Zugriff von außen. Der direkte Zugriff auf die interne Datenstruktur wird unterbunden und erfolgt stattdessen über definierte Schnittstellen. Die in der Objektorientierung verwendeten Zugriffsarten (private, protected, …) sowie eine Reihe von Entwurfsmustern – beispielsweise Facade – unterstützen bei der Umsetzung der Datenkapselung.
Linguistic-Modular-Units-Prinzip
{{#if: Linguistic-Modular-Units-Prinzip|{{#ifexist:Linguistic-Modular-Units-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Linguistic-Modular-Units-Prinzip (englisch für Prinzip linguistisch-modularer Einheiten) besagt, dass Module durch syntaktische Einheiten der verwendeten Sprache – sei es eine Programmier-, Design- oder Spezifikationssprache – repräsentiert werden müssen. Im Falle einer Programmiersprache müssen Module durch separat voneinander kompilierbare Einheiten dieser gewählten Programmiersprache repräsentiert werden:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Modules must correspond to syntactic units in the language used.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Modules must correspond to syntactic units in the language used.}}“
| {{#invoke:Text|quoteUnquoted| Modules must correspond to syntactic units in the language used. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Modules must correspond to syntactic units in the language used.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Module müssen den syntaktischen Einheiten der verwendeten Sprache entsprechen.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Module müssen den syntaktischen Einheiten der verwendeten Sprache entsprechen.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Module müssen den syntaktischen Einheiten der verwendeten Sprache entsprechen.
|
„Module müssen den syntaktischen Einheiten der verwendeten Sprache entsprechen.“{{#if: Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Object Oriented Software Construction
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Modules must correspond to syntactic units in the language used. | {{
#if: | {{#if: Modules must correspond to syntactic units in the language used. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Bertrand Meyer |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Object Oriented Software Construction |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Module müssen den syntaktischen Einheiten der verwendeten Sprache entsprechen. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Self-Documentation-Prinzip
{{#if: Self-Documentation-Prinzip|{{#ifexist:Self-Documentation-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Self-Documentation-Prinzip (englisch für Selbstdokumentierungsprinzip) besagt, dass alle Informationen zu einem Modul in diesem selbst enthalten sein sollten. Damit wird gefordert, dass der Code entweder selbst für sich spricht (d. h. keine weitere Dokumentation nötig hat) beziehungsweise die technische Dokumentation möglichst nahe beim Sourcecode (beispielsweise bei der Verwendung von Javadoc) liegt. Dadurch wird einerseits gewährleistet, dass die technische Dokumentation dem Code entspricht und andererseits, dass die Komplexität des Codes so gering ist, dass keine komplexe Dokumentation nötig ist:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|The designer of a module should strive to make all information about the module part of the module itself.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|The designer of a module should strive to make all information about the module part of the module itself.}}“
| {{#invoke:Text|quoteUnquoted| The designer of a module should strive to make all information about the module part of the module itself. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|The designer of a module should strive to make all information about the module part of the module itself.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Beim Entwurf eines Modules sollte man danach trachten, dass alle Informationen über das Modul selbst Teil des Moduls sind.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Beim Entwurf eines Modules sollte man danach trachten, dass alle Informationen über das Modul selbst Teil des Moduls sind.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Beim Entwurf eines Modules sollte man danach trachten, dass alle Informationen über das Modul selbst Teil des Moduls sind.
|
„Beim Entwurf eines Modules sollte man danach trachten, dass alle Informationen über das Modul selbst Teil des Moduls sind.“{{#if: Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Object Oriented Software Construction
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: The designer of a module should strive to make all information about the module part of the module itself. | {{
#if: | {{#if: The designer of a module should strive to make all information about the module part of the module itself. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Bertrand Meyer |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Object Oriented Software Construction |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Beim Entwurf eines Modules sollte man danach trachten, dass alle Informationen über das Modul selbst Teil des Moduls sind. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Uniform-Access-Prinzip
{{#if: Uniform-Access-Prinzip|{{#ifexist:Uniform-Access-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Uniform-Access-Prinzip (englisch für Prinzip des gleichartigen Zugriffes) fordert, dass auf alle Services eines Modules mittels einer gleichartigen Notation zugegriffen werden kann – ohne dass dadurch preisgegeben wird, ob die Services dahinter auf Datenbestände zugreifen, oder Berechnungen durchführen. Services sollten also nach außen nicht bekanntgeben, wie sie ihre Serviceleistung erbringen, sondern nur was ihre Serviceleistung ist:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.}}“
| {{#invoke:Text|quoteUnquoted| All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Alle Services eines Moduls sollten mittels einer gleichartigen Notation angeboten werden; eine Notation, welche nicht preisgibt, ob sie über Datenzugriffe oder Berechnungen umgesetzt wurden.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Alle Services eines Moduls sollten mittels einer gleichartigen Notation angeboten werden; eine Notation, welche nicht preisgibt, ob sie über Datenzugriffe oder Berechnungen umgesetzt wurden.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Alle Services eines Moduls sollten mittels einer gleichartigen Notation angeboten werden; eine Notation, welche nicht preisgibt, ob sie über Datenzugriffe oder Berechnungen umgesetzt wurden.
|
„Alle Services eines Moduls sollten mittels einer gleichartigen Notation angeboten werden; eine Notation, welche nicht preisgibt, ob sie über Datenzugriffe oder Berechnungen umgesetzt wurden.“{{#if: Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Object Oriented Software Construction
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation. | {{
#if: | {{#if: All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Bertrand Meyer |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Object Oriented Software Construction |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Alle Services eines Moduls sollten mittels einer gleichartigen Notation angeboten werden; eine Notation, welche nicht preisgibt, ob sie über Datenzugriffe oder Berechnungen umgesetzt wurden. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Single-Choice-Prinzip
{{#if: Single-Choice-Prinzip|{{#ifexist:Single-Choice-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Single-Choice-Prinzip besagt, dass verschiedene Alternativen (beispielsweise von Daten oder Algorithmen) in einem Softwaresystem in nur einem einzigen Modul abgebildet werden sollten. Beispielsweise unterstützt das Entwurfsmuster Abstrakte Fabrik dieses Prinzip, indem in der Fabrik einmal aus einem Set an Alternativen entschieden wird, welche Klassen und welche Algorithmen zu verwenden sind. Diese Entscheidung muss an keiner weiteren Stelle im Programm mehr getroffen werden:
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list.}}“
| {{#invoke:Text|quoteUnquoted| Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Immer wenn eine Software unterschiedliche Alternativen unterstützen muss, sollte es genau ein Modul geben, welches die vollständige Liste der Alternativen kennt.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Immer wenn eine Software unterschiedliche Alternativen unterstützen muss, sollte es genau ein Modul geben, welches die vollständige Liste der Alternativen kennt.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Immer wenn eine Software unterschiedliche Alternativen unterstützen muss, sollte es genau ein Modul geben, welches die vollständige Liste der Alternativen kennt.
|
„Immer wenn eine Software unterschiedliche Alternativen unterstützen muss, sollte es genau ein Modul geben, welches die vollständige Liste der Alternativen kennt.“{{#if: Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Object Oriented Software Construction
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list. | {{
#if: | {{#if: Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Bertrand Meyer |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Object Oriented Software Construction |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Immer wenn eine Software unterschiedliche Alternativen unterstützen muss, sollte es genau ein Modul geben, welches die vollständige Liste der Alternativen kennt. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Persistence-Closure-Prinzip
{{#if: Persistence-Closure-Prinzip|{{#ifexist:Persistence-Closure-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Persistence-Closure-Prinzip besagt, dass Persistenzmechanismen Objekte mit all ihren Abhängigkeiten speichern und auch wieder laden müssen. Damit ist sichergestellt, dass Objekte ihre Eigenschaften durch Speichern und darauffolgendes Laden nicht verändern.
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved.}}“
| {{#invoke:Text|quoteUnquoted| Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Wenn ein Speichermechanismus ein Objekt speichert, muss es auch dessen Abhängigkeiten speichern. Wenn ein Lademechanismus ein vorher gespeichertes Objekt lädt, muss er auch dessen bisher noch nicht geladenen Abhängigkeiten laden.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Wenn ein Speichermechanismus ein Objekt speichert, muss es auch dessen Abhängigkeiten speichern. Wenn ein Lademechanismus ein vorher gespeichertes Objekt lädt, muss er auch dessen bisher noch nicht geladenen Abhängigkeiten laden.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Wenn ein Speichermechanismus ein Objekt speichert, muss es auch dessen Abhängigkeiten speichern. Wenn ein Lademechanismus ein vorher gespeichertes Objekt lädt, muss er auch dessen bisher noch nicht geladenen Abhängigkeiten laden.
|
„Wenn ein Speichermechanismus ein Objekt speichert, muss es auch dessen Abhängigkeiten speichern. Wenn ein Lademechanismus ein vorher gespeichertes Objekt lädt, muss er auch dessen bisher noch nicht geladenen Abhängigkeiten laden.“{{#if: Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Object Oriented Software Construction
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved. | {{
#if: | {{#if: Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Bertrand Meyer |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Object Oriented Software Construction |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Wenn ein Speichermechanismus ein Objekt speichert, muss es auch dessen Abhängigkeiten speichern. Wenn ein Lademechanismus ein vorher gespeichertes Objekt lädt, muss er auch dessen bisher noch nicht geladenen Abhängigkeiten laden. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Command-Query-Separation-Prinzip
{{#if: Command-Query-Separation|{{#ifexist:Command-Query-Separation|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Command-Query-Separation-Prinzip (CQS) besagt, dass eine Methode entweder als Abfrage ({{#invoke:Vorlage:lang|flat}}) oder als Kommando ({{#invoke:Vorlage:lang|flat}} (auch {{#invoke:Vorlage:lang|flat}} oder {{#invoke:Vorlage:lang|flat}} genannt)) implementiert werden soll. Eine Abfrage muss hierbei Daten zurückliefern und darf keine Nebeneffekte auf dem beobachtbaren Zustand des Systems aufweisen, während ein Kommando beobachtbare Nebeneffekte aufweist und keine Daten zurückliefert.
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Functions should not produce abstract side effects…only commands (procedures) will be permitted to produce side effects.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Functions should not produce abstract side effects…only commands (procedures) will be permitted to produce side effects.}}“
| {{#invoke:Text|quoteUnquoted| Functions should not produce abstract side effects…only commands (procedures) will be permitted to produce side effects. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Functions should not produce abstract side effects…only commands (procedures) will be permitted to produce side effects.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Funktionen sollten keine Nebenwirkungen haben … nur Kommandos (Prozeduren) dürfen Nebenwirkungen haben.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Funktionen sollten keine Nebenwirkungen haben … nur Kommandos (Prozeduren) dürfen Nebenwirkungen haben.Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Funktionen sollten keine Nebenwirkungen haben … nur Kommandos (Prozeduren) dürfen Nebenwirkungen haben.
|
„Funktionen sollten keine Nebenwirkungen haben … nur Kommandos (Prozeduren) dürfen Nebenwirkungen haben.“{{#if: Bertrand MeyerObject Oriented Software Construction || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Object Oriented Software Construction
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Functions should not produce abstract side effects…only commands (procedures) will be permitted to produce side effects. | {{
#if: | {{#if: Functions should not produce abstract side effects…only commands (procedures) will be permitted to produce side effects. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Bertrand Meyer |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Object Oriented Software Construction |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Funktionen sollten keine Nebenwirkungen haben … nur Kommandos (Prozeduren) dürfen Nebenwirkungen haben. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Principle of Least Surprise
{{#if: Principle of Least Surprise|{{#ifexist:Principle of Least Surprise|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Principle of Least Surprise ({{#invoke:Vorlage:lang|full|CODE=de|SCRIPTING=Latn|SERVICE=deutsch}}) ist eigentlich ein Prinzip in der Software-Ergonomie, der Mensch-Computer-Interaktion und dem Interfacedesign. Es wird aber oft auch auf den Quellcode erweitert und betrifft im objektorientierten Design die Benennung von Variablen, Funktionen, Methoden, Parameter, Klassen und dergleichen. Sie sollen derart benannt werden, dass deren Funktion und mögliche Seiteneffekte alleine aus dem Namen klar erkenntlich sind.
Packaging-Prinzipien
Die folgenden von Bertrand Meyer und Robert C. Martin definierten Prinzipien beschäftigen sich mit der Frage, wie man Klassen zu Modulen (Packages) zusammenführen sollte. Sie führen insbesondere zu einer hohen Kohäsion innerhalb der Module und geringen Kopplung zwischen den Modulen.
Reuse-Release-Equivalence-Prinzip
{{#if: Reuse-Release-Equivalence-Prinzip|{{#ifexist:Reuse-Release-Equivalence-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Either all of the classes in a package are reusable or none of them are.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Either all of the classes in a package are reusable or none of them are.}}“
| {{#invoke:Text|quoteUnquoted| Either all of the classes in a package are reusable or none of them are. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Either all of the classes in a package are reusable or none of them are.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Entweder sind alle oder gar keine Klassen eines Packages wiederverwendbar.Robert C. Martin || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Entweder sind alle oder gar keine Klassen eines Packages wiederverwendbar.Robert C. Martin || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Entweder sind alle oder gar keine Klassen eines Packages wiederverwendbar.
|
„Entweder sind alle oder gar keine Klassen eines Packages wiederverwendbar.“{{#if: Robert C. Martin || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if:
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Either all of the classes in a package are reusable or none of them are. | {{
#if: | {{#if: Either all of the classes in a package are reusable or none of them are. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Entweder sind alle oder gar keine Klassen eines Packages wiederverwendbar. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Das Reuse-Release-Equivalence-Prinzip bezieht sich auf die Struktur von Packages im Sinne eines Moduls als kleinste Einheit eines Releases. Es gibt vor, dass sich Packages nur aus Klassen zusammensetzen dürfen, von denen entweder alle, oder gar keine zur Wiederverwendung gedacht sind.
Handelt es sich um ein wiederverwendbares Package, fordert das Prinzip zum einen, dass alle Änderungen nachvollzogen werden können und der Versionsverlauf zurückverfolgt werden kann, und zum anderen, dass nur Klassen enthalten sind, die auch für dieselbe Benutzergruppe gedacht sind (ein Benutzer, der eine Container-Class-Library wiederverwenden will, benötigt kein Finanz-Framework).
Common-Closure-Prinzip
{{#if: Common Closure Prinzip|{{#ifexist:Common Closure Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Common Closure Prinzip fordert, dass alle Klassen in einem Modul gemäß dem Open-Closed-Prinzip geschlossen gegenüber derselben Art von Veränderungen sein sollten. Änderungen an den Anforderungen einer Software, welche Änderungen an einer Klasse eines Moduls benötigen, sollten auch die anderen Klassen des Moduls betreffen. Die Einhaltung dieses Prinzips ermöglicht es die Software derart in Module zu zerlegen, dass (zukünftige) Änderungen in nur wenigen Modulen umgesetzt werden können. Damit ist sichergestellt, dass Änderungen an der Software ohne große Seiteneffekte und somit relativ kostengünstig gemacht werden können.
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package.}}“
| {{#invoke:Text|quoteUnquoted| The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Klassen eines Packages sollten gemeinsam geschlossen gegenüber denselben Arten von Veränderung sein. Eine Änderung, die ein Package betrifft, sollte alle Klassen dieses Packages betreffen.Robert C. MartinGranularity || <ref name="objectmentor.com">{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Klassen eines Packages sollten gemeinsam geschlossen gegenüber denselben Arten von Veränderung sein. Eine Änderung, die ein Package betrifft, sollte alle Klassen dieses Packages betreffen.Robert C. MartinGranularity || <ref name="objectmentor.com">{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Klassen eines Packages sollten gemeinsam geschlossen gegenüber denselben Arten von Veränderung sein. Eine Änderung, die ein Package betrifft, sollte alle Klassen dieses Packages betreffen.
|
„Klassen eines Packages sollten gemeinsam geschlossen gegenüber denselben Arten von Veränderung sein. Eine Änderung, die ein Package betrifft, sollte alle Klassen dieses Packages betreffen.“{{#if: Robert C. MartinGranularity || <ref name="objectmentor.com">{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Granularity
|}}}}
{{#if: <ref name="objectmentor.com">{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref name="objectmentor.com">{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package. | {{
#if: | {{#if: The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Granularity |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Klassen eines Packages sollten gemeinsam geschlossen gegenüber denselben Arten von Veränderung sein. Eine Änderung, die ein Package betrifft, sollte alle Klassen dieses Packages betreffen. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Common-Reuse-Prinzip
{{#if: Common-Reuse-Prinzip|{{#ifexist:Common-Reuse-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Common-Reuse-Prinzip beschäftigt sich mit der Verwendung von Klassen. Es besagt, dass diejenigen Klassen, welche gemeinsam verwendet werden, auch gemeinsam zu einem Modul zusammengefasst werden sollten. Durch die Einhaltung dieses Prinzips wird eine Unterteilung der Software in fachlich bzw. technisch zusammengehörende Einheiten sichergestellt.
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|The classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|The classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all.}}“
| {{#invoke:Text|quoteUnquoted| The classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|The classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Die Klassen eines Packages sollten gemeinsam wiederverwendet werden. Wenn man eine Klasse eines Packages wiederverwendet, sollte man alle Klassen des Packages wiederverwenden.Robert C. MartinGranularity || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Die Klassen eines Packages sollten gemeinsam wiederverwendet werden. Wenn man eine Klasse eines Packages wiederverwendet, sollte man alle Klassen des Packages wiederverwenden.Robert C. MartinGranularity || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Die Klassen eines Packages sollten gemeinsam wiederverwendet werden. Wenn man eine Klasse eines Packages wiederverwendet, sollte man alle Klassen des Packages wiederverwenden.
|
„Die Klassen eines Packages sollten gemeinsam wiederverwendet werden. Wenn man eine Klasse eines Packages wiederverwendet, sollte man alle Klassen des Packages wiederverwenden.“{{#if: Robert C. MartinGranularity || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Granularity
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: The classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all. | {{
#if: | {{#if: The classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Granularity |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Die Klassen eines Packages sollten gemeinsam wiederverwendet werden. Wenn man eine Klasse eines Packages wiederverwendet, sollte man alle Klassen des Packages wiederverwenden. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}}
Acyclic-Dependencies-Prinzip
{{#if: Acyclic-Dependencies-Prinzip|{{#ifexist:Acyclic-Dependencies-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Acyclic-Dependencies-Prinzip fordert, dass die Abhängigkeiten zwischen Modulen zyklenfrei sein müssen. D. h. wenn Klassen in einem Modul von anderen Klassen in einem anderen Modul beispielsweise durch Vererbungs- oder Relationsbeziehungen abhängen, dann dürfen keine Klassen des anderen Moduls direkt oder indirekt von Klassen des ersteren Moduls abhängen.
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|The dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|The dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure.}}“
| {{#invoke:Text|quoteUnquoted| The dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|The dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Die Abhängigkeiten zwischen Packages müssen einem gerichteten azyklischen Graphen entsprechen. Das bedeutet, dass es keine Zyklen in der Abhängigkeitsstruktur geben darf.Robert C. MartinGranularity || <ref name="objectmentor.com" /> }}
{{#if:
|
„{{{Latn}}}“{{#if: Die Abhängigkeiten zwischen Packages müssen einem gerichteten azyklischen Graphen entsprechen. Das bedeutet, dass es keine Zyklen in der Abhängigkeitsstruktur geben darf.Robert C. MartinGranularity || <ref name="objectmentor.com" /> }}
}}{{#if: Die Abhängigkeiten zwischen Packages müssen einem gerichteten azyklischen Graphen entsprechen. Das bedeutet, dass es keine Zyklen in der Abhängigkeitsstruktur geben darf.
|
„Die Abhängigkeiten zwischen Packages müssen einem gerichteten azyklischen Graphen entsprechen. Das bedeutet, dass es keine Zyklen in der Abhängigkeitsstruktur geben darf.“{{#if: Robert C. MartinGranularity || <ref name="objectmentor.com" /> }}
}}|{{#if: Granularity
|}}}}
{{#if: <ref name="objectmentor.com" /> |
{{#if: {{#invoke:Text|unstrip|<ref name="objectmentor.com" />}}
| }} }}{{#if: The dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure. | {{
#if: | {{#if: The dependency structure between packages must be a directed acyclic graph (DAG). That is, there must be no cycles in the dependency structure. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Granularity |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Die Abhängigkeiten zwischen Packages müssen einem gerichteten azyklischen Graphen entsprechen. Das bedeutet, dass es keine Zyklen in der Abhängigkeitsstruktur geben darf. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}} Derartige Zyklen kann man immer aufbrechen. Dafür gibt es prinzipiell zwei Möglichkeiten:
- Anwendung des Dependency-Inversion-Prinzips: Wenn die Abhängigkeit von Package A auf Package B invertiert werden soll, so führe im Package von A Interfaces ein, welches die von B benötigten Methoden hält. Implementiere diese Interfaces in den entsprechenden Klassen von Package B. Somit wurde die Abhängigkeit zwischen Package A und B invertiert.
- Restrukturierung der Packages: Sammle alle Klassen eines Zyklus in einem eigenen Package zusammen und führe ein oder mehrere neue Packages ein, befüllt mit den Klassen, von denen die Klassen außerhalb des Zyklus abhängen
Stable-Dependencies-Prinzip
{{#if: Stable-Dependencies-Prinzip|{{#ifexist:Stable-Dependencies-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Stable-Dependencies-Prinzip besagt, dass die Abhängigkeiten zwischen Modulen in Richtung der größeren Stabilität der Module gerichtet sein sollten. Ein Modul sollte also nur von Modulen abhängig sein, welche stabiler sind als es selbst.
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|The dependencies between packages in a design should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable that it is.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|The dependencies between packages in a design should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable that it is.}}“
| {{#invoke:Text|quoteUnquoted| The dependencies between packages in a design should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable that it is. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|The dependencies between packages in a design should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable that it is.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Die Abhängigkeiten zwischen Packages sollten in derselben Richtung wie die Stabilität verlaufen. Ein Package sollte nur von Packages abhängen, welche stabiler als es selbst sind.Robert C. MartinStability || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Die Abhängigkeiten zwischen Packages sollten in derselben Richtung wie die Stabilität verlaufen. Ein Package sollte nur von Packages abhängen, welche stabiler als es selbst sind.Robert C. MartinStability || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Die Abhängigkeiten zwischen Packages sollten in derselben Richtung wie die Stabilität verlaufen. Ein Package sollte nur von Packages abhängen, welche stabiler als es selbst sind.
|
„Die Abhängigkeiten zwischen Packages sollten in derselben Richtung wie die Stabilität verlaufen. Ein Package sollte nur von Packages abhängen, welche stabiler als es selbst sind.“{{#if: Robert C. MartinStability || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Stability
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: The dependencies between packages in a design should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable that it is. | {{
#if: | {{#if: The dependencies between packages in a design should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable that it is. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Stability |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Die Abhängigkeiten zwischen Packages sollten in derselben Richtung wie die Stabilität verlaufen. Ein Package sollte nur von Packages abhängen, welche stabiler als es selbst sind. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}} Unter Stabilität versteht man hier das umgekehrte Verhältnis der ausgehenden Abhängigkeiten zur Summe aller Abhängigkeiten. Je weniger Abhängigkeiten ein Modul zu anderen hat und je mehr Abhängigkeiten andere Module zu diesem Modul haben, umso stabiler ist das Modul. Die Stabilität berechnet sich indirekt über die Instabilität folgendermaßen:
<math>I=\frac{Aa}{(Ae+Aa)}</math>
I … Instabilität eines Moduls
Ae … eingehende Abhängigkeiten ({{#invoke:Vorlage:lang|full|CODE=en|SCRIPTING=Latn|SERVICE=englisch}})
Aa … ausgehende Abhängigkeiten (efferent couplings)
wobei sich <math>Ae</math> und <math>Aa</math> folgendermaßen berechnen:
- <math>Ae</math> = Klassen außerhalb des Moduls, welche von Klassen innerhalb des Moduls abhängen
- <math>Aa</math> = Klassen des Moduls, welche von Klassen außerhalb des Moduls abhängen
Die Instabilität liegt im Bereich von 0 bis 1, eine Instabilität von 0 weist auf ein maximal stabiles Modul hin, eine von 1 auf ein maximal instabiles Modul.
Stable-Abstractions-Principle
{{#if: Stable-Abstractions-Prinzip|{{#ifexist:Stable-Abstractions-Prinzip|
|{{#if: |{{#ifexist:{{{2}}}|
|{{#if: |{{#ifexist:{{{3}}}|
|}}|}}|}}|}}|}}|Einbindungsfehler: Die Vorlage Hauptartikel benötigt immer mindestens ein Argument.}}
Das Stable-Abstractions-Prinzip fordert, dass die Abstraktheit eines Moduls direkt proportional zu seiner Stabilität sein muss.
{{#ifeq: {{{vor}}}@@-@@{{{nach}}} | -@@-@@-
| {{#if:trim|Packages that are maximally stable should be maximally abstract. Instable packages should be concrete. The abstraction of a package should be in proportion to its stability.}}
| {{#ifeq: {{#if:|{{{vor}}}|@#@}}{{#if:|{{{nach}}}|@#@}} | @#@@#@
| {{#ifeq: en | de
| „{{#if:trim|Packages that are maximally stable should be maximally abstract. Instable packages should be concrete. The abstraction of a package should be in proportion to its stability.}}“
| {{#invoke:Text|quoteUnquoted| Packages that are maximally stable should be maximally abstract. Instable packages should be concrete. The abstraction of a package should be in proportion to its stability. | en }} }}
| {{#ifeq: {{#if:|{{{vor}}}|-}} | -
| „
| {{{vor}}} }}{{#if:trim|Packages that are maximally stable should be maximally abstract. Instable packages should be concrete. The abstraction of a package should be in proportion to its stability.}}{{
#ifeq: {{#if:|{{{nach}}}|-}} | -
| “
| {{{nach}}} }} }} }}{{
#if: Packages, die maximal stabil sind, sollten maximal abstrakt sein. Instabile Packages sollten konkret sein. Die Abstraktheit eines Packages sollte proportional zu seiner Stabilität sein.Robert C. MartinStability || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
{{#if:
|
„{{{Latn}}}“{{#if: Packages, die maximal stabil sind, sollten maximal abstrakt sein. Instabile Packages sollten konkret sein. Die Abstraktheit eines Packages sollte proportional zu seiner Stabilität sein.Robert C. MartinStability || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}{{#if: Packages, die maximal stabil sind, sollten maximal abstrakt sein. Instabile Packages sollten konkret sein. Die Abstraktheit eines Packages sollte proportional zu seiner Stabilität sein.
|
„Packages, die maximal stabil sind, sollten maximal abstrakt sein. Instabile Packages sollten konkret sein. Die Abstraktheit eines Packages sollte proportional zu seiner Stabilität sein.“{{#if: Robert C. MartinStability || <ref>{{#invoke:Vorlage:Literatur|f}}</ref> }}
}}|{{#if: Stability
|}}}}
{{#if: <ref>{{#invoke:Vorlage:Literatur|f}}</ref> |
{{#if: {{#invoke:Text|unstrip|<ref>{{#invoke:Vorlage:Literatur|f}}</ref>}}
| }} }}{{#if: Packages that are maximally stable should be maximally abstract. Instable packages should be concrete. The abstraction of a package should be in proportion to its stability. | {{
#if: | {{#if: Packages that are maximally stable should be maximally abstract. Instable packages should be concrete. The abstraction of a package should be in proportion to its stability. |
Vorlage:Zitat: Doppelangabe 1=Text=}}
}}| }}{{#if: | {{#if: Robert C. Martin |
Vorlage:Zitat: Doppelangabe 2=Autor=}}
}}{{#if: | {{#if: Stability |
Vorlage:Zitat: Doppelangabe 3=Quelle=}}
}}{{#if: | {{#if: |
Vorlage:Zitat: Doppelangabe Umschrift=Latn=}}
}}{{#if: en | {{#if: |
Vorlage:Zitat: Doppelangabe Sprache=lang=}}
}}{{#if: Packages, die maximal stabil sind, sollten maximal abstrakt sein. Instabile Packages sollten konkret sein. Die Abstraktheit eines Packages sollte proportional zu seiner Stabilität sein. | {{#if: |
Vorlage:Zitat: Doppelangabe Übersetzung=de=}}
}} Je abstrakter ein Modul ist – d. h. je mehr Interfaces, abstrakte Klassen und Methoden es hat –, desto stabiler sollte es sein. Generell errechnet sich die Abstraktheit eines Moduls folgendermaßen:
<math>A=\frac{Ka}{K}</math>
A … Abstraktheit eines Moduls
Ka … Anzahl abstrakter Klassen eines Moduls
K … Gesamtanzahl der Klassen eines Moduls
Für jedes Modul lässt sich die Distanz zur idealen Linie – {{#invoke:Vorlage:lang|full|CODE=en|SCRIPTING=Latn|SERVICE=englisch}} genannt – zwischen maximaler Stabilität und Abstraktheit und maximaler Instabilität und Konkretheit errechnen. Diese reicht von 0 bis ≈0,707:
<math>D=\frac{A+I-1}{\sqrt 2}</math>
D … Distanz zur idealen Linie
A … Abstraktheit eines Moduls
I … Instabilität eines Moduls
Je größer die Distanz ist, desto schlechter ist das Stable-Abstractions-Prinzip erfüllt.
Siehe auch
- Ockhams Rasiermesser – ein Sparsamkeitsprinzip aus der Wissenschaftstheorie
- Entwurfsmuster – lösen wiederkehrende Entwurfsprobleme basierend auf den Designprinzipien
- GRASP – Entwurfsmuster, mit denen die Zuständigkeit bestimmter Klassen objektorientierter Systeme festgelegt wird
- Domain-driven Design – Vorgehensmodell zur Modellierung komplexer Softwaresysteme
Literatur
- {{#invoke:Vorlage:Literatur|f}}
- {{#invoke:Vorlage:Literatur|f}}
- {{#invoke:Vorlage:Literatur|f}}
- {{#invoke:Vorlage:Literatur|f}}
Weblinks
Einzelnachweise
<references />
Vorlage:Navigationsleiste Prinzipien objektorientierten Designs