Yusuf Bülbül

An Engineer

“Abstract Factory” Yazılım Tasarım Deseni

Geçen hafta yazılım mimarilerinden biraz bahsetmiştim. Bu yazımda Yaratıcı(Creational Design Patterns) tasarım desenleri kategorisinden “Abstract Factory” yazılım tasarım deseninden bahsedeceğim.  Bu yazıyı buradaki web sayfasına referans alarak yazıyorum.

Bu yazılım tasarım deseni,  daha çok GUI, veritabanı yönetimi ya da 3D, 2D çizimlerle ilgili işlemler yapan yazılımlarda kullanılıyor.  Gündelik hayattan örnek vermek gerekirse, bir otomobil fabrikasını düşünebilirsiniz. Bu fabrikada, farklı seriye ait otomobillerin gövde ve kapılarının üretildiği bir üretim hattı düşünün. Bu üretim hattının bir çok seriye ait farklı özellikte ama aynı işlevi gören parçaları üretebilmesi gerekiyor. İşte bu üretim hattı bir “Abstract Factory” dir. Çünkü aynı işi yapan ama farklı özellikteki bir çok nesneyi üretip bu nesneler ile bir otomobil kapısı ya da bir kaporta yapıyorsunuz. Daha sonra başka seriye ait araba üretmek istediğinizde elimizdeki nesneyi kaldırıp o seriye ait kapıyı üretecek olan bir nesneyi “Abstract Factory” ile oluşturuyoruz.

Bu tasarım deseni aslında bize aynı işlevi farklı şekilllerde yapan nesneleri, birbirlerine dönüşebilecek şekilde bir çatı altına toplamamızı öneriyor. Bu sayede, bir başlık altına topladığımız ve dönüştürülebilen bu sınıf, oldukça portatif ve çok daha farklı özellikler eklenebilen geliştirmesi kolay bir sınıf haline geliyor.

Burada tasarım desenindeki en belirgin özellik, ismine “Abstract Factory” dediğimiz bizim ihtiyacımıza yönelik nesneler üreten bir fabrika nesnesinin olmasıdır.  Bu nesneyi kullanmadan hiç bir zaman kendi başınıza nesne üretip onu kullanmıyorsunuz. Tüm istenilen servisler, bu nesne ile oluşturulup birbirlerine dönüştürülebiliyor.

Aslında daha basit anlamda anlatmak gerekirse, bir çakıyı düşünebiliriz. Çakı içerisinde farklı işlevler yapan bir çok nesne vardır. Bir çakı aynı zamanda, bir bıçak ya da bir açacak olabilir. Bu sayede, fabrika nesnesi aynı zamanda yalnızca bir sınıfın işlevini yerine getirebilir.  Uygulama, yalnızca soyut fabrikanın farklı bir somut örneğini başlatarak, tüm ürün ailesinin yerini alır.

Fabrika nesnesinin sağladığı hizmet çok fazla olduğu için, genellikle bu tasarım deseni “Singleton” tasarım deseni ile uygulanır. Bu tasarım deseninin amacı, bir çok sınıfı somut olarak belirtip kullanmadan, ilgili nesneleri bir çatı altına toplayıp birbirine dönüşebilmesini sağlayan bir arayüz oluşturmaktır.

 

Örnek bir C++ kodu vermek gerekirse şöyledir;

#include <iostream.h>

class Shape {
  public:
    Shape() {
      id_ = total_++;
    }
    virtual void draw() = 0;
  protected:
    int id_;
    static int total_;
};
int Shape::total_ = 0;

class Circle : public Shape {
  public:
    void draw() {
      cout << "circle " << id_ << ": draw" << endl;
    }
};
class Square : public Shape {
  public:
    void draw() {
      cout << "square " << id_ << ": draw" << endl;
    }
};
class Ellipse : public Shape {
  public:
    void draw() {
      cout << "ellipse " << id_ << ": draw" << endl;
    }
};
class Rectangle : public Shape {
  public:
    void draw() {
      cout << "rectangle " << id_ << ": draw" << endl;
    }
};

class Factory {
  public:
    virtual Shape* createCurvedInstance() = 0;
    virtual Shape* createStraightInstance() = 0;
};

class SimpleShapeFactory : public Factory {
  public:
    Shape* createCurvedInstance() {
      return new Circle;
    }
    Shape* createStraightInstance() {
      return new Square;
    }
};
class RobustShapeFactory : public Factory {
  public:
    Shape* createCurvedInstance()   {
      return new Ellipse;
    }
    Shape* createStraightInstance() {
      return new Rectangle;
    }
};

int main() {
#ifdef SIMPLE
  Factory* factory = new SimpleShapeFactory;
#elif ROBUST
  Factory* factory = new RobustShapeFactory;
#endif
  Shape* shapes[3];

  shapes[0] = factory->createCurvedInstance();   // shapes[0] = new Ellipse;
  shapes[1] = factory->createStraightInstance(); // shapes[1] = new Rectangle;
  shapes[2] = factory->createCurvedInstance();   // shapes[2] = new Ellipse;

  for (int i=0; i < 3; i++) {
    shapes[i]->draw();
  }
}

Bu örnek kodda  farklı geometrik şekilleri oluşturabilmek için bu şekilleri üretmemizi sağlayan bir fabrika(Factory) nesnesi vardır. Bu fabrika nesnesine dahil olan farklı iki grup şekli çizmemizi sağlayan başka fabrikalar(RobustShapeFactory, SimpleShapeFactory) vardır. “Factory” nesnesi farklı gruba ait şekilleri çizmek için kullanılan diğer iki farklı nesneye dönüşebilir. Ve bu türetilen “SimpleShapeFactory” ve “RobustShapeFactory” nesneleri aynı soyut sınıfın(Shape)  farklı özellikteki şekil sınıflarını(Circle, Square, Ellipse, Rectangle) oluşturabilecek fonksiyonlar içerir.

Bence yukarıdaki kod,  örnek tasarım desenini anlamak adına oldukça anlaşılır bir örnek.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Copyright © Tüm Hakları Saklıdır.