Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme

Sadece kendinizin çalışması, sitemiz adına yaptığınız doküman çalışmalarının yer aldığı bölümümüz.
Cevapla
Kullanıcı avatarı
admin
Sistem Geliştiricisi
Sistem Geliştiricisi
Mesajlar: 832
Kayıt: 28 Ağu 2022 04:38
Konum: Database
Meslek: Teknisyen
Teşekkür etti: 456 kez
Teşekkür edildi: 308 kez
İletişim:

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme

Mesaj gönderen admin »

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme


Resim

Merhaba,

Bugün temiz kod hakkında konuşacağız. Gerçekten gerekli mi? Kodlarımız dağınık görünüyorsa gelecekte bizi neler bekliyor? Temiz kod yalnızca, okunması kolay ve basitlik anlamına mı geliyor? Yoksa bundan çok daha fazlası mı?
Sonuçta, okunması kolay kod ile değiştirilmesi kolay kod arasında bir fark vardır.
- "Büyük" Dave Thomas
Her şeyden önce, kimsenin bu kadar zamanı olmadığını biliyorum. Patron projenin sonuçlandırılmasını bekler. Ayrıntıları umursamaz. Kendinizi müşterinin önünde bir kasap olarak düşünebilirsiniz. Patron sizin müşteriniz ve siz kasapsınız. Müşteri hijyeninizi umursamıyor. Sadece etini olabildiğince çabuk almak istiyor. Yani patron her müşteri için ellerini yıkamanı istemiyor. Neden, çünkü zaman(vakit) nakittir. Son olarak, eğer ellerinizi yıkamazsanız ve zamanınızı boşa harcamazsanız (Bu örnekten farklı olarak, her zaman ellerinizi yıkayın, lütfen!), günün sonunda belki siz hariç herkes mutlu olabilir :) Ama gelecekte , müşteriler hasta olabilirler ve şirkete dava açabilirler. En sonunda ,kimse mutlu olmayacak. Patron detayları bilmez. Riskleri sadece sen bilirsin. Bu yüzden tüm sorumluluğu alın ve kodunuzu mümkün olduğunca temiz hazırlayın.

Bu makalenin sonunda çok karmaşık AI uygulama kodlarını yeniden değerlendireceğiz. Ama önce, sonunda o karmaşık kodları yeniden düzenlemek için kullanacağımız bu üç tasarım deseni stratejisini anlamamız gerekiyor. Belki çoğunuz bunları zaten biliyorsunuzdur ama güzel bir şeyi tekrar etmenin zararı olmaz :) Kısacası sonraki iki tasarım deseni sizi son örneğe hazırlayacaktır. Ve bu dağınık AI uygulamasında sonuncusunu derinlemesine inceleyeceğiz. Tıpkı iş eğitiminde olduğu gibi :)


Tekrarlanabilir kodlardan kaçınmalısınız…
Aşağıdaki C# Konsol Uygulaması kodunda çoklu iş mantığını görebilirsiniz. Bu, S.O.L.I.D.’in ilk kuralına aykırıdır.
Tek Sorumluluk prensibi. Bir sınıfı değişmek için bir ve yalnızca bir nedeni olmalıdır. Neden, çünkü kolay okunabilmesi, kolayca test edilmesi ve basitlik için. Şu koda bakın; her mantığın kendi işi vardır. CRM, Finans ve Servis. Yazılım Hepsi Bir Arada Kampanya değildir. Dağıtılmış bir süreçtir. CRM sürecini değiştirmek isterseniz, bu sınıfta kullanılan tüm uygulamalar bu güncellemeden etkilenir. Ve bir iş değişikliği için diğer tüm süreçleri yeniden inşa etmeniz gerekir. Bu, “CRM” sürecinin değişmesi için “Finans” ve “Hizmet”in durdurulması gerektiği anlamına gelir. Enum kullanmak bu koddaki tek iyi şey :)

Bu koddaki diğer kötü kokuyu hissedebiliyor musun?

Gelecekte, bir işleme daha ihtiyacınız olursa, bu sınıfı bulmalı ve başka bir “if koşulu” eklemelisiniz. Bu çılgınca ve sürdürülebilir değil. Bu sınıfa on yeni mantık daha gelirse, kod okunamaz hale gelir.

Kod: Tümünü seç

using System;
namespace SolidStrategy
{
    public enum ProcessType
    {
        Finance,
        Service,
        Crm
    }
    class Program
    {
        static void Main(string[] args)
        {
            ProcessCalculation(ProcessType.Crm);
        }
        public static void ProcessCalculation(ProcessType type)
        {
            try
            {
                if (type == ProcessType.Crm)
                {
                    CallCrm("Update Crm DB");
                }
                else if (type == ProcessType.Finance)
                {
                    CallFinance("Send Mail to Customers");
                }
                else if (type == ProcessType.Service)
                {
                    CallService("Backup all Data");
                }
            }
            catch
            {
            }
        }
        public static void CallCrm(string message) 
        {  
            Console.WriteLine($"Process Crm! :{message}"); 
        }
        public static void CallFinance(string message) 
        { 
            Console.WriteLine($"Process Finance! :{message}"); 
        }
        public static void CallService(string message) 
        {
           Console.WriteLine($"Process Service! :{message}"); }
        }
    }
}

Öncelikle tüm işlemleri farklı sınıflara ayıralım. Ve tüm sınıflar başka bir sınıftan veya ara yüzden miras alınmalıdır. Çıplak sınıf, nesne yönelimli programlamada istenmeyen bir şeydir.

Resim

IBussineLogic :

Tüm iş mantığı aynı ara birimden (IBussinesLogic) devralınmalıdır. Ve tüm sınıflar aynı “WorkProcess()” yöntemini geçersiz kılmalıdır. Bu Tasarım Modelini hatırlıyor musunuz?

Kod: Tümünü seç

using System;
namespace SolidStrategy
{
    public interface IBussinesLogic
    {
        void WorkProcess(string message);
    }
}
Crm:

İlk işletme sınıfı CRM'dir. “IBusinessLogic”ten miras alınır. Bu nedenle “WorkProcess()” yöntemi uygulanmalıdır. Her “WorkProcess()” yöntemi, farklı üst sınıfa aittir. Yani hepsinin mantığı farklı.

Crm Sınıfı :

Kod: Tümünü seç

using System;
namespace SolidStrategy
{
    public class Crm : IBussinesLogic
    {
        public void WorkProcess(string message)
        {
            Console.WriteLine($"Process Crm! :{message}");
        }
    }
}

Finance:

İkinci işletme sınıfı Finanstır. CRM gibi “IBusinessLogic”ten miras alınır. Ayrıca farklı Finansal mantık için “WorkProcess()” yöntemini uygulamak zorundadır.

Kod: Tümünü seç

using System;
namespace SolidStrategy
{
    public class Finance : IBussinesLogic
    {
        public void WorkProcess(string message)
        {
            Console.WriteLine($"Process Finance! :{message}");
        }
    }
}

(Service)Hizmet:

Son işletme sınıfı Hizmet'tir. Diğer işletme sınıfları gibi, “IBusinessLogic”ten miras alınır. Ayrıca, farklı Servis mantığı için “WorkProcess()” yöntemini uygulamak zorundadır.

Kod: Tümünü seç

using System;
namespace SolidStrategy
{
    public class Service : IBussinesLogic
    {
        public void WorkProcess(string message)
        {
            Console.WriteLine($"Process Service! :{message}");
        }
    }
}
(Process)İşlem:

Şimdi tüm iş mantığını tek bir kapsayıcı da ele almamız gerekiyor. Neden; çünkü müşteriler bu durumda, aslında diğer geliştiriciler yalnızca bir sınıfla ilgilenmelidir. Çünkü sadelik her şeydir. “Ve şehre yeni bir iş mantığı gelirse, hiç kimse bu ana Süreç kodunu değiştirmek zorunda kalmamalı” :)
Process sınıfı, Constructor() içindeki "IBussinesLogic" öğesinden devralınan bir mantık sınıfı gerektirir.
Tüm sınıfların ortak özelliği nedir?
Tabii ki “WorkProcess()” yöntemi. Process sınıfından “WorkProcess()” yöntemi çağrıldığında, Constructor'dan alınan “IBussinesLogic” sınıfına bağlı olarak mantık farklılık gösterir.

Kod: Tümünü seç

using System;
namespace SolidStrategy
{
    public class Process
    {
        IBussinesLogic _bussines = null;
        public Process(IBussinesLogic bussines) 
                       => _bussines = bussines;
        public void WorkProcess(string message)
        {
            _bussines.WorkProcess(message);
        }
    }
}
Daha zeki olmanın tek yolu, daha zeki bir rakiple oynamaktır.

Etiketler:
Kullanıcı avatarı
admin
Sistem Geliştiricisi
Sistem Geliştiricisi
Mesajlar: 832
Kayıt: 28 Ağu 2022 04:38
Konum: Database
Meslek: Teknisyen
Teşekkür etti: 456 kez
Teşekkür edildi: 308 kez
İletişim:

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 2.Kısım

Mesaj gönderen admin »

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 2.Kısım

Resim

Strateji Tasarım Deseni yukarıdaki sorunun cevabıdır. Çalışma zamanında bir algoritma seçmeyi sağlayan davranışsal bir yazılım tasarım modelidir. Bu durumda temiz ve basit kod almak için bu kalıbı kullandık.

Resim
Bu dünyayı bulduğunuzdan biraz daha iyi bırakmayı deneyin. . .
— Robert Baden-Powell
Program.cs

Dağınık Kodlar bu birkaç satırlık kod haline geliyor. Hadi,yeni oyuncak ile oynayalım :)
Sadelik her şeydir - çok daha okunabilir kod. Ama daha önemli bir şey var:
“Kod satırını değiştirmeden kolayca yeni mantık ekleyebilirsiniz. Ve kimse bu değişiklikten etkilenmiyor.”
Program.cs/Main() :

Kod: Tümünü seç

using System;
namespace SolidStrategy
{
    class Program
    {
        static void Main(string[] args)
        {            
            Process process = new Process(new Crm());
            process.WorkProcess("Update Crm DB");
        }
    }
}
Sonuç:

Resim
Daha zeki olmanın tek yolu, daha zeki bir rakiple oynamaktır.
Kullanıcı avatarı
admin
Sistem Geliştiricisi
Sistem Geliştiricisi
Mesajlar: 832
Kayıt: 28 Ağu 2022 04:38
Konum: Database
Meslek: Teknisyen
Teşekkür etti: 456 kez
Teşekkür edildi: 308 kez
İletişim:

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 3.Kısım

Mesaj gönderen admin »

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 3.Kısım

Extraction(Ekstraksiyon"İçinden çıkartma,dışarı ayıklama" Yöntemleri

İkinci senaryomuz ; Ekstraksiyon yöntemiyle ilgili. Çıkarma benim en sevdiğim Yeniden Düzenleme yöntemidir.

Resim

Extract"Dışarı çıkartma" yöntemiyle, mevcut bir yöntemden bir kod parçasını yeni bir yönteme taşırsınız. Ve lütfen ne yaptığı hakkında bir isim vermeyi unutmayın.
Bu teknik, karmaşıklıktan kaçmak ve kodun okunabilirliğini artırmak için kullanılır.
"Bir yığında böcek bulmak samanlıkta iğne aramaya benzer. Bu kütleyi bölün ve tüm hataları parça parça bulun. Ve asla unutma, bölersen paylaşabilirsin”
— Bora Kaşmer
Aşağıdaki koda bakın, her şey tek bir yerde ve tüm mantıklar birlikte çalışıyor. Tüm farklı mantıkları bulacağız ve bunları bu yöntemden farklı yöntemlere çıkaracağız. Amaç daha iyi okunabilirlik ve basitliktir.

Kod: Tümünü seç

using System;
using System.Collections.Generic;

namespace ExtractMethod
{
    enum Department
    {
        IT = 1,
        HumanResource = 2,
        System = 3,
        Officer = 4
    }
    enum Gender
    {
        Male,
        Female
    }
    class Person
    {
        public int Identity;
        public String Name;
        public double Salary;
        public int Department;
        public Gender Gender;
        public Person(int _identity, string name, float _salary, Department _department, Gender _gender)
        {
            this.Identity = _identity;
            this.Name = name;
            this.Salary = _salary;
            this.Department = (int)_department;
            this.Gender = _gender;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<Person> listPerson = new List<Person>();
            listPerson.AddRange(new List<Person>() {
                new Person(1, "Test User1", 5500, Department.HumanResource,Gender.Male),
                new Person(2, "Test User2", 6500, Department.Officer,Gender.Female),
                new Person(3, "Test User3", 7500, Department.IT,Gender.Female)
            });
            CalculateSalaryIncrease(ref listPerson);

            foreach (Person person in listPerson)
            {
                Console.WriteLine($"User Name:{person.Name} Sallary:{person.Salary} Departmant:{(Department)person.Department}");
            }
        }

        public static void CalculateSalaryIncrease(ref List<Person> personList)
        {
            foreach (Person person in personList)
            {
                switch ((Department)person.Department)
                {
                    case Department.IT:
                        {
                            person.Salary = person.Salary * 1.1;
                            break;
                        }
                    case Department.HumanResource:
                        {
                            person.Salary = person.Salary * 1.2;
                            break;
                        }
                    case Department.System:
                        {
                            person.Salary = person.Salary * 1;
                            break;
                        }
                    case Department.Officer:
                        {
                            person.Salary = person.Salary * 1.3;
                            break;
                        }
                }
                person.Name = person.Gender == Gender.Male ? $"Mr.{person.Name}" : $"Ms.{person.Name}";
            }
        }
    }
}
Hadi “CalculateSallaryIncrease()” yöntemini kontrol edelim. Bu yöntemde üç işimiz var.

1-) Bölümlere göre maaş zam oranını bulunuz:

Bu kod kişinin çalıştığı bölüme göre maaş artış oranını döndürür. İsim önemlidir. Bu yöntemin amacını adından anlayabilirsiniz.

Kod: Tümünü seç

public static double GetSalaryRatebyDepartment(Department department)
        {
            switch (department)
            {
                case Department.IT:
                    {
                        return 1.1;
                    }
                case Department.HumanResource:
                    {
                        return 1.2;
                    }
                case Department.System:
                    {
                        return 1;
                    }
                case Department.Officer:
                    {
                        return 1.3;
                    }
            }
            return 1;
        }
2-)Hadi,yukarıdaki kod ile bulunan yeni “artış oranını” kullanarak çalışanın yeni maaşını hesaplayalım.

Metot adından anlaşılan parametrelerin sırasını görebilirsiniz. Hesapla => NewSallary=>WithRate (maaş, oran). İleride her kişinin maaş hesaplaması için bu yönteme kolaylıkla yeni iş mantığı eklenebilir.

Kod: Tümünü seç

public static double CalculateNewSallaryWithRate(double salary, double rate)
        {
            return salary * rate;
        }
3-) Etiketi cinsiyete göre bir kişi adına ekleyin. Bay veya Bayan olarak

Bu yöntemi neden ayırdık? Çünkü birisi ileride herhangi bir koşul için yeni bir etiket eklemek isterse, ekstra bir çaba harcamadan bu yönteme kolayca ekleye bilmelidir.

Kod: Tümünü seç

public static string AppendTagToNameByGender(string name, Gender gender)
        {
            return gender == Gender.Male ? $"Mr.{name}" : $"Ms.{name}";
        }
Şimdi yeni “CalculateSalaryIncrease()” yöntemimiz şuna benziyor. Daha okunaklı, daha anlaşılır ve en önemlisi çok daha “kısa”.

Kod: Tümünü seç

public static void CalculateSalaryIncrease(ref List<Person> personList)
        {
            foreach (Person person in personList)
            {
                double sallaryRate = GetSalaryRatebyDepartment((Department)person.Department);
                person.Salary = CalculateNewSallaryWithRate(person.Salary, sallaryRate);
                person.Name = AppendTagToNameByGender(person.Name, person.Gender);
            }
        }
Sonuç:

Resim

Bu, bu makalenin son ve ana örneğidir:

Aşağıdaki örnekte yapılan üç yorumun (Tanım1, Tanım2, Tanım3) bir kadına mı yoksa bir erkeğe mi ait olduğu belirli analiz kuralları ile anlaşılmaya çalışılmıştır.

Resim

Elbette, bu gerçek bir hayat senaryosu değil. Ancak temiz kodu anlamamıza yardımcı oluyor. İki grup kelime kütüphanemiz var. Erkeklerin ve Kadınların konuşurken sıklıkla kullandıkları kelimeler. Yapılan yorumda bu kelimeleri veya bir grup kelimeyi düzelterek konuşmacının cinsiyetinin erkek mi, kadın mı olduğuna karar vermeye çalışıyoruz.

Erkekler için açıklama kısmındaki (futbol veya araba) kelimeleri arıyoruz. Bu kelimelerden biri tefsirde yer alırsa, bunu söyleyenin erkek olduğunu kabul ederiz.

Kadınlar için ise açıklama kısmındaki (anne veya bebek) veya (çizim ve araba) veya (ovma ve araba) kelimelerini arıyoruz. Bu kelime veya kelime gruplarından biri tefsirde yer alırsa, bunu söyleyenin kadın olduğunu kabul ederiz.

Bu kod ile ilgili yanlışlık nedir?
. Bu kodu herhangi bir açıklama olmadan anlamak çok zordur.

. Kod Okunabilirliği korkunç.

. Herhangi bir yeni kural gelirse, tüm koşulları değiştirmek zorundayız.

. Bir süre sonra ve - veya koşullarını takip etmek imkansızdır.

. Son olarak bu kod insanın anlaması için yazılmamıştır. Bilgisayarın anlaması için yazılmıştır :)

Kod: Tümünü seç

using System;

namespace Interpreter
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            string Description1 = "Although I like football matches very much, I don't usually watch.";
            string Description2 = "I attach great importance to breast milk for my baby's health.";
            string Description3 = "I hit the car on my way to the gym.";

            bool expResult = false;
            string word = "football";
            string word2 = "car";

            string word3 = "mother";
            string word4 = "baby";
            string word5 = "draw";
            string word6 = "rub";


            Console.Write(Description1 + " (Man):");
            //football || car
            expResult = Description1.ToLower().Contains(word.ToLower()) || Description1.ToLower().Contains(word2.ToLower());
            Console.WriteLine(expResult);

            //mother || baby , draw && car , rub && car
            Console.Write(Description2 + "(Woman):");
            expResult = ((Description2.ToLower().Contains(word3.ToLower()) || Description2.ToLower().Contains(word4.ToLower()))
                || (Description2.ToLower().Contains(word5.ToLower()) && Description2.ToLower().Contains(word2.ToLower()))
                || (Description2.ToLower().Contains(word6.ToLower()) && Description2.ToLower().Contains(word2.ToLower())));
            Console.WriteLine(expResult);

            //mother || baby , draw && car , rub && car
            Console.Write(Description3 + "(Woman):");
            expResult = ((Description3.ToLower().Contains(word3.ToLower()) || Description3.ToLower().Contains(word4.ToLower()))
               || (Description3.ToLower().Contains(word5.ToLower()) && Description3.ToLower().Contains(word2.ToLower()))
               || (Description3.ToLower().Contains(word6.ToLower()) && Description3.ToLower().Contains(word2.ToLower())));
            Console.WriteLine(expResult);

            Console.ReadLine();
        }
    }
}
Daha zeki olmanın tek yolu, daha zeki bir rakiple oynamaktır.
Kullanıcı avatarı
admin
Sistem Geliştiricisi
Sistem Geliştiricisi
Mesajlar: 832
Kayıt: 28 Ağu 2022 04:38
Konum: Database
Meslek: Teknisyen
Teşekkür etti: 456 kez
Teşekkür edildi: 308 kez
İletişim:

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 4.Kısım

Mesaj gönderen admin »

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 4.Kısım

Resim

Tercüman Tasarım Deseni

Bu karışıklığı temizlemek için birkaç tasarım deseni kullanacağız. Ve elbette, bu çözümün ana kalıbı “Tercüman Tasarım Kalıbı” olacaktır.

Yorumlayıcı, davranış sal bir tasarım kalıbıdır. Bir Ara yüzden uygulanan dil gramerini veya ifadesini değerlendirmek için kullanılır. Bu uygulamada ifademiz bu üç açıklamadır. Bu model, belirli bir bağlamı yorumlamak için bu ifade ara birimlerini kullanır.

Şimdi bir(Expression ara birimi) arayüz ifadesi oluşturacağız. Daha sonra, bu Expression ara birimini uygulayarak And — Or sınıflarını oluşturacağız. "Veya" İfadesi ve "Ve" İfadesi, birleşik ifadeler oluşturmak için kullanılır. Ve tabi ki, tanımlamada bağlamın ana yorumlayıcısı olarak tanımlanan bir “TerminalExpression” sınıfı oluşturacağız. Bu uygulamada buna “CheckExpression” diyoruz.
“Gelecekte, bir yorumcunun cinsiyetini tespit etmek için yeni kurallar gelirse, yeni bir tür İfade oluşturmamız gerekebilir.”
1-) Expression Interface(ara birimi) oluşturalım: Diğer tüm ifade sınıfları bu “Interpret()” yöntemini kullanmalıdır.

Kod: Tümünü seç

public interface Expression
{
     bool Interpret(string content);
}
2-) CheckExpression Oluştur: Oluşturucudan bir kelime alacağız ve ardından Interpret yönteminde parametre olarak alınan içerikte (açıklamada) ilgili kelimenin bulunup bulunmadığını kontrol edeceğiz. Bu bizim ilk aracımız olacak ve her yerde kullanacağız.

Resim

CheckExpression Class(Sınıfı) :

Kod: Tümünü seç

public class CheckExpression : Expression
{
  private string word;
  public CheckExpression(string _word)
  {
     this.word = _word;
  }
  
  public bool Interpret(string content)
  {
     return content.ToLower().Contains(word.ToLower());
  }
}
3-) Create OrExpression: Bu bizim ikinci aracımız. Yukarıdaki Expression sınıfını kullanacağız. Bu yöntemde iki ifade sınıfına ihtiyacımız var.

Bu uygulamada deyim “kelime” anlamına gelmektedir. Bu kelimelerden “birinin” bu açıklamada yer alıp almadığını kontrol edeceğiz.

Resim

OrExpression Class(sınıfı) :

Kod: Tümünü seç

public class OrExpression : Expression
{
    private Expression exp1;
    private Expression exp2;
    public OrExpression(Expression _exp1, Expression _exp2)
    {
       this.exp1 = _exp1;
       this.exp2 = _exp2;
    }
    public bool Interpret(string content)
    {
       return (exp1.Interpret(content) || exp2.Interpret(content));
    }
}
Biraz dikkat ederseniz, yeni bir araç oluşturmak için başka bir araç kullandığımızı görebilirsiniz! Yeni bir robot yaratmak için robot kullanmak gibi :)
Resim
A secene from “Ex Machine” Movie

Resim

4-) Create AndExpression: Bu bizim son aracımız. Yine burada iki ifade sınıfına ihtiyacımız var. Bu kelimelerin "her ikisinin" bu açıklamada yer alıp almadığını kontrol edeceğiz.

AndExpression Class :

Kod: Tümünü seç

public class AndExpression : Expression
{
    private Expression exp1;
    private Expression exp2;
    public AndExpression(Expression _exp1, Expression _exp2)
    {
       this.exp1 = _exp1;
       this.exp2 = _exp2;
    }
    
    public bool Interpret(string content)
    {
       return (exp1.Interpret(content) && exp2.Interpret(content));
    }
}
Daha zeki olmanın tek yolu, daha zeki bir rakiple oynamaktır.
Kullanıcı avatarı
admin
Sistem Geliştiricisi
Sistem Geliştiricisi
Mesajlar: 832
Kayıt: 28 Ağu 2022 04:38
Konum: Database
Meslek: Teknisyen
Teşekkür etti: 456 kez
Teşekkür edildi: 308 kez
İletişim:

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 5.Kısım

Mesaj gönderen admin »

Temiz Kod İçin Tasarım Modelleriyle Yeniden Düzenleme - 5.Kısım

Bu üç aracı oluşturarak ne yaptık?

1-) O kitle kodunu böldük. Mevcut yöntemlerden iki kod parçasını yeni yöntemlere taşıdık(AndExpression, OrExpression). İşi biraz daha ileri götürdük, bu yöntemlerden bir parça kod da yeni yöntemlere (CheckExpression) taşıdık. Bunu hatırlıyor musun?
Yazının başında bahsettiğimiz buna “Çıkarma Yöntemi” diyoruz.
2-) “AndExpression ve OrExpression” sınıflarına dikkatinizi çekmek istiyorum. Her ikisi de “İfade” arayüzünden miras alır. Her ikisi de aynı “Yorum()” yöntemine sahiptir. Aşağıdaki koda bakın. “getFemailExpression()” bir İfade Listesine sahiptir. “İfade” Arayüzünden miras alınan herhangi bir sınıfı alabilir. “AndExpression”, “OrExpression” gibi. Bu, “getFemailExpressions()”ın çalışma zamanında bir algoritma seçtiği anlamına gelir. Bunu hatırlıyor musun?
Yazının yukarısında bahsettiğimiz buna “Strateji Tasarım Modeli” diyoruz.
InterpretPattern Class (Yorumlama Modeli Sınıfı ):
. CheckExpression: Bu bir Kelimedir.
. OrExpression — AndExpression: Yorumcunun cinsiyetine karar vermek için kullanılan ifade. Karar vermek için bir veya daha fazla “CheckExpression” gerekir.
. Interpret(): Tüm İfadeler bu yöntemi uygulamak zorundadır. Parametre olarak content(description) alır. Ve cinsiyete karar verir. Erkek ya da kadın.
Her üç araç da bu sınıfta kullanılmak üzere yaratılmıştır. “AndExpression”, “Expression” ve “OrExpression”. Burada iki durum var. Erkek veya Kadın Karar Kuralları. Bir İfade veya İfade Listesi olarak toplanır ve döndürülürler.

getMaleExpression(): OrExpression değerini döndürür. Her ifade bir kelimedir ve bunlardan ikisi OrExpression sınıfına parametre olarak verilir. Her OrExpression, cinsiyete karar vermek için bir kuraldır.

getFemailExpression(): Bir İfade Listesini döndürür. Kadın Cinsiyeti için karar verilen üç İfade Kuralı vardır. İki AndExpression ve bir OrExpression. Hepsi parametre olarak altı ifade (kelime) alır.

Kod: Tümünü seç

public class InterpretPattern
{
   public static Expression getMaleExpression()
   {
      Expression futbol = new CheckExpression("football");
      Expression araba = new CheckExpression("car");
      
      return new OrExpression(futbol, araba);
   }
   public static List<Expression> getFemailExpressions()
   {
      List<Expression> ListExpression = new List<Expression>();
      Expression mother = new CheckExpression("mother");
      Expression baby = new CheckExpression("baby");
      Expression rub = new CheckExpression("rub");
      Expression draw = new CheckExpression("draw");
      Expression car = new CheckExpression("car");
      ListExpression.Add(new OrExpression(mother, baby));
      ListExpression.Add(new AndExpression(rub, car));
      ListExpression.Add(new AndExpression(draw, car));
      return ListExpression;
    }
}
Her şey bulmacanın bir parçası gibi görünüyor. Hepsi birbirine kenetlenir ve küçük parçalar daha büyük parçaları, daha büyük parçalar da resmi oluşturur.
Resim

Aşağıdaki koda bakın, çok daha net. Uygulaması kolaydır. İş mantığını bilmenize gerek yok. “Kadına karar vermek için içeriğin hangi sözcükleri içermesi gerektiği sizi ilgilendirmez.”

İş mantığına yeni kurallar veya yeni kelimeler gelirse, tüm kodları değiştirmeniz gerekmez. OOP( Object-Oriented Nesne Yönelimli) Programlamanın doğası budur.

Formasyon Ağacı :
“İfadeler =>CheckExpression =>OrExpression&AndExpression =>getFemailExpressions&getMaleExpression”
Kuralların iş mantığına göre tek tek çalıştırılması durumunda, kurallardan biri belirli koşulları geçerse tüm işlemler durdurulur ve “doğru” sonuca döndürülür.

Kod: Tümünü seç

using System;

namespace Interpreter
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            string Description1 = "Although I like football matches very much, I don't usually watch.";
            string Description2 = "I attach great importance to breast milk for my baby's health.";
            string Description3 = "I hit the car on my way to the gym.";

            Console.Write(Description1 + " (Man):");
            Console.WriteLine(InterpretPattern.getMaleExpression().Interpret(Description1));

            bool expResult = false;
            Console.Write(Description2 + "(Woman):");
            foreach (Expression exp in InterpretPattern.getFemailExpressions())
            {
                if (exp.Interpret(Description2)) { expResult = true; break; }
            }
            Console.WriteLine(expResult);

            bool expResult2 = false;
            Console.Write(Description3 + "(Woman):");
            foreach (Expression exp in InterpretPattern.getFemailExpressions())
            {
                if (exp.Interpret(Description3)) { expResult2 = true; break; }
            }
            Console.WriteLine(expResult2);
            Console.ReadLine();
        }
    }
}
Sonuç:

Resim

Bu yazıda, tasarım kalıpları kullanarak okunamayan dağınık kodu açık ve net koda nasıl dönüştürebileceğimizden bahsettik. Bazı durumlarda, yalnızca bir tasarım deseni sorununuzu çözmez. Bu durumda çözüm için birden fazla tasarım deseni tercih etmelisiniz.

OOP(bject-Oriented"Nesne Yönelimli" programlama ve Tasarım kalıpları, kodunuzu kolay bakım (değişim ve test) için optimize ediyor, onları genişletilebilir ve esnek hale getiriyor.
Hızlı İpucu: Erkek yorumcuyu tanımlamak için “getMaleExpression()”a gelen yeni bir kuralı hayal edin. Bu senaryo için içerikte (açıklamada) üç ifade (kelime) bulunmalıdır. Bu tamamen yeni bir şey.

Aşağıdaki gibi yeni bir İfade türü oluşturmak yeterlidir. “And3Expression” olarak adlandırılır. İfade arayüzünden uygulama yapıyoruz ve bu sefer üç İfade(kelime) oluşturuyoruz. Son olarak “Interpret()” yönteminde bu üç kelimenin içerikte (açıklamada) yer alıp almadığını kontrol ediyoruz. Bu kadar. Hiçbir yerde hiçbir şeyi değiştirmemize gerek yok. Sadece bu yeni “And3Expression” sınıfını ekleyin ve onu “getMaleExpression()” içinde kullanın. Bu, OOP programlamanın gücüdür.

Kod: Tümünü seç

public class And3Expression : Expression
{
        //bag,shoe,hairdresser
        private Expression exp1;
        private Expression exp2;
        private Expression exp3;
        
        public And3Expression(Expression _exp1, Expression _exp2, Expression _exp3)
        {
            this.exp1 = _exp1;
            this.exp2 = _exp2;
            this.exp3 = _exp3;
        }
        public bool Interpret(string content)
        {
            return (exp1.Interpret(content) && exp2.Interpret(content) && exp3.Interpret(content));
        }
    }
Source Codes: https://github.com/borakasmer/CleanCode
Sources: refactoring.com, geeksforgeeks.org, en.wikipedia.org

Kaynak :

Kod: Tümünü seç

 https://medium.com/swlh/refactoring-for-clean-code-with-design-patterns-2d3d754c3bfe
Çeviri :

Kod: Tümünü seç

Google & www.YazilimAdasi.com - 2022
Teşekkürler :

Kod: Tümünü seç

https://medium.com/@borakasmer , Bora KAŞMER
Daha zeki olmanın tek yolu, daha zeki bir rakiple oynamaktır.
Cevapla

“Makaleler & Dokümanlar” sayfasına dön