11 Kasım 2022 Cuma

Singleton Pattern

Bir sınıfın sadece bir tane nesnesi olsun ve bu nesneye global bir erişim noktası sağlansın.
Ne zaman kullanılır ? 
- Sadece bir tane kaynağa ihtiyacımız oludğunda (DB connection, soket connecction vb.) 
- Bellek israfını önlemek amacıyla stateless bir sınıfın birden fazla instancesini oluşturmamak için
Stateless Obje : instance variableları olmayan bir sınıftır. Sınıfın static fieldları olabilir

Singleton nesnelere global bir erişim noktasının olması bu patterni anti pattern yapar.
Singleton nesne uygulamanın her bir noktasından erişilebilir. Hemde herke tarafında kullanılabilir olduğu için uygulama boyunca bellekte kalacaktır.







10 Kasım 2022 Perşembe

Dependency İnvertion Principle


A sınıfı B sınıfını kullandığında Anın B ye bağımlı olduğunı söyleriz ve A,B olmadan çalışamaz. A nın B ye olan bağımlılığı ortadan kaldırmak için abstraction uygularız



A sınıfı artık direkt olarak B sınıfına bağlı değildir.Bunun yerine  bir absractiona bağlıdır. B de bu absractiona bağlıdır. Böylece ikiside absractiona bağlıdır. Bağımlılık tersine dönüştürülerek düşük bağımlılık sağlanmış olur.

Dependency Injection

Dependecy İnvertion bir prensibtir. Dependency Injectionda bu prensibi uygulamak için geliştirilmiş bir patterndir. Bir nesnenin kullanacağı nesneleri kendisi yaratmaktansa, dışarıdan başka birinin ona bu nesnleri vermesine Dependecy Injection denir. Bu da genellikle constructerlara konan parametrelerle yapılır.

İnterface Segregation Principle



Client A sadece A ve B metodlarını kullanıyor ve bunları implemente etmiştir. Fakat interface içerisinde geri kalan metodlarda olduğu için o metodları da implemente ediyor ve logic olarak throw exception fırlatarak o metodları boş geçmeye çalışıyoruz.

Yukarıdaki senaryoda bu inteface alt interfacelere bölünmelidir. Öyleki clientlar sadece görmek istedikleri metodları görmeli, alt sınıflarda sadece ihtiyacı olan sınıfları devralıp sadece onları onları implemente etmelidir.

Liskov Substitution Prensibi

Super Type ları kullanmayı bilen Clientlar subtype ları kullanırken şaşırmamalıdır. S, T nin bir alt türüyse, bir programdaki T türü nesneler programın işlevselliğini değiştirmeden S türü nesnelerle değiştirilebilir olmalıdır.


Deve kuşu sınıfı kuş sınıfını miras alıyorsa, Kuş sınıfının tüm özelliklerini yerine getirmelidir. Yukarıdaki örnekte olduğu gibi deve kuşu sınıfı uç metodunu gerçekleştiremez.

Open Closed Principle

Sınıflar, metodlar ve modüller değişiklik için kapalı, ancak genişleme için açık olmalıdır.
Anlamı
Eklemek istediğimiz her özellik için mevcut source koduna dokunmuyorsak bu sınıf değişime kapalıdır.
Aynı zamanda bir component, Yeni kod oluşturarak yeni şekillerde davranmamıza izin veriyorsa genişlemeye açıktır.

Schedulable'nin rahatlıkla farklı implementasyonlarını oluşturarak  genişleyebiliriz.Ve bu her yeni eklenen Employe,Equipment vs. Schedula sınıfınları sebebiyle Schedula sınıfında değişiklik yapmamıza gerek yok

Open Closed Principileyi uygulamanın 2 yolu vardır.

1- İnheritance
Kalıtım OCPyi uygulamanın güzel bir yoludur. Fakat kalıtımın dezavantajı base class ve sub class  arasında bağ oluşturuyor olmasıdır.

2- Strategy Desing Pattern
Strategy Patternde interface kullanıyoruz. Ve bu interafaceyi implement eden sınıflar birbirleri yerine kullanılabiliyor.

Single Responsibility Principle


- Her function, class yada modülün değişmesi için tek bir neden olması.
- Bir yazılımcı olarak componentdeki değişim nedenlerini belirlemeli ve bunların her birini tek bir bileşene indirmeliyiz.

1- IF Statement

Sorun : İF Statementlar metodun değişmesi için birden fazla nedenin olduğunun açık bir işaretidir. Bu durum Single Responsibility Principleyi ihlal eder.

Çözüm : if ve else branch logiclerini ayrı bir metod yada sınıfa çıkartmalıyız.

2- Swtich Statement
3- Monster Method 
Bir sınıfın içerisinde birden fazla işin yapılması
    income getIncome(Employe e){
        income income = employeRepository.getIncome(e.id);
        StateAuthorityApi.Send(income, e.fullName);
        PaySlip.paySlip = new PaySlip();    
        EmailService.Send(e.email, paySlip)
        . . .
        . . .
        return income ;
   }

Yukarıdaki kodda bir metod içersinde birden fazla işlem yapılmaktadır. Bu getIncome metodunun içeriği  yönetilebilir sınıflara ve metodlara ayrılmalıdır.


4- God Class

Utils classlarındaki tüm bu işler özel classlara taşınabilir. 


Paket :Birlikte release edilen yapılar aynı pakette olmalıdır.
Class : Sadece bir şeyi soyutlamalı ve sadece o şeyle ilgili veri ve davranışa sahip olmalıdır.
Metod : Sınıfın soyutladığı şeyle ilgili tekrar kullanılabilecek bölünmez tek bir iş yapmalıdır.
Blok : Metod seviyesine çıkamamış dolayısıyla da tekrar kullanımı söz konusu olmayan ama ya hep ya hiç şeklinde çalışan bir grup cümle olmalıdır.
Cümle(Statement) : Bir bloğun yada metodun parçası olarak bir işin tek bir adımını rahat anlaşılır bir şekilde yerine getirmelidir. Bir satır da sadece bir cümle, bir cümlede sadece bir adımı yerine getirmelidir.

Metod, Tekrar kullanımın en temel öğesidir.
- Tekrar kullanılma ihtimali olan her blok yada cümle vb. kod parçası ne kdar kısa olursa olsun ayrı bir metod olmalıdır. Aksi takdirde aynı kod parçası copy-paste ile farklı yerlere dağılır. Tekrar kullanılması gereken hatta ihtimali olan kod parçaları refactoring sürecinde metod haline getirilmelidir.
- Metodlar 10-15 satırı geçmemli ve max parametre sayısı 3 olmalıdır.

NOT: Bir kodun içinde davranış İF- ELSE ile değişiyorsa her farklı if-else branchini bir başka polymorfik nesneye atayın, Öyleki bunlar aynı tipin sub nesneleri olsun.

SOLİD Prensibleri

 

Eğer SOLİD Prensiblerini uygulamazsak aşağıdaki senaryolardaki sorunlarla karşılaşırız.

senaryo 1 : Yukarıdaki modüllere sahip bir uygulamamızın olduğunu düşünelim. Yeni bir değişiklik talebi geldiğini ve yeni bir payment metodu eklenmek isteniyor olsun. Bu nedenle gidip payment metodunda değişikliği yapıyoruz. Daha sonra uygylamayı canlıya alıyoruz. Farkediyoruz ki diğer alt sistemler patlamış. Buna kod kırılganlığı denir(Code Fragility).

senaryo 2 : Artık raporları yeni bilgilerle güncellememiz gerekiyor. Raporlama modülüne gidiyoruz ve değişikliği uygulamaya çalışırken farkediyoruz ki raporlama modülünü değiştirmek için diğer modülleride değiştirmemiz gerekiyor. Buna da kod katılığı denir(code rigidity)