SOLID: Nesne Yönelimli Tasarımın Altın Kuralları

Merhaba arkadaşlar! Bugün sizlere oyun geliştirmede önemli bir yere sahip olan SOLID prensiplerinden bahsedeceğiz. Bu prensipler, kodunuzu daha okunabilir, bakımı kolay ve genişletilebilir hale getirmek için rehberlik eder. Hadi gelin, bu prensipleri Unity’de nasıl uygulayabileceğimize bakalım.

SOLID Nedir?

SOLID, nesne yönelimli yazılım tasarımında uygulanan beş temel prensibin baş harflerinden oluşan bir kısaltmadır:

  1. Single Responsibility Principle (SRP) – Tek Sorumluluk İlkesi
  2. Open/Closed Principle (OCP) – Açık/Kapalı İlkesi
  3. Liskov Substitution Principle (LSP) – Liskov Yerine Geçme İlkesi
  4. Interface Segregation Principle (ISP) – Arayüz Ayırma İlkesi
  5. Dependency Inversion Principle (DIP) – Bağımlılıkların Tersine Çevirilmesi İlkesi

Bu prensipler, yazılımcılara daha sürdürülebilir, bakım yapılabilir ve genişletilebilir yazılımlar oluşturma konusunda rehberlik eder. Şimdi her bir ilkeyi daha ayrıntılı bir şekilde inceleyelim.

1. Single Responsibility Principle (SRP) - Tek Sorumluluk İlkesi

Her sınıfın yalnızca bir sorumluluğu olmalıdır. Bu, bir sınıfın yalnızca tek bir amaca hizmet etmesi gerektiği anlamına gelir. Eğer bir sınıf birden fazla sorumluluğa sahipse, bu sınıfın değişimi zorlaşır ve hata olasılığı artar.

Uygulama Örneği:

public class Player
{
    public int health;
    
    public void TakeDamage(int damage)
    {
        health -= damage;
    }
}

public class PlayerUI
{
    public void UpdateHealthDisplay(int health)
    {
        // Sağlık arayüzünü güncelle
    }
}

Yukarıdaki örnekte, Player sınıfı sadece oyuncunun sağlık yönetimi ile ilgilenirken, PlayerUI sınıfı sağlık arayüzünü güncellemektedir. Bu, kodun daha düzenli olmasını sağlar.

2. Open/Closed Principle (OCP) - Açık/Kapalı İlkesi

Sınıflar, genişlemeye açık, ancak değişime kapalı olmalıdır. Yani, yeni özellikler eklemek için mevcut kodu değiştirmek yerine yeni sınıflar eklemeliyiz.

Uygulama Örneği:

public abstract class Weapon
{
    public abstract void Attack();
}

public class Sword : Weapon
{
    public override void Attack()
    {
        // Kılıç ile saldırı
    }
}

public class Bow : Weapon
{
    public override void Attack()
    {
        // Yay ile saldırı
    }
}

Bu yapı ile yeni bir silah türü eklemek için sadece yeni bir sınıf oluşturmanız yeterlidir. Mevcut Weapon sınıflarına dokunmanıza gerek yok.

3. Liskov Substitution Principle (LSP) - Liskov Yerine Geçme İlkesi

Bir sınıfın alt sınıfları, üst sınıfın yerine kullanılabilir olmalıdır. Yani, alt sınıflar üst sınıfın davranışını bozmak zorundadır.

Uygulama Örneği:

public class Enemy
{
    public virtual void Attack()
    {
        // Düşman saldırısı
    }
}

public class Goblin : Enemy
{
    public override void Attack()
    {
        // Goblin saldırısı
    }
}

public class Troll : Enemy
{
    public override void Attack()
    {
        // Troll saldırısı
    }
}

Burada, Goblin ve Troll sınıfları Enemy sınıfının yerini alabilir ve farklı saldırı davranışlarına sahip olabilir.

4. Interface Segregation Principle (ISP) - Arayüz Ayırma İlkesi

Kullanıcılar, ihtiyaç duymadıkları arayüzlere bağımlı olmamalıdır. Yani büyük ve karmaşık arayüzler yerine, daha küçük ve spesifik arayüzler oluşturmalısınız.

Uygulama Örneği:

public interface IDamageable
{
    void TakeDamage(int damage);
}

public interface IHealable
{
    void Heal(int amount);
}

public class Player : IDamageable, IHealable
{
    public int health;

    public void TakeDamage(int damage)
    {
        health -= damage;
    }

    public void Heal(int amount)
    {
        health += amount;
    }
}

Bu yapıda, Player sınıfı yalnızca gerçekten ihtiyaç duyduğu arayüzleri uygular.

5. Dependency Inversion Principle (DIP) - Bağımlılıkların Tersine Çevirilmesi İlkesi

 Yüksek seviye sınıflar, düşük seviye sınıflara bağımlı olmamalıdır. Her ikisi de arayüzlere bağımlı olmalıdır.

Uygulama Örneği:

public interface IWeapon
{
    void Attack();
}

public class Player
{
    private IWeapon weapon;

    public Player(IWeapon weapon)
    {
        this.weapon = weapon;
    }

    public void Attack()
    {
        weapon.Attack();
    }
}

public class Sword : IWeapon
{
    public void Attack()
    {
        // Kılıç ile saldırı
    }
}

Bu yapıda, Player sınıfı doğrudan bir silaha bağımlı değildir; bunun yerine IWeapon arayüzüne bağımlıdır. Böylece, farklı silahlar ekleyebilirsiniz.

Sonuç

SOLID prensipleri, kodunuzu daha iyi yapılandırmanıza ve genişletmenize yardımcı olur. Unity’de bu prensipleri uygulamak, projenizin sürdürülebilirliğini artırır ve bakımını kolaylaştırır. Bu yazıda öğrendiklerinizle projelerinizi daha düzenli hale getirebilirsiniz.

Bir Yanıt Bırakın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir