Modyfikatory dostępu – po co mi one?

W poprzednim poście pokazałem, jak wygląda prosta klasa w TypeScript. Teraz czas by wprowadzić kilka dodatkowych elementów. Jedną z rzeczy, która mocno wyróżnia klasy TypeScript, od tych znanych z klasycznego JavaScript, jest możliwość zastosowania modyfikatorów dostępu.

Po co modyfikatory dostępu?

Modyfikatory dostępu mają proste zadanie. Mają one pokazać osobie używającej klasy, która stworzyliśmy, których rzeczy może użyć, a od jakich powinna trzymać się z daleka.

Na przykład mamy klasę służącą do transformacji danych (i tu uwaga, o ile klasa dobrze nadaję się do zobrazowania tematu, to nie jest ona najlepszym rozwiązaniem z punktu designu klasy, ale o tym innym razem)

class DataTransformer {

    data: string;
    reversed: string[];
    transformed: string;

    constructor(data: string) {
       this.data = data;
       this.reversed = [];
       this.transformed = "";
    }

    splitData() : void {
       this.reversed = this.data.split("");
    }

    reverseData() : void {
       this.reversed = this.reversed.reverse();
    }

    joinData() : void {
       this.transformed = this.reversed.join("");       
    }

    transform() : string {
       this.splitData(); 
       this.reverseData();
       this.joinData();
       return this.transformed;  
    }
}

W tym konkretnym przypadku nasza klasa odwraca stringa, czyli “hello” zostanie przetransformowane na “olleh”. Mamy metodę transformującą, która składa się z kliku ‘podfunkcji” – jedna dzieli stringa na tablice, druga odwraca kolejność, trzecia łączy z powrotem do stringa.

Mamy tu jednak kilka problemów. Tej metody “powinno się” używać w taki sposób:

const trans : DataTransformer = new DataTransformer("hello");
console.log(trans.transform());

Jednak w klasycznym JavaScript każdy może wywołać dowolną z czterech metod, w dowolnej kolejności… w dodatku może nam podmieniać dane również w dowolnym momencie, bo ma dostęp do wszystkiego. Więc nic nie stoi na przeszkodzie, by zrobić coś takiego:

trans.reverseData();
trans.transformed = "xxs"; 
trans.splitData();
trans.reversed = ["x", "s"];

I jest to realny problem. Możemy się ratować dokumentacją i komentarzami /* NIE UŻYWAJ TEJ METODY */. Innym wprowadzonym umownym rozwiązaniem jest dodawanie _ przed nazwami zmiennych bądź metod. Tak nazwane elementy klasy przyjęło się, że są tylko do użytku wewnętrznego klasy i nie powinno się ich wołać. Wówczas nasza klasa wyglądałaby tak:

class DataTransformer {

    _data: string;
    _reversed: string[];
    _transformed: string;

    constructor(data: string) {
       this._data = data;
       this._reversed = [];
       this._transformed = "";
    }

    /* INTERNAL METHOD */
    _splitData() : void {
       this._reversed = this._data.split("");
    }

    /* INTERNAL METHOD */
    _reverseData() : void {
       this._reversed = this._reversed.reverse();
    }

    /* INTERNAL METHOD */
    _joinData() : void {
       this._transformed = this._reversed.join("");       
    }

    transform() : string {
       this._splitData(); 
       this._reverseData();
       this._joinData();
       return this._transformed;  
    }
}

Zarówno komentarze i _ to rozwiązanie umowne, wciąż nie ma problemu by ktoś kto chce danej klasy użyć to zrobił.

I tu z pomocą dla programistów przychodzą modyfikatory dostępu, dzięki którym kompilator będzie pilnował by na zewnątrz naszej klasy wykorzystywane były tylko metody do tego przeznaczone.

W następnym wpisie cyklu przyjrzymy się już konkretom, czyli konkretnym modifikatorom dostępu w TypeScript.

Zapraszam do dołączenia do newslettera

Jedna myśl w temacie “Modyfikatory dostępu – po co mi one?”

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *