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ı

SOLID Prensipleri : 01 Single Responsibility ve Agile Metodolojilerde Önemi

By Burak Tungut - 15.12.2015 - Kategori Design / Architectural Patterns

Herkese selam laugh

Paylaştığım iki adet elasticsearch makalesinden sonra araya başka bir makale koymak iyi olur diye düşündüm. Hep aynı konuları işleyen türk dizileri gibi on tane elasticsearch makalesi eminim düzenli okurlarımında canını sıkardı. Hem ilgilenen var, ilgilenmeyen var efendim! Öyle değil mi?

Gelelim okumaya başladığınız makalemizin konusuna. Gariptir ki bu makalede aslında SOLID prensiplerini işleyeceğim makale serisinin ilk adımı niteliği taşıyor. Yani paralelde başka bir seriye daha girmiş olduk. Sonumuz hayır olsun.

SOLID prensipleri 2000'li yıllarda Robert C.Martin tarafından ortaya atılmış beş adet prensipten oluşur. SOLID ismi ise bu beş presibin isimlerinin ilk harflerini alarak oluşturulmuştur. Yabancı kaynaklarda çevrilmiş haliyle SOLID presinsiplerinin amacı ise kısa vadede bazen taklalar atarak uzun vadede daha maintain (bakım) edilebilir ve extensible (genişletilebilir, esnetilebilir) mimariler kurulmasıdır. 

SOLID ve Agile Metodolojilerdeki Önemi

Günümüzde SOLID'in popülerliğinin arttığını şahsen görüyorum. Bunun nedenlerinden biri ise aslında Türkiye'de agile metodolojilerin git gide kullanılmaya başlanması. Sonuçta ne kadar agile software team o kadar refactoring, maintain edilebilirlik ve haliyle SOLID implementasyonları diyorum.

Bazen öyle legacy code içeren projeler görüyoruz ki bir sınıfında binlerce satır olabiliyor. (5000 satırı görmüşlüğüm var surprise)  Bunun en büyük nedenlerinen biride o yıllarca üstüne business eklenerek büyümüş olan projelerin her bir modülünün tamamiyle bir kaç developer sorumluluğuna bırakılması (A modülüne iş var. Kim bilir? Hasan bilir!)
Bir de ürün yetiştirmek için gerekli zamandan daha hızlı geri dönüşler bekleyen bir firmadan bahsediyorsak o modüllerden okunabilir kod çıkma olasılığı gittikçe düşüyor. Velhasıl sayabileceğimiz bir çok madde ve dış etkenler mevcut.

Konuyu çok dağıtmayayım. Bunlar benim şahsi görüşlerim idi. Yukarıda verdiğim örnek ile geçmişte uygulanan metodolojilere dil uzatmak istemedim. Sonuçta elde olan bu ise ve koşullar onu gerektiriyorsa pekte yapılabilecek birşey kalmıyor smiley

Şimdi SOLID prensiplerinden Single Responsibility yani Tek Sorumluluk prensibini incelemeye başlayalım.

Solid prensipleri

Devamı

C# ile Dependency Injection ve Loosely Coupling

By Burak TUNGUT - 6.5.2013 - 1 Yorum - Kategori C#

Düzgün ve detaylı bir analiz yapılmadan geliştirme sürecine geçilmiş bir çok projenin eninde sonunda başvurduğu nadide yöntemlerden biridir Dependency Injection.

Dependency Injection ve Loosely Coupling Genellikle geliştirme sürecinde ihtiyaç duyulan gereksinimlere göre yapılan projelerde bir sorun görülmese de, zamanla ihtiyaçların artacağı ve sıkı bağlı tipler ile geliştirilmiş projelerde ciddi sıkıntılar yaşanabilmektedir.

Az önce güzel bir anahtar kelimeden bahsetti; sıkı bağlı!
Aslında biz bu anahtar kelimeden ziyade, bunun tam tersi ile ilgileniyor olacağız. Yani; gevşek bağlı (Loosely Coupled).

Gevşek bağlı tipler ile çalışmanın en büyük faydası projenin ilerleyen zamanlarda gelişime açık ve rahatça revize edilebilmesidir.

Konuyu ilk hakimiyeti sağlamanın en güzel yolu kanımca göresellerdir. Bunun için yandaki gibi fareye bağımlı olmuş bir insan elini örnek alabiliriz smiley

Günlük Hayattan Bir Senaryo

Bir proje yapıyor olalım. Bu projenin bir aşamasında da kullanıcının fareyi ara bir tip ile kullanması gerektiğiniz düşünelim.

Proje tahmin edileceği üzere düzgün bir şekilde analiz edilmediği için farenin hiç bozulmayacağı ya da fareden beklenen ihtiyaçların hiç değişmeyeceği düşünüldü. Bu nedenle de sokakta görülen ilk bilgisayarcıdan bir fare alındı ve kullanıcının eline tıpkı resimde olduğu gibi verildi smiley

Bir müddet sonra fark ettik ki elimizdeki fare artık bizim ihtiyaçlarımızı karşılayamıyor. Bu durumda akla gelen ilk çözüm o fareyi atıp, yerine yeni bir fare almak olacaktır. Tabi ki yazılım geliştirme ve revize işlemlerindeki süreçler ne yazık ki günlük hayattan verdiğimiz bu örnekteki gibi olmuyor blush

Senaryonun Yazılım Tarafı

Şimdi ise düşündüğümüz bu senaryoyu C# ile uygulamaya dökelim. Bunun için LogitechMouse adlı bir sınıf tasarlıyor ve içerisinde ekrana kullanılan farenin markasını yazacak Write adlı bir metod yazıyorum.

class LogitechMouse
    {
        public void Write()
        {
            Console.WriteLine("Logitech Mouse Kullanıldı");
        }
    }

Bir de mouse ile kullanıcı arasındaki entegrasyonu sağlayacak ara bir sınıf daha yazıyorum. Bu sınıfımızın adı da MouseManager şeklinde olsun ve içerisindeki Use metodu tetiklendiğin de bir adet LogitechMouse sınıfından instance alsın ve Write metodunu tetiklesin.

Devamı
1
Facebook
Son Yorumlar