SOLID Prensipleri : 03 Liskov Substitution Principle

By Burak Tungut - 15.6.2016 - 5 Yorum - Kategori Design / Architectural Patterns

Selamlar herkese,

Son 1 haftadır bazı çalışma arkadaşlarımın "Yazmaya neden ara verdin?" tepkilerine daha fazla dayanamıyor ve bu yazımızda SOLID prensiplerinden Liskov Substitution - Liskov'un Yerine Geçme prensibini inceliyor olacağız. Yazmam için sürekli beni dürten sevgili çalışma arkadaşım Barış BIYIK'a teşekkürlerimi buradan da iletmek isterim :)

Liskov Substitution aslında Prof. Barbara Liskov ismindeki bir bilim insanının tasarladığı bir prensip.
Prensip bize der ki ;

"Aynı base sınıftan üretilen tüm alt sınıflar, birbirlerinin yerine kullanılabilir olmalıdır. Alt sınıflara özel bir istisnai durum kesinlikle oluşmamalıdır."

Bazen abstract class'lar ile interface'ler arasındaki farkın ne olduğuna dair sorularda alıyor olabilirsiniz. Aslınd bu prensibin amacı bu iki tip abstraction yapmamızı sağlayan tip arasındaki en büyük farkı göstermekte. Birazdan yapacağımız örnek ile bunu çok daha iyi anlıyor olacağız.

 

Liskov Substitution Principle

 

Küçük Bir Senaryo İle Liskov Substitution Principle

Farz edelimki ürünlerin ve ürünler üzerinde çeşitli business'ları işletebilecek üyelik tiplerinin olduğu bir proje geliştiriyoruz. Çok minimal bir ürün tipi tasarlayalım. Ben aşağıdaki gibi bir şeyler tasarladım;

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public List<string> Features { get; set; }
}

Devamı

Gerçek Hayattan Factory Method Design Pattern Örneği

By Burak Tungut - 5.6.2016 - Kategori Design / Architectural Patterns

Selamlar herkese,

Bu yazımda sizlerle gerçek bir uygulama ile Factory Method Design Pattern'in nasıl uygulanacağını paylaşacağım. Geçtiğimiz aylarda üzerinde çalıştığımız ana modüllerimizden birinde sürekli benzer istek ve değişikliklerin geldiğini fark ettik. Uygulamada ki genel gidişimizde sürekli if-clause'lar üzerine dayanmaya başlayınca buna bir dur demek istedik ve biraz sonra sizlerle paylaşacağım bir geliştirme gerçekleştirdik. Dilerseniz uygulamaya geçmeden önce ihtiyacın ortaya çıkmasına sebep olan istekleri biraz inceleyelim.

Not : Makale aşağıda listelediğim bazı konuları içerir. Aşağıdaki konular hakkında bilgi sahibi iseniz harika! Değilseniz makalenin daha anlaşılabilir olabilmesi için bir kaç saatinizi ayırarak önce bu listeyi halletmenizi önemle rica ediyorum :)

  • Thread Safety
  • Stateless-Stateful
  • Principal & Identity
  • Reflection

"Backend'i Aynı Olsun, Frontend'i Farklı"

Geliştirmekte olduğumuz bir ürünümüz başlangıçta bir kullanıcı tipine sahip iken iş birimlerimizden bu tiplerin çoğalacağı haberlerini aldık. Fakat her kullanıcı aynı veriye erişirken, verilerin gösterim biçimleri farklı olacaktı. Benzetmek gerekirse uygulamada kullanıcı tipi farketmeksızın herkes beş adet ürün görecek lakin kimi kullanıcı tipleri bunları slider ile görecek iken kimileri bir table içerisinde görecekti.

İsteğe çevik bir şekilde cevap vermek adına geliştirmeleri tamamladık. Lakin MVC projemizde fark ettik ki Controller ve Action'larımız hiç değişmez iken bunları execute ettiği View'larda sürekli if blokları yazmak durumunda kaldık. Tıpkı aşağıdaki gibi;

<h2>Product</h2>

@if (userType == FactoryMethod.Core.UserType.New)
{
    <b>Slider ile datayı görüntüle</b>
}
else if (userType == FactoryMethod.Core.UserType.Old)
{
    <b>Table ile datayı görüntüle</b>
}

Bu if-clause'ları View'dan alıp Action'lara koyarsakta çok bir değişiklik olmayacaktı. Buyrun bakalım;

public class ProductController : Controller
{
    UserType userType = UserType.Old;

    public ActionResult Index()
    {
        //Business call

        if (userType == UserType.New)
        {
            return View("IndexOfNewUsers.cshtml");
        }
        else
        {
            return View("IndexOfOldUsers.cshtml");
        }
    }
}

Bu iki yapının arasında kalsak ben kesinlikle ikinci olanı seçerdim. Sonuçta tüm business ve backend aynı iken sadece frontend değişiyor ise View'ları ayıralım. Hangi View'ın execute edileceğine ise bir önceki pipeline katmanında karar verelim.

Başka Kullanıcı Tipleri Eklenmeye Devam Ederse?

Son yaptığımız haliyle uygulama daha kabul edilebilir bir hal alabilir. Fakat bu yapıyı inşaa etmemize neden olan istekler gelmeye devam ederde yeni kullanıcı tipleri eklenmek isterse sürekli her Action'a if blokları mı yazacağız? İşte bu noktada artık bir dur dememiz gerekir.

Bizim artık öyle bir yapıya ihtiyacımız var ki ne View ne de Action bir state'e bağlı olsun. Yani stateless olsun. Action'ımız Business Engine'ler ile konuşsun, gerekli model'i intialize etsin ve View'a versin. View'da asla business içermesin gerekli veriyi istendiği gibi göstersin.

O zaman bu stateless olarak belirlediğimiz scope'un dışında kullanıcı tipine (ya da herhangi stateful bir olgu) göre akışı değiştirecek, ilgili View'ı bulup execute edecek bir yapıya ihtiyacımız var. 

Biraz detaylıda olsa problemimizi tanıdığımıza göre gerçek bir uygulama ile sorunumuzu çözmeye başlayabiliriz.

Devamı
1
Facebook
Son Yorumlar