Factory Method tasarım deseni, nesne oluşturma ihtiyacı doğrultusunda
ortaya çıkmış bir tasarım desenidir. Bu tasarım deseni, oluşturulacak
somut nesnenin türünü belirlemeye gerek duymadan nesne oluşturma
işlemini temel almaktadır.

Resim-1
Factory deseninin temel amacı nesne oluşturma karmaşıklığını
kullanıcıdan gizlemektir. Ayrıca kullanıcı, oluşturulacak nesnenin somut
türünü belirlemek zorunda değildir. Bunun yerine somut nesnenin
implemente edildiği soyut tür olan
interface veya
abstract class tipini bilmesi yeterlidir. Yani sorumluluk somut nesnelerden soyut nesnelere aktarılmaktadır. Genel olarak
Factory sınıflar “
static”
erişim belirleyicili bir metod barındırırlar. Bu metod, kullanıcıya
interface veya abstract class tipinde bir nesne döndürür. Bu sayede
kullanıcılar, alt sınıfların oluşturulması sorumluluğundan dolayı
oluşabilecek hatalardan da uzak tutulmuş olur.
Örnek Uygulama
Bu örnek uygulamamızda Grafik türüne göre Grafiğin temsilini yapan
Sembollerin oluşturulmasını Factory Method yöntemiyle üretmeyi
amaçlamaktayız.
Yukarıdaki şekildeki tasarım deseninin uygulanışını şu şeklide yapabiliriz.

Resim – 2
Gerçek bir uygulamadan alarak göstereceğim bu örnekte bir REST
servisinden gelen Graphic nesnesinin türüne göre sembol nesnesinin
belirlenmesi işlemini Factory Method inceleyeceğiz. Tabi bu örnekteki
konumuz Factory uygulaması olduğundan Servis işlemlerini temsili olarak
göreceğiz. Bizi ilgilendiren sadece nesne üretimi olduğundan nesne
üretim aşamasını inceleyeceğiz.
public class Graphic
{
public Symbol Symbol { get ; set ; }
}
|
Bize servis tarafından sunulan
Graphic nesnesi Null olarak gelmektedir. Biz yazılım tarafında Graphic nesnesinin türüne göre Sembolünü üretmekle sorumluyuz.
public abstract class Symbol
{
public abstract void draw();
}
|
Symbol sınıfının soyut bir tip olduğunu görüyoruz.
Graphic sınıfında da bu soyut tip kullanılmıştır.
public class SimpleLineSymbol: Symbol
{
public override void draw()
{
}
}
public class SimpleFillSymbol: Symbol
{
public override void draw()
{
}
}
public class SimpleMarkerSymbol: Symbol
{
public override void draw()
{
}
}
|
Somut sembol sınıfları ise
SimpleLineSymbol,
SimpleFillSymbol,
SimpleMarkerSymbol şeklinde oluşturulmuştur.
public class GraphicSymbolFactory
{
public static Symbol GetSymbol(Graphic graphic)
{
if (graphic is Point)
return new SimpleMarkerSymbol();
if (graphic is Polygon)
return new SimpleFillSymbol();
if (graphic is Polyline)
return new SimpleLineSymbol();
throw new InvalidExpressionException( "Unknown graphic type" );
}
}
|
GraphicSymbolFactory sınıfına eklediğimiz
GetSymbol metodu,
Graphic türüne göre somut olan
Symbol tiplerini oluşturmaktadır. Dikkat edecek olursak kullanıcıya soyut olan bir
Symbol tipi vermekteyiz. Yani içerde olup bitenden kullanıcılar haberdar değildir.
public class GraphicService
{
private readonly IGraphicRestService service;
public GraphicService(IGraphicRestService service)
{
this .service = service;
}
public Graphic GetGraphicsFromRESTService( string serviceUrl)
{
Graphic graphic = service.GetGraphic(serviceUrl);
graphic.Symbol = GraphicSymbolFactory.GetSymbol(graphic);
return graphic;
}
}
|
GraphicService sınıfı içerisinde tanımlı
GetGraphicsFromRESTService metodu, bir servis yardımıyla
Graphic nesnesini elde etmektedir. Gelen
Graphic nesnesinin sembolü ise kullanıcı tarafından Factory sınıfı yardımıyla belirlenir. Burada kullanıcı diye adlandırdığımız
GraphicService sınıfıdır aslında. Çünkü API içerisinde hazırladığımız
GraphicSymbolFactory tipini kullanan sınıftır. Kullanıcı sınıf aslında
Symbol tipinden türetilen
SimpleLineSymbol veya
SimpleFillSymbol
gibi tiplerden haberdar değildir. Bu somut tipleri oluşturmak zorunda
da değildir. Bu karmaşık sorumluluğu Factory deseni ile bir sınıfa
aktarmış olduk.