Zastanawiam się w jaki sposób rozwiązać problem hermetyzacji danych w obiektach agregujących inne obiekty.
public class CustomModel : ICloneable
{
private int _age;
public int Age
{
get { return this._age;}
set { this._age=value;}
}
public override object Clone()
{
return this.MemberwiseClone();
}
}
public class SafeClass
{
private CustomModel _model;
public SafeClass(CustomModel model)
{
// wersja 1
this._model = model;
// wersja 2 (klonowanie wewnatrz konstruktora)
this._model = (CustomModel)model.Clone();
}
}
Jeżeli napiszemy kod klasy SafeClass w wersji 1, a nastepnie utworzymy jej instację, np:
CustomModel cm = new CustomModel();
cm.Age = 20;
SafeClass sc = new SafeClass(cm);
cm.Age = 40; //==> możliwa manipulacja zawartością obiektu sc ! (brak hermetyzacji)
mozliwe będzie modyfikowanie prywatnej zmiennej klasy SafeClass z zewnątrz tej klasy.
Problem można rozwiązać, np tak:
SafeClas sc = new SafeClass((CustomModel)cm.Clone());
Jednak należałoby założyć, że użytkownik naszej klasy w natłoku innych pilnych spraw, zapomni sklonować obiekt przed przekazaniem go do konstruktora. Wówczas nasza klasa SafeClass będzie narażona na modyfikację z zewnątrz. Jeżeli konstruktor klasy SafeClass będzie sam dokonywać klonowania (wersja 2), nasza klasa będzie bezpieczna. W takim jednak przypadku, jeżeli użtykownik naszej klasy jest świadomy zagrożenia związanego z przekazywaniem referencji do innego obiektu, a nie zna kodu naszej klasy (bo nie musi) i świadomie dokona klonowania (jak powyżej), wówczas wykonają się dwa klonowania (w tym jedno zbędne).
Czy ktoś kiedyś zastanawiał się nad takim problemem. Jakieś wasze przemyślenia w temacie ? Jak najrozsądniej podejść do sprawy ?
Pozdrawiam