Hermetyzacja i niezmienniki
Ukrywaj stan wewnętrzny, udostępniaj bezpieczne operacje i dbaj o zachowanie niezmienników klasy (np. nieujemnego salda i prawidłowych zakresów).
Hermetyzacja i niezmienniki to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 3 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 3 lekcji w sumie.
Przegląd enkapsulacji
Cel: Ochrona stanu obiektu.
- Enkapsulacja: ukrywaj pola, udostępniaj bezpieczne interfejsy API
- Niezmiennik: reguła, która zawsze jest prawdziwa
- Weryfikuj dane w konstruktorach, setterach i metodach
Interfejs tylko do odczytu
Przechowuj pola jako prywatne. Udostępniaj wywołującym właściwość tylko do odczytu oraz bezpieczne operacje.
using System;
// Expose read-only view; mutate via methods only
public class Counter
{
private int _value; // hidden state
public int Value // read-only to callers
{
get { return _value; }
private set { _value = value; } // keep setter private
}
public void Increment()
{
Value = Value + 1;
}
}
public class Program
{
public static void Main(string[] args)
{
Counter c = new Counter();
c.Increment();
c.Increment();
Console.WriteLine("Value = " + c.Value);
}
}
Zabezpieczenia konstruktorów
Konstruktory ustawiają wymagany stan. Zabezpieczaj je przed nieprawidłowymi danymi wejściowymi, aby obiekty były poprawne od samego początku.
using System;
// Enforce rules early (constructor guard)
public class User
{
public string Name { get; private set; }
public int Age { get; private set; }
public User(string name, int age)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentException("name");
if (age < 0) throw new ArgumentOutOfRangeException("age");
Name = name;
Age = age;
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
User u = new User("Ada", 28);
Console.WriteLine(u.Name + " (" + u.Age + ")");
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
Niezmiennik w praktyce
Zdefiniuj niezmiennik (np. Balance ≥ 0) i egzekwuj go w setterach oraz metodach.
using System;
// Invariant: Balance >= 0 at all times
public class BankAccount
{
private decimal _balance;
public decimal Balance
{
get { return _balance; }
private set
{
if (value < 0) throw new InvalidOperationException("Balance would be negative");
_balance = value;
}
}
public BankAccount(decimal opening)
{
if (opening < 0) throw new ArgumentOutOfRangeException("opening");
_balance = opening;
}
public void Deposit(decimal amount)
{
if (amount <= 0) throw new ArgumentOutOfRangeException("amount");
Balance = Balance + amount;
}
public bool TryWithdraw(decimal amount)
{
if (amount <= 0) return false;
if (Balance - amount < 0) return false;
Balance = Balance - amount;
return true;
}
}
public class Program
{
public static void Main(string[] args)
{
BankAccount a = new BankAccount(50m);
a.Deposit(20m);
bool ok = a.TryWithdraw(100m); // fails, invariant protected
Console.WriteLine("ok=" + ok + " balance=" + a.Balance);
}
}
Ochrona kolekcji
Nie udostępniaj bezpośrednio wewnętrznych list ani tablic. Zwracaj kopię (lub widok tylko do odczytu), aby chronić niezmienniki.
using System;
using System.Collections.Generic;
public class Tags
{
private readonly List<string> _items = new List<string>();
public void Add(string tag)
{
if (string.IsNullOrWhiteSpace(tag)) return;
_items.Add(tag.Trim());
}
// Expose a copy so callers cannot mutate internal list
public List<string> GetAllCopy()
{
return new List<string>(_items);
}
}
public class Program
{
public static void Main(string[] args)
{
Tags t = new Tags();
t.Add(" apple ");
t.Add("banana");
List<string> view = t.GetAllCopy();
view.Add("hacker"); // modifies the copy only
Console.WriteLine("copy count=" + view.Count);
Console.WriteLine("original count=" + t.GetAllCopy().Count);
}
}
Wskazówki dotyczące enkapsulacji
Lista kontrolna:
- Prywatne pola; publiczne właściwości/metody.
- Weryfikuj dane w konstruktorach i setterach.
- Po każdym wywołaniu zachowuj prawdziwość niezmienników.
- Nie ujawniaj wewnętrznych kolekcji.
Zasada enkapsulacji
Podsumowanie
Podsumowanie: Stosuj enkapsulację za pomocą prywatnych pól i interfejsów API z walidacją. Zdefiniuj niezmiennik i egzekwuj go w konstruktorach, setterach oraz metodach. Nigdy nie ujawniaj wewnętrznych kolekcji.
Często zadawane pytania
Czy lekcja „Hermetyzacja i niezmienniki” jest bezpłatna?
Tak — pełny tekst „Hermetyzacja i niezmienniki” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 3 lekcji w sumie.
Co nauczysz się w „Hermetyzacja i niezmienniki”?
Ukrywaj stan wewnętrzny, udostępniaj bezpieczne operacje i dbaj o zachowanie niezmienników klasy (np. nieujemnego salda i prawidłowych zakresów). Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 3.
Ile czasu zajmuje lekcja „Hermetyzacja i niezmienniki”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Pola, właściwości automatyczne i inicjalizatory obiektów
- Konstruktory i elementy statyczne
- Hermetyzacja i niezmienniki