Abstract Factory Tasarım Şablonu

Amaç

Sorun

Yazdığımız uygulamanın değişik platformlarda çalışmasını istediğimizde bu platformlara özgü farklılıklar sorun oluşturur ve nesne yaratımlarında bu farklılıkları ele almamız gerekir. Örneğin, windows işletim sistemindeki arayüz birleşenleri ile ubuntu işletim sistemindekler arasında ciddi farklar vardır ve biz her yeni birleşen oluşturma esnasında platformu kontrol etmek, ona göre farklı şekilde yaratmak istemeyiz. Bir arayüz tasarlamak ve bu ortak arayüz üzerinden bütün nesneleri yaratmak ve kullanmak isteriz. Platforma özgü sınıflar bu arayüzü destekleyecek şekilde kendi birleşenlerini oluşturacak işlevselliği sağlarlar.

Yöntem

Bu tasarım şablonunda nesnelerin sınıflarını ve nesneleri üreten üretici sınıfları soyutlamamız gerekir. Bu nesneler kullanıcılar (clients) tarafından doğrudan oluşturulmayıp nesne üretici (fabrika) sınıflar vasıtası ile üretilirler.

Yapı

Abstract Factory her bir ürün için bir Factory Method (makeProductOne,makeProductTwo vb.) tanımlar. Her Factory Method new operatörünü ve platforma özgü ürün sınıflarını sarmalar. Her platform fabrika sınıflarıyla modellenir.

Örnek

Örneğimizde Ubuntu ve Windows platformları için UI birleşenleri üreten bir Abstract Factory şablonu oluşturalım. Bu örnekte platformlardan bağımsız bir şekilde pencere ve buton üreten bir yapı kuralım. Örneğin UML diagramı ve kodu aşağıda mevcuttur.

Buton arayüzü ve Windows+Ubuntu Platformları için ürün sınıfları





Pencere arayüzü ve Windows+Ubuntu Platformları için ürün sınıfları



Abstract Factory ve Windows+Ubuntu Platformları için fabrika sınıfları



Kod


public interface Button {
    public void click();
    public void setLabel(String label);
}

public interface Window {
    public void setHeader(String label);
    public void openWindow();
    public void closeWindow();
}

public interface AbstractUIFactory {
    public Button createButton();
    public Window createWindow();
}

public class UbuntuButton implements Button {

    @Override
    public void click() {
        System.out.println("UbuntuButton is  Clicked");
    }

    @Override
    public void setLabel(String label) {
        System.out.println("UbuntuButton label is set as "+label);
    }
}

public class UbuntuWindow implements Window {

    @Override
    public void setHeader(String label) {
        System.out.println("Ubuntu window header is set as "+label);
    }

    @Override
    public void openWindow() {
        System.out.println("Ubuntu window is opened");
    }

    @Override
    public void closeWindow() {
        System.out.println("Ubuntu window is closed");
    }
}

public class UbuntuUIFactory implements UIFactory {

    @Override
    public Button createButton() {
        return new UbuntuButton();
    }

    @Override
    public Window createWindow() {
        return new UbuntuWindow();
    }
}

public class WindowsButton implements Button {

    @Override
    public void click() {
        System.out.println("Windows Button is  Clicked");
    }

    @Override
    public void setLabel(String label) {
        System.out.println("WindowsButton Label is set as "+label);
    }
}

public class WindowsWindow implements Window {

    @Override
    public void setHeader(String label) {
        System.out.println("Windows window header is set as "+label);
    }

    @Override
    public void openWindow() {
        System.out.println("Windows window is opened");
    }

    @Override
    public void closeWindow() {
        System.out.println("Windows window is closed");
    }
}

public class WindowsUIFactory implements UIFactory {

    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public Window createWindow() {
        return new WindowsWindow();
    }

}

public class Client {

    public static void main(String[] args) {

        /**
         *  buradan sonra abstractUiFactory üzerinden nesneleri olusturuyoruz.
         *  windows mu ubuntu mu umrumuzda değil.
         */
        AbstractUIFactory abstractUiFactory =  createUIFactoryAccordingToOS();

        doButtonOperations(abstractUiFactory);
        doWindowOperations(abstractUiFactory);
    }

    private static void doWindowOperations(AbstractUIFactory abstractUiFactory) {
        Window window = abstractUiFactory.createWindow();
        window.setHeader("Header of Window");
        window.openWindow();
        window.closeWindow();
    }

    private static void doButtonOperations(AbstractUIFactory abstractUiFactory) {
        Button button = abstractUiFactory.createButton();
        button.setLabel("Click me");
        button.click();
    }

    private static AbstractUIFactory createUIFactoryAccordingToOS() {
        if (System.getProperty("os.name").startsWith("Windows")) {
            return new WindowsUIFactory();
        } else {
            return new UbuntuUIFactory();
        }
    }
}

Kontrol Listesi

Genel Kabul Görmüş Kurallar

Repo

github

Kaynakça

Önemli Not 1: sourcemaking.com sitesinde About Us sayfasında “We also welcome translation.” ibaresi yer almaktadır. Bu yazının yazılmasında/çevrilmesinde herhangi bir ticari amaç bulunmamaktadır.

Önemli Not 2: Yazıda gördüğünüz hataları bana bildirirseniz sevinirim.

comments powered by Disqus