Drobne programowanie

Kaczuś zaprasza do opowieści o algorytmach, językach programowania i strukturach danych

Na stronie stosowane są pliki cookies. Więcej na podstronie.
odsłon: 979

Programowanie obiektowe w C: Hermetyzacja

W poprzednim odcinku pisałem, że zajmiemy się hermetyzacją. W języku C hermetyzację najłatwiej uzyskać poprzez ukrycie części prywatnych w plikach *.c, natomiast część publiczną w plikach *.h (nagłówkowych).

Załóżmy, że mamy te same typy co w poprzednim odcinku. Powiedzmy, że chcemy aby można było tworzyć obiekt takiego typu, niszczyć go, tworzyć kopię, zmieniać jego wartość oraz wypisać zawartość. Implementację, jak i konstrukcje obiektów proponuję ukryć.
Skąd takie podejście? Ano stąd, że gdy przyjdzie nam w przyszłości zmienić troszkę typ (np dodając dodatkowe pola w obiekcie, ponieważ chcemy w innym projekcie zwiększyć jego użyteczność, albo nawet w tym samym projekcie wykorzystać w nieco inny sposób), to nie będziecie musieli myśleć, czy wpłynie to na kod wykorzystujący ten obiekt w innym miejscu, ponieważ tam korzystaliśmy z funkcji pośredniczącej, która nam gwarantuje właśnie to, że obiekt w tamtym miejscu bedzie dalej działał prawidłowo. Tak więc podstawowa wartość hermetyzacji, to utrzymanie kompatybilności na poziomie źródeł programu. Ale wystarczy "gadania", przejdźmy do przykładu.

Jeśli zajrzycie do środka paczki z przykładem, to zauważycie dodatkowe 4 pliki w stosunku do przykładu z poprzedniego odcinka. Są to 2 pliki nagłówkowe, i 2 pliki z definicjami. Każda para nagłówek i kod właściwy dotyczy konkretnego stworzonego typu. W plikach nagłówkowych mamy
  • deklarację nowego typu:
    struct myIntegerObj;
    ....
    struct myTextObj;
    
  • deklaracje funkcji
    struct myIntegerObj *CreateIntegerObj(int aval);
    int SetIntegerObjValue(struct myIntegerObj *aobj, int aval);
    void PrintIntegerObjValue(struct myIntegerObj *aobj);
    
    .....
    
    struct myTextObj *CreateTextObj(const char* astr);
    int SetTextObjValue(struct myTextObj *aobj, const char *astr);
    void PrintTextObjValue(struct myTextObj *aobj);
    
Jak widzimy, dla każdego z obiektów mamy poza funkcją tworzącą obiekt, zadeklarowane również funkcje zmieniające wartość obiektu, jak i drukującą tą wartość (wypisujemy tu informacje na konsoli funkcją printf). Oczywiście można by to uzyskać bardziej elegancko, ale o tym będzie w odcinku o polimorfiźmie.
Przejdźmy zatem do plików z definicjami (*.c). Tu mamy już pełny opis typów. Typ przechowujący tekst pozwoliłem sobie wzbogacić o dodatkowe pole z informacją o wielkości zaalokowanej pamięci na dane tekstowe. Uprościłem troszkę funkcję zmiany wartości tego tekstowego obiektu, maksymalna długość tekstu jaki zostanie zapamiętany przy zmianie wartości to wielkość tekstu, którym inicjujemy obiekt.
Proszę zwrócić uwagę, iż przed każdą funkcją, która nie jest zadeklarowana w pliku nagłówkowym, stoi etykieta static. Ten manewr ograniczy nam skutecznie widoczność tych metod tylko do tego pliku i zniweluje ewentualne problemy w przyszłości.

Gdy już wszystko mamy napisane jak należy, to teraz tworzymy krótki program testowy:
int main()
{
    struct myTextObj *txta, *txtb;
    struct myIntegerObj *iobja, *iobjb;
    txta = CreateTextObj("Mój Text 1");
    iobja = CreateIntegerObj(7);
    txtb = (struct myTextObj *)CloneDefaultObject((struct TDefaultObj *)txta);
    iobjb = (struct myIntegerObj *)CloneDefaultObject((struct TDefaultObj *)iobja);
    SetTextObjValue(txtb, "Mój Text 2");
    SetIntegerObjValue(iobjb, 14);

    PrintTextObjValue(txta);
    PrintTextObjValue(txtb);
    PrintIntegerObjValue(iobja);
    PrintIntegerObjValue(iobjb);


    FreeDefaultObject((struct TDefaultObj *)txtb);
    FreeDefaultObject((struct TDefaultObj *)iobjb);
    FreeDefaultObject((struct TDefaultObj *)iobja);
    FreeDefaultObject((struct TDefaultObj *)txta);

    return 0;
}
W wyniku działania takiego programu powinniśmy uzyskać:
Wynik działania programu przykładowego
Na tym kończę odcinek i serdecznie zapraszam na kolejny.
Tomasz Kaczanowski

2013-09-12 20:32:25


C obiektowość programowanie obiektowe hermetyzacja język C Tomasz Kaczanowski Kaczuś