Come mantenere pulito il codice con l’incapsulamento degli oggetti

Incapsulamento significa mantenere qualcosa di isolato. Se metti qualcosa in una capsula, il mondo esterno non può accedervi. L'incapsulamento è un concetto importante nella programmazione orientata agli oggetti perché aiuta a mantenere gestibile il codice complesso.

Perché hai bisogno di lezioni

Supponiamo che tu abbia un'app per zoo con centinaia di migliaia di righe di codice. Ora immagina che ci sia un oggetto molto importante che è centrale per l'intera applicazione, chiamato animale . E se ogni singola parte del programma che era un animale potesse accedere e modificare quell'oggetto?

L'accesso illimitato causerebbe molto caos. Se un maialino usa un animale per definire i suoi parametri, allora l' animale avrà attributi maialino . Supponiamo ora che una capra decida di utilizzare l' animale per definire i suoi parametri.

In JavaScript / TypeScript, sarebbe simile a questo:

 var animal = {name: "piglet", legs: 4, color: "pink", decoration: "snout"}
animal.name = "goat"
animal.decoration = "horns"

La prossima cosa che sai, hai capre rosa e maialini con le corna. Guarda il codice in azione nella sandbox TypeScript, quindi fai clic su Esegui per visualizzare l'output della console.

Se stai imparando a programmare e desideri ispirazione oltre a creare una fattoria didattica, ecco altri 10 progetti per ispirarti .

Poiché la tua base di codice è così grande, potrebbero essere necessarie centinaia di ore per trovare il codice che dà ai tuoi agnelli i colli di lama e la lana ai tuoi anatroccoli. E una volta trovato il codice incriminato, dovrai scrivere ancora più codice spaghetti per evitare che gli oggetti interferiscano tra loro. Deve esserci un modo migliore.

Il modo per risolvere il problema della sovrapposizione è definire gli oggetti con le classi. Qualsiasi parte del codice può creare un oggetto basato sulla definizione della classe. La creazione di un oggetto univoco si chiama istanziazione. Garantisce che ogni oggetto creato avrà le proprie proprietà. E quegli oggetti non saranno in grado di interferire tra loro accidentalmente.

Le lezioni non bastano; Anche le variabili oggetto devono essere incapsulate

Quindi abbiamo deciso che ogni animale ha bisogno del proprio oggetto. Creiamo una classe che definirà i nostri animali.

 class Animal {
name: string;
legs: number;
color: string;
decoration: string;
constructor(name: string, legs: number, color: string, decoration: string) {
this.name = name;
this.legs = legs;
this.color = color;
this.decoration = decoration;
}
}

Successivamente, creiamo un paio di oggetti animali.

 let babyDuck = new Animal("baby duck", 2, "yellow", "beak");
let bunny = new Animal("bunny", 4, "gray", "floppy ears");

Gioca con il codice finora.

Ora possiamo aggiungere tutti gli animali che vogliamo senza strane mutazioni. Oppure possiamo?

Cosa succederebbe se una notte un programmatore stanco scrivesse del codice per modificare un animale dall'app raccapricciante, ma modificasse il coniglio per errore?

 bunny.color = "black";
bunny.legs = 8;

I conigli ragno non sono belli, amico! È altrettanto grave come quando non abbiamo incapsulato il nostro codice in oggetti. Assicuriamoci che non accada mai più.

La prima cosa che dobbiamo fare è rendere privati ​​i nostri oggetti. Ciò significa che nulla può modificare le nostre variabili direttamente dopo averle create. Ecco il codice che mostra che la modifica delle variabili private crea un errore .

Tuttavia, le variabili devono essere modificabili. Ed è qui che entrano in gioco getter e setter .

Getter e setter sono funzioni che accedono e modificano le variabili in modo controllato. I setter possono impostare limitazioni sui dati che vengono modificati. E i getter possono alterare i dati che vengono recuperati.

Questo è l'aspetto della nostra classe con le funzioni get e set per controllare il conteggio delle gambe.

 class Animal {
private _name: string;
private _legs: number;
private _color: string;
private _decoration: string;
constructor(name: string, legs: number, color: string, decoration: string) {
this._name = name;
this._legs = legs;
this._color = color;
this._decoration = decoration;
}
get legs() {
return this._legs;
}
set legs(legCount: number) {
if(legCount > 1 && legCount < 5) {
this._legs = legCount;
}
}
}

Impara l'incapsulamento ed evita le variabili globali

Ecco il codice finale. Riassumi ciò che hai imparato per assicurarti la tua comprensione:

  • Aggiungi getter e setter per il resto delle variabili.
  • Restituisci il nome dell'animale come tag span: <span> llama </span>
  • Modificare la variabile di decorazione per consentire più decorazioni. Crea un getter e un setter appropriati per riflettere quel cambiamento.

Se vuoi mantenere il tuo codice in esecuzione come una macchina ben oliata, devi assolutamente usare l'incapsulamento. Evita le variabili globali a tutti i costi. E se hai bisogno di condividere variabili tra oggetti, puoi visualizzare la documentazione TypeScript su come creare variabili di classe / statiche per imparare come.