JavaRush /Blog Java /Random-MS /Corak Reka Bentuk: AbstractFactory

Corak Reka Bentuk: AbstractFactory

Diterbitkan dalam kumpulan
hello! Hari ini kita akan terus mengkaji corak reka bentuk dan bercakap tentang kilang abstrak . Corak Reka Bentuk: AbstractFactory - 1Apa yang akan kami lakukan semasa kuliah:
  • Mari kita bincangkan apa itu kilang abstrak dan apakah masalah yang diselesaikan oleh corak ini;
  • kami akan mencipta rangka kerja aplikasi merentas platform untuk memesan kopi dengan antara muka pengguna;
  • Mari kita kaji arahan untuk menggunakan corak ini dengan gambar rajah dan kod;
  • Sebagai bonus, terdapat telur Paskah yang tersembunyi di dalam kuliah, yang mana anda akan belajar untuk menentukan nama sistem pengendalian menggunakan Java dan, bergantung pada hasilnya, melakukan satu atau tindakan lain.
Untuk memahami corak ini sepenuhnya, anda perlu mempunyai pemahaman yang baik tentang topik berikut:
  • warisan di Jawa;
  • kelas dan kaedah abstrak dalam Java.

Apakah masalah yang diselesaikan oleh corak kilang abstrak?

Kilang abstrak, seperti semua corak kilang, membantu kami mengatur penciptaan objek baharu dengan betul. Dengan bantuannya, kami menguruskan "pelepasan" pelbagai keluarga objek yang saling berkaitan. Pelbagai keluarga objek yang saling berkaitan...Apakah itu? Jangan risau: dalam praktiknya semuanya lebih mudah daripada yang kelihatan. Mari kita mulakan dengan apa yang mungkin merupakan keluarga objek berkaitan? Katakan anda dan saya sedang membangunkan strategi, dan terdapat beberapa unit tempur di dalamnya:
  • infantri;
  • pasukan berkuda;
  • pemanah.
Jenis unit tempur ini berkaitan antara satu sama lain, kerana mereka berkhidmat dalam tentera yang sama. Kita boleh mengatakan bahawa kategori yang disenaraikan di atas ialah keluarga objek yang saling berkaitan. Itu sudah diselesaikan. Tetapi corak kilang abstrak digunakan untuk mengatur penciptaan pelbagai keluarga objek yang saling berkaitan. Tiada yang rumit di sini juga. Mari kita teruskan contoh dengan strategi. Mereka biasanya mempunyai beberapa pihak bertentangan yang berbeza. Unit tempur pihak yang berbeza mungkin berbeza dengan ketara dalam penampilan. Askar berjalan kaki, penunggang kuda dan pemanah tentera Rom tidak sama dengan askar berjalan kaki, penunggang kuda dan pemanah Viking. Dalam kerangka strategi, askar tentera yang berbeza adalah keluarga objek yang saling berkaitan. Ia akan menjadi lucu jika, dengan kesilapan pengaturcara, seorang askar berpakaian seragam Perancis dari zaman Napoleon, dengan senapang siap sedia, sedang berjalan-jalan di antara infantri Rom. Ia adalah untuk menyelesaikan masalah sedemikian bahawa corak reka bentuk kilang abstrak diperlukan. Tidak, bukan masalah perjalanan masa yang memalukan, tetapi penciptaan pelbagai kumpulan objek yang saling berkaitan. Kilang abstrak menyediakan antara muka untuk mencipta semua produk sedia ada (objek keluarga). Kilang abstrak biasanya mempunyai pelbagai pelaksanaan. Setiap daripada mereka bertanggungjawab untuk mencipta produk daripada salah satu variasi. Sebagai sebahagian daripada strategi, kami akan mempunyai kilang abstrak yang mencipta infantri abstrak, pemanah dan pasukan berkuda, serta pelaksanaan kilang ini. Sebuah kilang yang mencipta legionnair Rom dan, sebagai contoh, sebuah kilang yang mencipta pahlawan Carthaginian. Abstraksi adalah prinsip yang paling penting dalam corak ini. Pelanggan kilang bekerja dengannya dan dengan produk hanya melalui antara muka abstrak. Oleh itu, kita tidak perlu memikirkan jenis pahlawan yang sedang kita cipta, tetapi memindahkan tanggungjawab ini kepada beberapa pelaksanaan khusus kilang abstrak.

Kami terus mengautomasikan kedai kopi

Dalam kuliah yang lepas, kami mempelajari corak kaedah kilang, dengan bantuannya kami dapat mengembangkan perniagaan kopi dan membuka beberapa tempat jualan kopi baharu. Hari ini kami akan meneruskan kerja kami untuk memodenkan perniagaan kami. Menggunakan corak kilang abstrak, kami akan meletakkan asas untuk aplikasi desktop baharu untuk memesan kopi dalam talian. Apabila kita menulis aplikasi untuk desktop, kita harus sentiasa memikirkan tentang merentas platform. Aplikasi kami harus berfungsi pada kedua-dua macOS dan Windows (spoiler: Linux akan ditinggalkan untuk anda sebagai kerja rumah). Apakah rupa aplikasi kami? Agak mudah: ia akan menjadi borang yang terdiri daripada medan teks, medan pilihan dan butang. Jika anda mempunyai pengalaman menggunakan sistem pengendalian yang berbeza, anda pasti perasan bahawa pada Windows butang dipaparkan secara berbeza daripada pada Mac. Seperti segala-galanya... Jadi, mari kita mulakan. Dalam peranan keluarga produk, seperti yang anda mungkin sudah faham, kami akan mempunyai elemen antara muka grafik:
  • butang;
  • medan teks;
  • medan untuk pemilihan.
Penafian. Dalam setiap antara muka kita boleh menentukan kaedah seperti onClick, onValueChangedatau onInputChanged. Itu. kaedah yang membolehkan kami mengendalikan pelbagai acara (mengklik butang, memasukkan teks, memilih nilai dalam kotak pilihan). Semua ini sengaja ditinggalkan supaya tidak membebankan contoh dan menjadikannya lebih visual untuk mengkaji corak kilang. Mari kita tentukan antara muka abstrak untuk produk kami:
public interface Button {}
public interface Select {}
public interface TextField {}
Untuk setiap sistem pengendalian, kita mesti mencipta elemen antara muka dalam gaya sistem pengendalian tersebut. Kami menulis untuk Windows dan MacOS. Mari buat pelaksanaan untuk Windows:
public class WindowsButton implements Button {
}

public class WindowsSelect implements Select {
}

public class WindowsTextField implements TextField {
}
Kini sama untuk MacOS:
public class MacButton implements Button {
}

public class MacSelect implements Select {
}

public class MacTextField implements TextField {
}
Hebat. Sekarang kita boleh memulakan kilang abstrak kami, yang akan mencipta semua jenis produk abstrak sedia ada:
public interface GUIFactory {

    Button createButton();
    TextField createTextField();
    Select createSelect();

}
Sempurna. Seperti yang anda lihat, tiada yang rumit setakat ini. Kemudian semuanya sama mudah. Dengan analogi dengan produk, kami mencipta pelaksanaan berbeza bagi kilang kami untuk setiap OS. Mari mulakan dengan Windows:
public class WindowsGUIFactory implements GUIFactory {
    public WindowsGUIFactory() {
        System.out.println("Creating gui factory for Windows OS");
    }

    public Button createButton() {
        System.out.println("Creating Button for Windows OS");
        return new WindowsButton();
    }

    public TextField createTextField() {
        System.out.println("Creating TextField for Windows OS");
        return new WindowsTextField();
    }

    public Select createSelect() {
        System.out.println("Creating Select for Windows OS");
        return new WindowsSelect();
    }
}
Output konsol dalam kaedah dan pembina telah ditambahkan untuk menunjukkan lagi cara ia berfungsi. Sekarang untuk macOS:
public class MacGUIFactory implements GUIFactory {
    public MacGUIFactory() {
        System.out.println("Creating gui factory for macOS");
    }

    @Override
    public Button createButton() {
        System.out.println("Creating Button for macOS");
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        System.out.println("Creating TextField for macOS");
        return new MacTextField();
    }

    @Override
    public Select createSelect() {
        System.out.println("Creating Select for macOS");
        return new MacSelect();
    }
}
Nota: setiap kaedah, mengikut tandatangannya, mengembalikan jenis abstrak. Tetapi di dalam kaedah kami mencipta pelaksanaan konkrit produk. Ini adalah satu-satunya tempat di mana kita mengawal penciptaan kejadian tertentu. Kini tiba masanya untuk menulis kelas borang. Ini ialah kelas Java yang bidangnya adalah elemen antara muka:
public class OrderCoffeeForm {
    private final TextField customerNameTextField;
    private final Select coffeTypeSelect;
    private final Button orderButton;

    public OrderCoffeeForm(GUIFactory factory) {
        System.out.println("Creating order coffee form");
        customerNameTextField = factory.createTextField();
        coffeTypeSelect = factory.createSelect();
        orderButton = factory.createButton();
    }
}
Kilang abstrak diserahkan kepada pembina borang, yang mencipta elemen antara muka. Kami akan menyerahkan pelaksanaan kilang yang diperlukan kepada pembina supaya kami boleh mencipta elemen antara muka untuk OS tertentu.
public class Application {
    private OrderCoffeeForm orderCoffeeForm;

    public void drawOrderCoffeeForm() {
        // Определим Name операционной системы, получив meaning системной проперти через System.getProperty
        String osName = System.getProperty("os.name").toLowerCase();
        GUIFactory guiFactory;

        if (osName.startsWith("win")) { // Для windows
            guiFactory = new WindowsGUIFactory();
        } else if (osName.startsWith("mac")) { // Для mac
            guiFactory = new MacGUIFactory();
        } else {
            System.out.println("Unknown OS, can't draw form :( ");
            return;
        }
        orderCoffeeForm = new OrderCoffeeForm(guiFactory);
    }

    public static void main(String[] args) {
        Application application = new Application();
        application.drawOrderCoffeeForm();
    }
}
Jika kami menjalankan aplikasi pada Windows, kami akan mendapat output berikut:

Creating gui factory for Windows OS
Creating order coffee form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
Pada Mac outputnya adalah seperti berikut:

Creating gui factory for macOS
Creating order coffee form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
Di Linux:

Unknown OS, can't draw form :( 
Nah, anda dan saya membuat kesimpulan berikut. Kami menulis rangka kerja untuk aplikasi GUI yang mencipta elemen antara muka yang betul-betul sesuai untuk OS tertentu. Mari kita ulangi secara ringkas apa yang kita buat:
  • Keluarga produk: medan input, medan pilihan dan butang.
  • Pelbagai pelaksanaan keluarga produk ini, untuk Windows dan macOS.
  • Sebuah kilang abstrak, di mana kami menentukan antara muka untuk mencipta produk kami.
  • Dua pelaksanaan kilang kami, yang masing-masing bertanggungjawab untuk mencipta keluarga produk tertentu.
  • Borang, kelas Java yang bidangnya adalah elemen antara muka abstrak yang dimulakan dalam pembina dengan nilai yang diperlukan menggunakan kilang abstrak.
  • Kelas permohonan. Di dalamnya, kami mencipta borang yang dengannya kami menyerahkan pelaksanaan kilang kami yang diperlukan kepada pembina.
Jumlah: kami telah melaksanakan corak kilang abstrak.

Kilang Abstrak: arahan untuk digunakan

Kilang Abstrak ialah corak reka bentuk untuk menguruskan penciptaan keluarga produk yang berbeza tanpa terikat dengan kelas produk tertentu. Apabila menggunakan templat ini, anda mesti:
  1. Tentukan keluarga produk itu sendiri. Katakan kita mempunyai dua daripadanya:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. Untuk setiap produk dalam keluarga, tentukan kelas abstrak (antara muka). Dalam kes kami ialah:
    • ProductA
    • ProductB
  3. Dalam setiap keluarga produk, setiap produk mesti melaksanakan antara muka yang ditakrifkan dalam langkah 2.
  4. Cipta kilang abstrak, dengan kaedah cipta untuk setiap produk yang ditakrifkan dalam langkah 2. Dalam kes kami, kaedah ini ialah:
    • ProductA createProductA();
    • ProductB createProductB();
  5. Cipta pelaksanaan kilang abstrak supaya setiap pelaksanaan mengawal penciptaan produk keluarga yang sama. Untuk melakukan ini, di dalam setiap pelaksanaan kilang abstrak, adalah perlu untuk melaksanakan semua kaedah cipta, supaya pelaksanaan konkrit produk dicipta dan dikembalikan di dalamnya.
Di bawah ialah gambar rajah UML yang menggambarkan arahan yang diterangkan di atas: Corak Reka Bentuk: AbstractFactory - 3Sekarang mari tulis kod untuk arahan ini:
// Определим общие интерфейсы продуктов
public interface ProductA {}
public interface ProductB {}

// Создадим различные реализации (семейства) наших продуктов
public class SpecificProductA1 implements ProductA {}
public class SpecificProductB1 implements ProductB {}

public class SpecificProductA2 implements ProductA {}
public class SpecificProductB2 implements ProductB {}

// Создадим абстрактную фабрику
public interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory1 implements AbstractFactory {

    @Override
    public ProductA createProductA() {
        return new SpecificProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new SpecificProductB1();
    }
}

// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory2 implements AbstractFactory {

    @Override
    public ProductA createProductA() {
        return new SpecificProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new SpecificProductB2();
    }
}

Kerja rumah

Untuk menyatukan bahan anda boleh melakukan 2 perkara:
  1. Tingkatkan aplikasi pesanan kopi supaya ia berfungsi pada Linux.
  2. Cipta kilang abstrak anda sendiri untuk menghasilkan unit mana-mana strategi. Ini boleh menjadi sama ada strategi sejarah dengan tentera sebenar atau fantasi dengan orc, kerdil dan bunian. Perkara utama ialah anda mendapati ia menarik. Jadi kreatif, hantar pin pada konsol dan berseronok mempelajari corak!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION