SOLID - Open/Closed - Açık/Kapalı Prensibi

Solid Prensipleri'nin ilkesi olan Open/Closed - Açık/Kapalı Prensibi

                                                      

Bu prensip, yazdığımız bir sınıfın geliştirilmeye açık (Open) fakat değiştirilmeye kapalı (Closed) olmasıdır. Yani bir modüle yeni bir özellik eklerken o sınıfın yapısını bozacak bir değişiklik yapmamamız gerektiğini belirtir.

Normal şartlarda bir metoda yeni bir özellik eklerken if blokları oluşturup o özellik için işlemleri orada yaparız. Fakat o sınıftaki metodun yapısını bozacaktır ve Açık/Kapalı prensibine aykırı bir durum oluşturacaktır.

Bu sınıfı değiştirmeden geliştirebilmenin en önemli yolu abstract bir metot ya da interface içerisine metot oluşturup yeni oluşturacağımız bir özellik için bir sınıf oluşturup abstract metodu override veya interface'deki metodu implement etmektir.

Örneğimizde bir Employee sınıfında çalışanın statüsüne göre maaş verisini gösteren metodumuz (EmployeeSalary) var. Fakat bu yeni bir statü eklendiğinde sınıfımıza ait bu metodu bozacaktır.

Aşağıdaki bu kod Open/Closed prensibine aykırıdır.
    public class Employees
    {        
        public Employees(string name,string surname)
        {
            this.FirstName = name;
            this.LastName = surname;
        }
        
        public Employees()
        {

        } 

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public EmployeeStatus Status {get;set;}

        public double EmployeeSalary(double salary)
        {
            double salaryResult = 0;

            if (Status == EmployeeStatus.Kadrolu)
            {
                salaryResult = salary * 1;
            }
            else if (Status == EmployeeStatus.Stajyer)
            {
                salaryResult = salary * 0.3;
            }

            return salaryResult;
        }                
    } 

    public enum EmployeeStatus
    {
        Kadrolu,
        Stajyer
    }

Örneğimizi Open/Closed prensibine göre düzenlediğimizde Employees adında abstract bir class ve EmployeeSalary metodunu da statüsüne göre oluşturacağımız sınıfta override etmek için abstract olarak tanımladık.
    public abstract class Employees
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public abstract double EmployeeSalary(double salary);
        
        public Employees(string name,string surname)
        {
            this.FirstName = name;
            this.LastName = surname;
        }
        
        public Employees()
        {

        }                 
    }     
 
Kadrolu çalışan birisi için oluşturduğumuz Kadrolu class'ı
    public class Kadrolu : Employees
    {
        public override double EmployeeSalary(double salary)
        {
            return salary * 1;
        }
    }
 
Stajyer olarak çalışan birisi için oluşturduğumuz Stajyer class'ı
    public class Stajyer:Employees
    {
        public override double EmployeeSalary(double salary)
        {
            return salary * 0.3;
        }
    }
Eğer bu statülerden başka bir statü daha oluştuğunda if-else bloğu oluşturmak yerine yeni bir class tanımlayıp abstract class'taki abstract metodu override edebiliriz. Böylece bu prensip bize genişletilebilirlik sağlayacaktır.

Yorumlar