Datenkapselung
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Datenkapselung
Ich habe eine Objektklasse (Für allgemeine Objekte in der Spielwelt), die eine Reihe von Komponenten besitzt, welche das Objekt quasi 'definieren'. Jetzt müssen diese Komponenten aber auf das Objekt zugreifen und es verändern können. Natürlich würde ich Attribute wie die Position in der Objektklasse gerne private machen, aber dann könnten die Komponenten nicht mehr direkt darauf zugreifen. Ich würde ja gerne mit friend arbeiten, aber das wird nicht vererbt, weswegen ich sämtliche Komponenten einzeln eintragen müsste, was dann auch keinen Sinn macht.
Im Moment tendiere ich dazu, die Attribute einfach public zu machen, denn quasi leere Getter/Setter sind ja eigentlich auch nichts anderes. Aber es fühlt sich irgendwie auch "böse" an, weil es ja irgendwie ein Grundsatz ist, Attribute private zu machen. Es ist ja auch toll, wenn man z.B. die Implementierung getrennt vom Interface ändern kann, aber in meinem Fall würde das wohl nie Sinn machen, da Objekte und Komponenten ja sehr eng zusammen arbeiten müssen.
Irgendwelche Vorschläge?
Im Moment tendiere ich dazu, die Attribute einfach public zu machen, denn quasi leere Getter/Setter sind ja eigentlich auch nichts anderes. Aber es fühlt sich irgendwie auch "böse" an, weil es ja irgendwie ein Grundsatz ist, Attribute private zu machen. Es ist ja auch toll, wenn man z.B. die Implementierung getrennt vom Interface ändern kann, aber in meinem Fall würde das wohl nie Sinn machen, da Objekte und Komponenten ja sehr eng zusammen arbeiten müssen.
Irgendwelche Vorschläge?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Brainsmith
- Establishment
- Beiträge: 109
- Registriert: 04.09.2009, 13:52
- Echter Name: Fabbo
Re: Datenkapselung
Ich weiß ja nicht, wie du es implemetiert hast, aber kannst du den Components nicht einfach nen Pointer auf die Owner-Entity geben?? (im Konstuktor)
Re: Datenkapselung
Ja, das mach ich ja. Aber über diesen Pointer kann man ja trotzdem nur auf öffentliche Attribute des Entity zugreifen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: Datenkapselung
Warum keine public-Methoden die die private Members in gewünschter Weise verändern?
Also statt:
lieber
Ist zwar mehr Schreibarbeit ist aber ordentlich gekapselt. Weiterhin kannst du in den Methoden auch komplexere Abfragen einbauen, Exceptions werfen, Log schreiben usw. und du kannst für verschiedene Zwecke verschiedene Methoden implementieren die auf demselben Member operieren. Kapselung heißt, dass sich Objekte nur selbst verändern (durch die methoden) und nicht direkt von außen verändert werden können. So kann die Konsistenz des Objektes besser gewährleistet werden.
Also statt:
Code: Alles auswählen
class test
{
public int count;
}
test.count = test.count + 1;
Code: Alles auswählen
class test
{
private int count;
public IncrementCount() {count++;}
}
test.IncrementCount();
- Brainsmith
- Establishment
- Beiträge: 109
- Registriert: 04.09.2009, 13:52
- Echter Name: Fabbo
Re: Datenkapselung
Entweder Set/Get-Methoden oder so, wie Despotist sagt..
Wenn die Komponente was verändern muss, braucht es auch die erforderlichen Daten.
Wenn die Komponente was verändern muss, braucht es auch die erforderlichen Daten.
- Chromanoid
- Moderator
- Beiträge: 4263
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Datenkapselung
Bei Spielen, die von einem kleinen Personenkreis entwickelt werden, halte ich solche Konzepte für eher vernachlässigbar. Datenkapselung ist dann sinnvoll, wenn man auch spürbare Vorteile davon hat. Wenn man bei einem kleinen Spiel, an dem man vielleicht ein halbes Jahr arbeitet, Variablen und Funktionen gerne public machen möchte und man dadurch bugfreiheit nicht signifikant gefährded, sollte man das IMO ohne schlechtes Gewissen tun. Das ist einfach zeitsparender, bequemer und wesentlich sauberer als immer kompliziert um irgendwelche Architekturkonzepte herum zu bauen.
-
- Beiträge: 91
- Registriert: 07.12.2009, 16:42
- Echter Name: Fabian R
Re: Datenkapselung
In dem Zusammenhang sind C#'s anonyme Properties (public int foo {get; set}; oder so) sehr interessant.
Man kann erst mal seine Variablen vollkommen public machen und spart Schreibarbeit, aber später noch Prüfungen einbauen die Werte testen, ohne dass sich die Benutzung ändert.
Schade, dass es das nur da gibt. ;)
Edit: Generell würde ich also Setter/Getter vorziehen, da man so halt einfach später noch Kontrollen einbauen kann und moderne IDE's die auch automatisch generieren.
Man kann erst mal seine Variablen vollkommen public machen und spart Schreibarbeit, aber später noch Prüfungen einbauen die Werte testen, ohne dass sich die Benutzung ändert.
Schade, dass es das nur da gibt. ;)
Edit: Generell würde ich also Setter/Getter vorziehen, da man so halt einfach später noch Kontrollen einbauen kann und moderne IDE's die auch automatisch generieren.
Zuletzt geändert von zwergmulch am 27.06.2010, 11:52, insgesamt 1-mal geändert.
- Chromanoid
- Moderator
- Beiträge: 4263
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Datenkapselung
ja die empfinde ich auch als königsweg für dieses problem...
- Krishty
- Establishment
- Beiträge: 8268
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Datenkapselung
Ich würde auch zu dem tendieren, was Despotist vorgeschlagen hat … also quasi Move()-Methoden statt auf dem .Position-Member zu arbeiten oder Getter und Setter zu implementieren.
Das krasse Gegenteil davon, was mir aber auch legitim vorkäme, wäre, alle komponentenspezifischen Objekteigenschaften in ein struct zu packen (Daten von Logik zu trennen) und das den Komponenten über einen einzigen Getter und Setter zur Verfügung zu stellen.
Gruß, Ky
Das krasse Gegenteil davon, was mir aber auch legitim vorkäme, wäre, alle komponentenspezifischen Objekteigenschaften in ein struct zu packen (Daten von Logik zu trennen) und das den Komponenten über einen einzigen Getter und Setter zur Verfügung zu stellen.
Sowas ist nie vernachlässigbar. Genau sowas hält den Verstand fit für das nächste Mal, wenn man so ein Problem für einen „großen Personenkreis“ lösen muss.Chromanoid hat geschrieben:Bei Spielen, die von einem kleinen Personenkreis entwickelt werden, halte ich solche Konzepte für eher vernachlässigbar.
Gruß, Ky
- Chromanoid
- Moderator
- Beiträge: 4263
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Datenkapselung
Naja man sollte auch immer abwägen inwiefern der Aufwand seinen Verstand in diesem Sinne fit zu halten gerechtfertigt ist... Solange man sich darüber bewusst ist, dass das so in anderen Projekten vielleicht nicht geht, sehe ich da nicht immer eine Notwendigkeit. So eine Entscheidung seinen Geist für vernünftige OOP Programmierung fit zu halten ist ja auch immer eine Frage der Zeit/des Geldes...Krishty hat geschrieben:Sowas ist nie vernachlässigbar. Genau sowas hält den Verstand fit für das nächste Mal, wenn man so ein Problem für einen „großen Personenkreis“ lösen muss.Chromanoid hat geschrieben:Bei Spielen, die von einem kleinen Personenkreis entwickelt werden, halte ich solche Konzepte für eher vernachlässigbar.
Re: Datenkapselung
Der Vorteil von extra Methoden ist ganz klar die Wartbarkeit, der Nachteil ganz klar der Aufwand.
Ich würde Methoden bauen, da Du heute ja nicht weisst welche Erweiterungen Du in Zukunft vornehmen willst, Du willst ja nicht überall in Deinem Code rumgraben nur weil z.B. beim setzen der Position eine zusätzliche Prüfung her muss. Bei den "public" Variablen müsstest die Prüfung dann überall beim Zugriff auf die Variable einbauen, oder spätestens dann anfangen alles zu kapseln, also kannst das auch gleich machen. :)
Ich würde Methoden bauen, da Du heute ja nicht weisst welche Erweiterungen Du in Zukunft vornehmen willst, Du willst ja nicht überall in Deinem Code rumgraben nur weil z.B. beim setzen der Position eine zusätzliche Prüfung her muss. Bei den "public" Variablen müsstest die Prüfung dann überall beim Zugriff auf die Variable einbauen, oder spätestens dann anfangen alles zu kapseln, also kannst das auch gleich machen. :)
Re: Datenkapselung
Ich finde das ist eher eklig. Ähnlich wie die Möglichkeit, dass = überladen ist. Ich muss sagen dass ich selber bei Wenige-Leute-Projekten meine getter/setter Zeit überwunden habe. Wenn man z.B. in Java Ding.eigenschaft=5; schreibt, dann hat man immerhin im Griff was in diesem Moment passiert. Bei C++ Überladung und C# Properties muss ich an jeder =, += etc. Stelle genauso argwönisch sein was ich damit eigentlich auslöse. Bei kleinen Projekten verzichte ich mittlerweile auf getter/setter soweit es geht, ich habe auch kein Problem damit wenn es denn doch notwendig wird eine Stunde umzubauen. Letzlich gilt das aber alles nur weil ich den kompletten Code in der Hand habe bzw. auf alle Beteiligten Einfluss nehmen kann. Bei externe Libs ist das nat. nicht zu machen, hier kenne ich aber auch die ganze Palette an Ekelkram: getter + setter die blocken, getter deren Rückgabe nicht dem gesetten gleicht, getter und setter die manchmal unkalkulierbar lange dauern etc.zwergmulch hat geschrieben:In dem Zusammenhang sind C#'s anonyme Properties (public int foo {get; set}; oder so) sehr interessant.
...
Schade, dass es das nur da gibt. ;)
Re: Datenkapselung
@exploid
Es geht hier um ein Spiel und nicht um eine Bibliothek die potentiell von vielen anderen benutzt wird, daher denke ich nicht, dass getter/setter hier Sinn machen. Sollte ich irgendwann eine Überprüfung einbauen wollen, muss ich nur die entsprechende Funktion erstellen und die 50 trivialen Compilerfehler abarbeiten, was im Zweifelsfalle mit suchen/ersetzen geht. Das dauert dann ungefähr 5 Minuten. Aber bis dahin habe ich eine übersichtliche und aufgeräumte Klassenschnittstelle weniger Tipparbeit und übersichtlicheren Code (weil weniger () durch Funktionsaufrufe).
Letztendlich geht es mit dem ganzen Kapseln ja darum, dass man keine Daten von außen verändern kann, sobald man einen setter hat, der den Wert einfach so übernimmt, hat man mit ein wenig Arbeit einfach mal gar nichts erreicht. Weil man immer noch genauso von außen zugreifen kann, nur umständlicher.
Es geht hier um ein Spiel und nicht um eine Bibliothek die potentiell von vielen anderen benutzt wird, daher denke ich nicht, dass getter/setter hier Sinn machen. Sollte ich irgendwann eine Überprüfung einbauen wollen, muss ich nur die entsprechende Funktion erstellen und die 50 trivialen Compilerfehler abarbeiten, was im Zweifelsfalle mit suchen/ersetzen geht. Das dauert dann ungefähr 5 Minuten. Aber bis dahin habe ich eine übersichtliche und aufgeräumte Klassenschnittstelle weniger Tipparbeit und übersichtlicheren Code (weil weniger () durch Funktionsaufrufe).
Letztendlich geht es mit dem ganzen Kapseln ja darum, dass man keine Daten von außen verändern kann, sobald man einen setter hat, der den Wert einfach so übernimmt, hat man mit ein wenig Arbeit einfach mal gar nichts erreicht. Weil man immer noch genauso von außen zugreifen kann, nur umständlicher.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Krishty
- Establishment
- Beiträge: 8268
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Datenkapselung
Das Überladen von Operatoren kann nicht mehr versteckte Gefahren bergen als jede andere Funktion auch (siehe [url=ttp://james-iry.blogspot.com/2009/03/operator-overloading-ad-absurdum.html]hier[/url]). Und ich finde sogar ganz im Gegenteil, dass Properties die einzige Möglichkeit sind, bei der man sicher weiß, was passiert.dronus hat geschrieben:Ich finde das ist eher eklig. Ähnlich wie die Möglichkeit, dass = überladen ist. Ich muss sagen dass ich selber bei Wenige-Leute-Projekten meine getter/setter Zeit überwunden habe. Wenn man z.B. in Java Ding.eigenschaft=5; schreibt, dann hat man immerhin im Griff was in diesem Moment passiert. Bei C++ Überladung und C# Properties muss ich an jeder =, += etc. Stelle genauso argwönisch sein was ich damit eigentlich auslöse.
Re: Datenkapselung
Leider noch mehr Tipperei und Kopfarbeit, aber eine gute Möglichkeit dass nur die registrierten Komponenten und niemand sonst z.B. an der Objektposition was ändern können, sehe ich im Observer-Pattern: das Objekt registriert einen Listener zum Event "ChangePosition" bei seiner Komponente. Diese löst nur Events aus statt Eigenschaften des Objekts direkt zu beeinflussen. Das Objekt selbst kümmert sich bei gefeuerten Events dann selbst um die Ausführung und ändert seine Eigenschaften, welche dadurch auch private bleiben können.
Das wäre im allereinfachsten Fall eine private Funktion im Objekt, deren Referenz gezielt an die Komponente weitergegeben wird, welche sie dadurch bei Bedarf aufrufen darf. Wer die Referenz nicht hat, darfs auch nicht. Und da die Referenz in der Komponente ebenfalls private bleiben kann, bleibt diese auch hier nach außen geheim.
Ich habe hier gerade nur AS zur Verfügung, aber ich glaube damit wirds klar:
Das wäre im allereinfachsten Fall eine private Funktion im Objekt, deren Referenz gezielt an die Komponente weitergegeben wird, welche sie dadurch bei Bedarf aufrufen darf. Wer die Referenz nicht hat, darfs auch nicht. Und da die Referenz in der Komponente ebenfalls private bleiben kann, bleibt diese auch hier nach außen geheim.
Ich habe hier gerade nur AS zur Verfügung, aber ich glaube damit wirds klar:
Code: Alles auswählen
public class PLObject{
private var x:Number;//private position
//add a new component to this object
public function registerComponent(component:PLComponent){
component.changePositionX=setPositionX;//register event listener for event "changePositionX"
}
//event handler for event "changePositionX"
private function setPositionX(value:Number){
x=value;
trace("PLObject: position x is set to "+x);//log output
}
}
public class PLComponent{
private var _changePositionX:Function;//event handler for event "changePositionX"
//register a handler function for event "changePositionX"
public function set changePositionX(handler:Function){
_changePositionX=handler;
}
//test changing a private value in parent object
public function updateX(anyValue:Number){
if(_changePositionX)_changePositionX(anyValue);// fire event "changePositionX" if it has a handler
}
}
//test it!
var myObject:PLObject=new PLObject();
var myComponent:PLComponent=new PLComponent();
myObject.registerComponent(myComponent);//add component to object
myComponent.updateX(15);// --> "PLObject: position x is set to 15"
//other ways to acces the PLObject property "x" will fail:
//myObject.x=8;//error
//myObject.setPositionX(8);//error
//myComponent.changePositionX(8);//error
Re: Datenkapselung
Naja bei den set/get Methoden, bauste halt nur Deine zusätzliche Prüfung und brauchst keine 50 Compiler-Fehler abarbeiten.Jonathan hat geschrieben:@exploid
Es geht hier um ein Spiel und nicht um eine Bibliothek die potentiell von vielen anderen benutzt wird, daher denke ich nicht, dass getter/setter hier Sinn machen. Sollte ich irgendwann eine Überprüfung einbauen wollen, muss ich nur die entsprechende Funktion erstellen und die 50 trivialen Compilerfehler abarbeiten, was im Zweifelsfalle mit suchen/ersetzen geht. Das dauert dann ungefähr 5 Minuten. Aber bis dahin habe ich eine übersichtliche und aufgeräumte Klassenschnittstelle weniger Tipparbeit und übersichtlicheren Code (weil weniger () durch Funktionsaufrufe).
Letztendlich geht es mit dem ganzen Kapseln ja darum, dass man keine Daten von außen verändern kann, sobald man einen setter hat, der den Wert einfach so übernimmt, hat man mit ein wenig Arbeit einfach mal gar nichts erreicht. Weil man immer noch genauso von außen zugreifen kann, nur umständlicher.
Ist aber ja letztlich Dein Code, und wenn Du mit suchen/ersetzen arbeiten willst, mach das. :)