1. Girişi idarə edirik
İnkapsulyasiya – bu "hər şeyi gizlətmək" deyil, idarə olunan giriş təqdim etmək-dir.
Çox vaxt yeni başlayanlar düşünür ki, inkapsulyasiya sadəcə bütün field-ləri private etməkdir. Doğrudur, field-lər adətən private olur, amma məsələ təkcə bunda deyil. Əsas ideya məlumatları gizlətməkdə yox, onlara girişi idarə etməkdə-dir.
Bəzən bu, tam dəyişiklik qadağası deməkdir (məsələn, get-only property). Bəzən — oxuma və yazmaya validation ilə icazə verməkdir. Bəzən — oxuma və dəyişməyə yalnız class daxilində icazə verməkdir (public Type Property { get; private set; }).
İnkapsulyasiya sənə obyektin üçün "oyun qaydaları" yaratmağa imkan verir: necə dəyişə biləcəyini müəyyən edirsən və zəmanət verirsən ki, bu dəyişikliklər həmişə düzgün vəziyyətə gətirəcək.
Real layihələrdə, xüsusilə böyük komandada, inkapsulyasiyasız xaos olardı. Hər developer başqa obyektlərin daxili vəziyyətini birbaşa dəyişə bilərdi, bu da saysız-hesabsız səhvlərə və konfliktlərə gətirib çıxarardı. İnkapsulyasiya qayda yaradır və hər modula (class-a) öz məlumatlarına cavabdeh olmağa imkan verir.
Bu, SOLID prinsiplərinin əsas daşlarından biridir, xüsusilə tək məsuliyyət prinsipi (Single Responsibility Principle) və açıq/qapalı prinsipi (Open/Closed Principle) barədə, hansını ki, sonra öyrənəcəksən. Amma hələlik sadəcə yadında saxla ki, inkapsulyasiya kodunu möhkəm, çevik və başa düşülən, dəstəklənməsi asan edir.
// İnkapsulyasiyanın məqsədi: vacib məlumatların ətrafında görünməz hasar
// Heç kim təsadüfən "pozmayacaq" kənardan!
İnkapsulyasiya — bu, obyektinin vacib məlumatlarının ətrafında görünməz hasar çəkmək kimidir ki, heç kim təsadüfən pozmasın. Axı istəməzsən ki, itinin yaşı birdən mənfi olsun — bax, inkapsulyasiya buna nəzarət edir. O həm də class-ı istifadədə rahat edir: başqa proqramçılar içini qurdalamağa ehtiyac duymur, sadəcə sənin göstərdiyin hissə ilə işləyirlər. Və ən gözəli, sabah class-ın içini dəyişsən — məsələn, yaş əvəzinə doğum tarixini saxlasan — kənardan heç kim hiss etməyəcək, çünki interface eyni qalacaq. Bax, inkapsulyasiyanın əsl dəyəri budur!
2. İnkapsulyasiyanın üstünlükləri
Niyə bu sənin layihələrin və karyeran üçün bu qədər vacibdir?
Məlumatların bütövlüyü (Data Integrity):
İnkapsulyasiya obyektin məlumatlarının həmişə düzgün, məntiqli vəziyyətdə olmasına imkan verir. Bu, proqramdakı səhvlərin sayını xeyli azaldır. Müsahibədə OOP barədə soruşanda, əgər sən gözəl izah etsən ki, inkapsulyasiya məlumatların bütövlüyünü necə qoruyur, bu böyük üstünlükdür!
Çeviklik və dəstək rahatlığı (Flexibility & Maintainability):
Təsəvvür elə, əvvəlcə itin yaşını int Age kimi saxlayırdın. Bir il sonra müştəri deyir: "Bilirsiz, bizə yaş yox, itin dəqiq doğum tarixi lazımdır!".
İnkapsulyasiyasız: Əgər Age public int idisə, kodunun yüzlərlə yerində birbaşa myDog.Age-ə müraciət oluna bilərdi. Bütün o yerləri dəyişib int-i DateTime-a çevirməli, yaş hesablamasını dəyişməli olacaqdın. Bu, əzabdır!
İnkapsulyasiya ilə: Əgər səndə private int _age; və public int Age { get; set; } idisə, sadəcə daxili field-i private DateTime _dateOfBirth; ilə əvəz edə və get və set logic-ini Age property-də dəyişə bilərsən ki, yaş doğum tarixindən hesablansın. Kənardakı kod, hansı ki, myDog.Age istifadə edir, dəyişiklikləri hiss etməyəcək, çünki o, public interface Age ilə işləyir, birbaşa field-lə yox. Buna az bağlılıq (loose coupling) deyilir.
Gördün, necə magiya oldu? Class-ın "içini" dəyişdik, amma "qabığı" (public interface) eyni qaldı!
Debug-un asanlaşması (Easier Debugging):
Əgər obyektin məlumatları ilə bağlı nəsə səhv gedibsə, düzgün inkapsulyasiya ilə bilirsən ki, bu ya class-ın öz metodlarında, ya da onun public property-ləri vasitəsilə baş verib. Bug-u axtarmaq sahəsi bir class-a qədər daralır, bütün proqram boyu yayılmır.
API dizaynının yaxşılaşması:
Class-ı inkapsulyasiya edəndə, açıq "kontrakt"ın (API) nə olduğunu və nə daxili detal olduğunu aydın müəyyən edirsən. Bu, class-ların üçün təmiz, proqnozlaşdırılan və başa düşülən interface-lər yaratmağa kömək edir. API nə qədər aydındırsa, başqa developer-lar (və ya gələcəkdə özün) kodunu istifadə etmək bir o qədər asandır.
Təhlükəsizlik (Security):
Baxmayaraq ki, C# təhlükəsizlik baxımından C++ kimi sistem dilləri üçün nəzərdə tutulmayıb, inkapsulyasiya yenə də vacibdir. O, məlumatların kim və necə istifadə edə biləcəyini idarə etməyə imkan verir, arzuolunmaz dəyişikliklərin və ya obyektin daxilində gizli məlumatlara girişin qarşısını alır.
3. C#-da inkapsulyasiya necə əldə olunur?
C#-da inkapsulyasiya əsasən bunlarla əldə olunur:
Access modifier-lər (private, public və s.):
Class field-lərini private edirik ki, onları kənardan birbaşa dəyişmək mümkün olmasın. Bu, məlumatların gizlədilməsi (information hiding)-dir.
Metod və property-ləri public edirik ki, məlumatlara və davranışa idarə olunan giriş verək. Bu, bizim public interface-imizdir.
Property-lər (Properties):
Artıq öyrəndiyimiz kimi, property-lər get (oxumaq) və set (yazmaq) metodlarının sintaktik şəkəridir. Onlar field-i gizlətməyə imkan verir, amma public facade vasitəsilə giriş verirlər. Ən əsası — set accessor-da yoxlama logic-i əlavə etmək olar!
Nümunə: Dog class-ı inkapsulyasiya ilə
Əvvəlcə belə yazacağıq, BELƏ ETMƏK OLMAZ (inkapsulyasiyasız):
public class Dog
{
public string Name;
public int Age;
public void Bark()
{
Console.WriteLine($"{Name} deyir: Gav!");
}
}
Bu versiyada istənilən başqa class itə ad və yaşını istədiyi kimi dəyişə bilər. Məsələn:
Dog dog = new Dog();
dog.Name = ""; // Adı boş qoymaq olar!
dog.Age = -100; // İti çox "qədim" etmək olar
Real həyatda belə şey az olur. Amma kodda — tez-tez, əgər inkapsulyasiyanı düşünməsən.
Məlumatları qoruyuruq: field-ləri private edirik
Field-ləri qapalı (private) edirik. Onda heç kim, class-ın özü istisna olmaqla, onları birbaşa dəyişə bilməz:
public class Dog
{
private string _name;
private int _age;
public void Bark()
{
Console.WriteLine($"{_name} deyir: Gav!");
}
}
İndi belə giriş mümkün deyil:
Dog dog = new Dog();
dog._name = "Reks"; // Kompilyasiya xətası!
Məlumatlara giriş property-lər (Properties) vasitəsilə
Amma axı itinin adını bilmək istəyirsən (məsələn, ekrana çıxarmaq üçün), bəzən də dəyişmək lazım olur, əgər itə yeni sahibi çıxıbsa və ya xarakteri dəyişibsə. Bunun üçün property-lər var!
public class Dog
{
private string _name;
private int _age;
public string Name
{
get { return _name; }
set
{
// Validation əlavə edirik: ad boş olmamalıdır
if (string.IsNullOrWhiteSpace(value))
{
Console.WriteLine("Xəta: ad boş ola bilməz!");
}
else
{
_name = value;
}
}
}
public int Age
{
get { return _age; }
set
{
// Bir az realizm: yaş mənfi ola bilməz!
if (value < 0)
{
Console.WriteLine("Xəta: yaş mənfi ola bilməz!");
}
else
{
_age = value;
}
}
}
public void Bark()
{
Console.WriteLine($"{_name} deyir: Gav!");
}
}
İndi məlumatlar qorunur, amma sən onlarla idarə olunan interface vasitəsilə işləyə bilərsən:
Dog dog = new Dog();
dog.Name = "Barbos"; // Hər şey qaydasındadır!
dog.Age = 3;
dog.Name = ""; // Xəta çıxacaq, field dəyişməyəcək!
dog.Age = -1; // Yenə xəta
Avtomatik property-lər
Əgər əlavə yoxlama logic-i lazım deyilsə, ayrıca field yazmağa ehtiyac yoxdur — avtomatik property-lərdən istifadə et:
public class Dog
{
public string Name { get; set; }
public int Age { get; set; }
public void Bark()
{
Console.WriteLine($"{Name} deyir: Gav!");
}
}
Bu halda Name və Age əslində "inkapsulyasiya olunub" — onlara birbaşa yox, yalnız property vasitəsilə oxuma və yazma ilə giriş var.
4. Davranışı inkapsulyasiya edirik: yalnız lazım olan metodlar açıqdır
İnkapsulyasiya — təkcə məlumatlar üçün deyil, metodlar üçün də vacibdir! Bəzən class-ın metodları daxili "dişlilər"dir, onları kənara göstərmək lazım deyil.
Nümunə:
public class Dog
{
// Yalnız daxili istifadə üçün
private void WagTail()
{
Console.WriteLine("It quyruğunu yelləyir.");
}
// Hamı üçün açıqdır
public void Bark()
{
WagTail(); // class daxilində gizli metodu çağırırıq
Console.WriteLine("Gav!");
}
}
İndi heç kim, itdən başqa, onu birbaşa quyruğunu yelləməyə məcbur edə bilməz:
Dog dog = new Dog();
dog.WagTail(); // Xəta! Metod privatedir.
dog.Bark(); // Bark içində WagTail çağırılır
Fərqlər: field-lər, metodlar, property-lər və onların görünməsi
Gəlin yekunlaşdıraq:
| Class hissəsi | Private etmək olar? | Public etmək olar? | Girişi niyə məhdudlaşdırırıq? |
|---|---|---|---|
| Field-lər | Bəli | Bəli (amma lazım deyil!) | Məlumatları qorumaq üçün |
| Metodlar | Bəli | Bəli | Reallaşdırma detallarını gizlətmək üçün |
| Property-lər | Bəli | Bəli | Oxuma/yazmaya nəzarət üçün |
Tövsiyə: field-ləri private et, kənara yalnız property və ya metod vasitəsilə göstər.
GO TO FULL VERSION