Factory Tasarım Deseni

header_factory

Yaratımsal kategoride yer alan diğer tasarım deseni factory desenidir.Aynı arayüze veya soyut sınıfı uygulayan sınıfların nesnelerinin oluşturulmasından sorumludur.Bu sınıflardan nesne oluşturma işlemi  sınıfın uyguladığı arayüz veya soyut sınıf aracılığıyla fabrika sınıfları tarafından oluşturulur.

diagram_factory

Yukarıda bir sınıftan nesne oluşturulmasına yönelik bir diagram görüyorsunuz.Yeni yazdığımız bir sınıftan nesne oluşturmak istediğimizde doğrudan new anahtar kelimesini kullanarak nesne yaratım işlemini gerçekleştirebiliriz.Bu desen ile istemci kodun bu sınıftan nesne oluşturması için araya factory yapısını yerleştiriyoruz.Desenin mantıksal modeli bu şekildedir.Teknik açıdan bakıldığında bir kaç kalıtılmış sınıfından nesne üretilmesi için kullanılır.

Factory deseni ile bir sınıfın nesne oluşturma ve fonksiyonellikleri birbirinden ayrılmış olur.İstemci kod doğrudan asıl sınıfın fonksiyonelliğine erişemez.Asıl sınıfın fonksiyonellikerine erişmek için factory methodu veya sınıfı aracılığıyla asıl sınıfından bir instance oluşturur ve bu şeklide fonksiyonelliklere erişebilmiş olur.İstemci ve işi yapacak olan sınıf fonksiyonellikleri birbirinden ayrıldığı için gevşek bağımlılık sağlanmış olur.

Bu desenin Enterprise Library içerisinde Unity blogu içerisinde kullanıldığını buradan görebiliriz.Örneğin bir bankacılık istemi içerisinde bir çok çeşit ödeme dosyası sistemde izlenilen bir dizine düşüyor.Bu dizine düşen dosyaları işlemeniz ve bu bilgileri sistem içerisine entegre etmeniz gerekiyor.Burada dosya tipine bağlı olarak (xml,txt,xlsx) farklı işler yapacaksınız fakat dosya tipinden bağımsız olarak dosyayı açmanız(open), belirli validasyonlardan geçirmeniz (valid) ve ayrıştırmanız (parse) gerekiyor.Bu gibi ortak özellikler için arayüz tanımlanır.Her bir dosya tipi için tüm fonksiyonları içeren ayrı ayrı sınıflar yazılıp bu işlemleri o şeklide gerçekleştiririz.Bu gibi ortak karakteristiği olan sınıfların nesne örneğinin oluşturulması için bu deseni kullanımı güzel bir strateji olabilir.

Tasarım

factory-implementation

Yukarıda en temel şekli ile factory deseninin UML şemasını görüyorsunuz.Factory desenin temel olarak 2 farklı şeklide uygulama yöntemi vardır.Birinci yöntemde nesnelerin oluşturulması için Creator veya Factory soneki almış bir sınıf bir sınıf içerine tek bir method araılığıyla oluşturulur.Diğer yöntemde ise her nesne için ayrı bir factory sınıf yazılır.İki yönteminde yaptığı iş aynı kurgusu farklıdır.Fakat ikinci yöntemi tercih ettiğimizde yeni eklemeler daha rahat olacaktır.

Factory Method

Aşağıda ilk yöntem için yazılan kod örneğini görüyoruz.Burada dökümanları okumak için altyapı oluşturulmaya çalışıyor.Burada generic kullanım şeklini de görüyorsunuz.

Factory Sınıfı

Bu yöntemde ise concrete sınıflarımız için factory sınıfları yazıyoruz.Yani PDFReader ve MsWordReader sınıfları için PDFReaderFactory ve MsWordReaderFactory sınıflarını tanımladık.Kullanım kısmında göreceğiniz gibi nesne örnekleri için bu factory sınıflarını kullanıyoruz.

Örnek Kodlama

Örnek kodlamamızda Muhasebe gerçekleştirim işlemi için sınıf yapılarını oluşturmaya çalışlıyoruz.Burada muhasebesi yapılacak işlemin türünden (yurtiçi,yurtdışı,avrupa ödemesi) bağımsız olarak Teknik bazı ortak fonksiyonellikleri var bunun için interface ve soyut sınıf tanımladım.Kurguladığım bu örnek için her bir asıl sınıf için factory sınıfları tanımladım ve muhasebe akış sınıfı için bu factory sınıflarını kullandım.

Örnek kodlarımızın sınıf diagramını görelim.

 

capture_diagram

Sonuç

Birbirine yapısal olarak farklı ama bazı ortak özelliklere sahip -interface veya abstract kalıtımı- sınıfların nesnelerinin oluşturulmasını sağlar.Aynı zamanda nesne oluşturma sürecini merkezi hale getirerek belirli kriterlere göre hangi nesnenin oluşturulacağı gibi kararlarının alınmasına da yardımcı olur.

İlişkili olduğu desenler

  • Null Object Pattern ; hiç bir duruma girmeyen durumlarda var sayılan olarak nesne gönderilmesi durumunda NULL tanımlı bir nesne örneğinin gönderilmesi düşünülebilir.

Şimdilik bu kadar.Yazıda yanlış olarak ifade edilen noktalar görürseniz lütfen yorumlayın :D

Singleton Tasarım Deseni

header

Yaratımsal desenler içerisinde yer alan singleton bir sınıfın uygulama yaşam süresi boyunca tek bir nesne örneğinin oluşturulmasını sağlamak için kullanılır.Ayrıca singleton olarak tasarlanan sınıfın global bir erişim seviyesine sahip olmasını da garanti eder.Bir sınıfın örneğinin oluşturulması istediğimizde newanahtar kelimesini kullanırız.Bu anahtar kelimeyi kullandığımız sınıflara bakıldığında yapıcı methodun erişim belirleyicisinin public olduğunu görürsünüz.Yeni yazılan sınıfların yapıcı methodu varsayılan olarak gizli bir puclic yapıcı methoduna sahiptir böylelikle new anhatar kelimesiyle nesneyi oluşturabiliyoruz.Singleton olarak tasarladığımız sınıflar da bu yapıcı method dışarıdan erişime kapatılarak sınıftan nesnelerin oluşturulması engellenmiş olur.Bir sınıfı singleton olarak tasarlamak istediğimiz de aşağıdaki bir kaç adım bize yardımcı olacaktır.

  • ilk olarak sınıftan nesne oluşturulmasını sağlayan yapıcı methodun erişim belirleyicisi private veya protected yapılarak dışardan erişime kısıtlanır.Bunu yaparak sınıfın new  ile oluşturulması engellemiş oluyoruz
  • Sınıfı sealed olarak işaretleyebiliriz
  • Nesne yaratmak için sınf içerisinde kendi tipinde private erişime sahip static bir değişken tanımlanır.
  • Son olarak singeleton tipimizi temsil etmek için static ve public olarak bir method veya propertytanımlıyoruz.Bunun içerisinde nesnenin yaratılması sağlanıcak.Bu method veya property yi kullanarak istemci nesneye erişim sağlar.

singleton-design-pattern

İstemci kod parçası singleton olan sınıfın örneğinin oluşturmak istediğinde eğer daha önce hiç nesne oluşmadıysa ilk olarak nesne oluşur fakat daha sonraki nesne çağrımlarında daha önce oluturulan nesne gönderilir.Yukarıdaki resimde geleneksel ve singleton implementasyonunu görebilirsiniz.

Uygulanabilirlik

Singleton deseni aşağıdaki durumlarda kullanılabilir.

  • Bir sınıftan sadece bir nesne örneğini,n olması öngörüldüğünde
  • Singleton uygulanacak sınıfın global bir erişim seviyesine sahip olması durumunda ve uygulamanın diğer tüm bileşenleri bu sınıfa erişilebilmeli
  • Sınıftan nesne oluşturması masraflı olduğu durumlar da 
  • Singleton olması istenen sınıfın yapıcı methodu parametresiz olması gerekir

Singleton deseni kullanılma sıklığı diğer desenlere göre daha fazladır ve çok daha kolay uygulanır.Bir framework tasarımında genelde caching , logging , kaynak tüketim sınıfları (database connections,file processor) gibi sınıflar singleton olarak tasarlanır.

Tasarım

Desenin UML şemasını görelim.

singleton_diagram

Singleton desenenin single-threaded ve multi-threaded olarak iki farklı gerçekleştirim yönetemi vardır.Kodunuzun bulunduğu ortamın multi-thread olup olmamasına bağlı olarak bu yöntemler kullanılır.Aşağıda farklı singleton uygulama versiyonlarını görelim.

Thread safe olmayan kod örneği

Bu kod parçacığı Thread safe bir kod değildir.Eğer iki farklı thread yakın zaman dilimlerinde bu sınıftan Instance methodunu çağırırsa iki ayrı nesne oluşur.Singleton deseninin gereklilikleri sağlanmamış olur.Bu kod tamamiyle teorik olarak singleton desenini uygulamıştır.Kullanılması önerilmez.

Thread Safe kod örneği

Singleton deseninin bu versiyonu thread-safe versiyonudur. Thread paylaşılan bir nesne üzerinden (lock) kilitlenir ve nesne örneğinin yaratılıp yaratılmadığını kontrol eder.

Lazy initialization

Lazy initialization bir nesnenin yaratılmasını geçiktirmek için bir taktiktir.Nesne ihtiyaç duyulacağı son ana kadar nesne yaratılmaz.NET 4 ile Base Class Library içerisine dahil olan generic Lazy tipi ile Lazy Initialization  işlemini gerçekleştiriyor.Bu tipi kullanarak singleton desenini kolaylıkla uygulayabiliriz.

Generic Singleton

Singleton desenini uygulamak istediğimizde , varolan sınıfın düzenlememiz gerekir.Tipten bağımsız bir şeklide bir sınıf singleton yapmak istersek  generic singleton ile kolaylıkla bunu gerçekleştirebiliriz.

Gerçek hayat örneği

Uygulamalarımızda kullanıcının yaptığı işleme göre hata mesajı , uyarı mesajı veya işlemin sorunsuz tamamlandığına dair bir mesaj veririz.Verdiğimiz bu mesajları kodumuza doğrudan yazmak yerine bunun için bir key tanımlayıp bu key e karşılık gelen string ifadeyi uygulamanın veri kaynağında key-value şeklinde tutmak istediğimiz düşünün ve bunun için de gerekli olan StringManager sınıfını yazdık.Fonksiyonel olarak düşündüğünüzde StringManager sınıfına uygulamanın her yerinden (app , uı) istek de bulunulabilir ve istenildiği kadar nesne oluşturulabilir.Bu aşırı kaynak üretimine ve uygulama yavaşlamasına sebep olacaktır.Bu sınıfı aşağıdaki şekilde singleton olarak tasarladık.

İlişkili olduğu desenler

  • Abstract Factory daki gerekli görülen ConcreteProduct sınıfları singleton tasarlanır.
  • Factory Method
  • Builder 
  • Durum sınıfları sıklıkla singleton olarak tasarlanır.
  • Alt sistemleri oluşturan Facade tipleri singleton tasarlanır.

Sonlandırırken

Singleton deseni genel olarak test edilmesi zor olduğundan mümkün olduğunda kullanmamak gerekir ve bu sebeple çoğunlukla anti-pattern olarak algılanır.Bunun yerine IoC Container gibi yapıları kullanmak daha efektif bir çözüm olarak görülür.

Peki neden bir sınıfı static yerine singleton tasarlamalıyım ?

Genel olarak bakıldığında singleton deseninin sağladığı fonksiyonelliği static sınıfların da karşıladığını düşünebiliriz.Fakat static sınıflar singleton yapılardan tamamiyle farklıdır.Şimdi bu yapılar hakkındaki bir kaç önemli noktaya bakalım.

  • Static sınıflar sistemdeki global verilere erişim için kullanılabilir. hızlı erişim ve performans sağlar
  • Singleton sınıflar geleneksel sınıf yapısını korur , static sınıfların kullanılması nesne yönelimli prensiplerden uzaklaştırır.
  • Singleton tasarladığımız sınıflar üzerinden kalıtım yapabiliriz diğer taraftan static sınıflarda kalıtım yapılamaz
  • Singleton ihtiyaç olduğu durumlarda lazy olarak tasarlanabilir.

Şimdilik bu kadar. Aşağıda kaynak kodları ve dökümanları bulabilirsiniz.Yazıda yanlış olarak ifade edilen noktaları görürseniz lütfen yorumlayın 😀

Interpreter design pattern

You can see a sample implementation of the interpreter design pattern.it’s possible smilliar to each other definitions for interpreter in internet literature.

  •  interpreter pattern is a design pattern that specifies how to evaluate sentences in a language
  • Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
  • Map a domain to a language, the language to a grammar, and the grammar to a hierarchical object-oriented design

Sample scenarios for this pattern

  • read barcode
  • roman numbers converting numbers   –   (X == 10)
  • Total ASCII values ​​of the characters  – (A == 65)
  • reading result operations with mathematical and logical operators (10*5-3==47)
  • analysis of the encrypted text

Now let’s take a look our sample codes and diagram

ClassDiagram1

Main classes

example of use:

see you blog post

also get clone using VisualStudio 2012 with git source control in the bitbucket repository.You can see repository address and git address in the below

Repository : https://bitbucket.org/yemrekeskin/interpreter.designpattern

Git : https://yemrekeskin@bitbucket.org/yemrekeskin/interpreter.designpattern.git to get clone repository

[Code] Events for uncaught exception

You see sample codes for Unhandled exception as follows. Unhandled exception Event is notification of uncaught exceptions.I met with such a case while i have been coded a console application named ReportExporter for payments reports and i want to share this case

see you blog post