Ok taki prosty przykład, skoro to ma być tylko fragment referatu:
Mamy dwie klasy które mają mniej więcej to samo zastosowanie, przy czym jedna używa hermetyzacji a druga nie
class Wektor
{
public:
int x;
int y;
double length;
Wektor(int xx, int yy):x(xx),y(yy)
{
length = sqrt(x*x+y*y);
}
};
class WektorHermetyczny
{
private:
int x;
int y;
double length;
public:
Wektor(int xx, int yy):x(xx),y(yy)
{
recalculateLength();
}
int getX()
{
return x;
}
void setX(int newX)
{
x=newX;
recalculateLength();
}
int gety()
{
return y;
}
void setY(int newY)
{
y=newY;
recalculateLength();
}
double getLength()
{
return length;
}
private:
void recalculateLength()
{
length = sqrt(x*x+y*y);
}
};
I mamy przykładowe kody które korzystają z tych klas:
Wektor pierwszy(1,2);
cout<< pierwszy.x <<" "<<pierwszy.y<<" "<<pierwszy.length<<endl;
WektorHermetyczny drugi(1,2);
cout<< pierwszy.getX() <<" "<<pierwszy.getY()<<" "<<pierwszy.getLength()<<endl;
Wydaje się że w zasadzie nie ma większej różnicy. Otóż jest dość fundamentalna: pole length wynika z wewnętrznego stanu naszego obiektu (tzn z X i Y). Uzytkownik jednak moze sobie dowolnie tą wartość zmienić (nawet nieumyślnie). Co więcej, gdybyśmy postanowili ze chcemy oszczędzić na pamięci programu i zamiast przechowywać tą wartość, po prostu ją wyliczać (co pozwoliłoby nam uniknąć podanego wcześniej problemu) to znów pojawia się kłopot: musimy ten nasz przykładowy kod przepisać...
Rozwiazanie hermetyczne nie dość że pozwala nam uniknąć pierwszego problemu to pozwala nam też dokonać zmiany struktury wewnętrznej klasy bez konieczności modyfikacji kodu który z niej korzysta. Jak? Tak:
class WektorHermetyczny
{
private:
int x;
int y;
public:
Wektor(int xx, int yy):x(xx),y(yy){}
int getX()
{
return x;
}
void setX(int newX)
{
x=newX;
}
int gety()
{
return y;
}
void setY(int newY)
{
y=newY;
}
double getLength()
{
return sqrt(x*x+y*y);
}
};
Z punktu widzenia uzytkownika NIC się nie zmieniło, mimo że dokonaliśmy dość poważnej zmiany w implementacji naszej klasy.