Apa perbedaan antara pola desain Pabrik Abstrak dan Pabrik?

455

Saya tahu ada banyak posting di luar sana tentang perbedaan antara kedua pola ini, tetapi ada beberapa hal yang tidak dapat saya temukan.

Dari apa yang telah saya baca, saya melihat bahwa pola metode pabrik memungkinkan Anda untuk menentukan cara membuat produk beton tunggal tetapi menyembunyikan implementasi dari klien karena mereka akan melihat produk generik. Pertanyaan pertama saya adalah tentang pabrik abstrak. Apakah perannya memungkinkan Anda membuat keluarga objek beton (yang dapat bergantung pada pabrik spesifik apa yang Anda gunakan) daripada hanya satu objek konkret? Apakah pabrik abstrak hanya mengembalikan satu objek yang sangat besar atau banyak objek tergantung pada metode apa yang Anda panggil?

Dua pertanyaan terakhir saya adalah tentang satu kutipan yang tidak sepenuhnya saya mengerti yang saya lihat di banyak tempat:

Salah satu perbedaan antara keduanya adalah bahwa dengan pola Abstrak Pabrik, kelas mendelegasikan tanggung jawab instantiasi objek ke objek lain melalui komposisi sedangkan pola Metode Pabrik menggunakan pewarisan dan bergantung pada subkelas untuk menangani instantiasi objek yang diinginkan.

Pemahaman saya adalah bahwa pola metode pabrik memiliki antarmuka Pencipta yang akan membuat ConcreteCreator bertanggung jawab untuk mengetahui produk Beton mana yang harus dipakai. Apakah ini yang dimaksud dengan menggunakan warisan untuk menangani instantiasi objek?

Sekarang sehubungan dengan kutipan itu, bagaimana sebenarnya pola Pabrik Abstrak mendelegasikan tanggung jawab instantiasi objek ke objek lain melalui komposisi? Apa artinya ini? Sepertinya pola Pabrik Abstrak juga menggunakan warisan untuk melakukan proses konstruksi juga di mata saya, tetapi sekali lagi saya masih belajar tentang pola-pola ini.

Bantuan apa pun terutama dengan pertanyaan terakhir, akan sangat dihargai.

Silverbolt
sumber
Melihat "bagaimana instance dibuat" dari sudut pandang klien, akan membantu Anda memahami penawaran.
Karthik Bose
@nawfal, jawaban di utas itu mengerikan.
jaco0646

Jawaban:

494

Perbedaan Antara Dua

Perbedaan utama antara "metode pabrik" dan "pabrik abstrak" adalah bahwa metode pabrik adalah metode tunggal, dan pabrik abstrak adalah objek. Saya pikir banyak orang membuat kedua istilah ini bingung, dan mulai menggunakannya secara bergantian. Saya ingat bahwa saya mengalami kesulitan menemukan apa perbedaannya ketika saya mempelajarinya.

Karena metode pabrik hanyalah sebuah metode, metode ini dapat ditimpa dalam subkelas, karenanya bagian kedua dari kutipan Anda:

... Pola Metode Pabrik menggunakan warisan dan bergantung pada subclass untuk menangani instantiasi objek yang diinginkan.

Kutipan ini mengasumsikan bahwa suatu objek memanggil metode pabriknya sendiri di sini. Oleh karena itu satu-satunya hal yang dapat mengubah nilai pengembalian adalah subclass.

Pabrik abstrak adalah objek yang memiliki banyak metode pabrik. Melihat bagian pertama dari kutipan Anda:

... dengan pola Abstrak Pabrik, kelas mendelegasikan tanggung jawab instantiasi objek ke objek lain melalui komposisi ...

Apa yang mereka katakan adalah bahwa ada objek A, yang ingin membuat objek Foo. Alih-alih membuat objek Foo sendiri (misalnya, dengan metode pabrik), itu akan mendapatkan objek yang berbeda (pabrik abstrak) untuk membuat objek Foo.

Contoh Kode

Untuk menunjukkan perbedaannya, berikut adalah metode pabrik yang digunakan:

class A {
    public void doSomething() {
        Foo f = makeFoo();
        f.whatever();   
    }

    protected Foo makeFoo() {
        return new RegularFoo();
    }
}

class B extends A {
    protected Foo makeFoo() {
        //subclass is overriding the factory method 
        //to return something different
        return new SpecialFoo();
    }
}

Dan inilah pabrik abstrak yang digunakan:

class A {
    private Factory factory;

    public A(Factory factory) {
        this.factory = factory;
    }

    public void doSomething() {
        //The concrete class of "f" depends on the concrete class
        //of the factory passed into the constructor. If you provide a
        //different factory, you get a different Foo object.
        Foo f = factory.makeFoo();
        f.whatever();
    }
}

interface Factory {
    Foo makeFoo();
    Bar makeBar();
    Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}

//need to make concrete factories that implement the "Factory" interface here
Tom Dalling
sumber
15
Ini penjelasan yang luar biasa. Tetapi, bagian terpenting apa yang belum terjawab, dan itu adalah: kapan harus menggunakan yang satu, dan kapan pola yang lain?
croraf
11
Tidak yakin ini benar. Cukup yakin Metode Pabrik adalah pola desain yang dinamai metode pabrik, tetapi melibatkan struktur kelas dan warisan. Itu bukan metode tunggal.
Aviv Cohn
2
Jadi apakah benar mengatakan: Metode Pabrik dapat menjadi metode di semua kelas reguler dengan tujuan yang berbeda. Tetapi Pabrik Abstrak adalah kelas / objek yang digunakan oleh klien dan HANYA bertanggung jawab untuk menciptakan beberapa produk dalam keluarga?
Hieu Nguyen
Apakah Anda menggunakan kata "Super" di "SuperFoo" hanya untuk berarti kasus khusus Foo, atau apakah itu sebenarnya berarti kelas super? Seperti yang saya duga pasti subclass.
dahui
@ Dahui Ya itu subkelas. Saya sudah mengubahnya SpecialFooagar lebih jelas.
Tom Dalling
125

Abstrak pabrik menciptakan kelas dasar dengan metode abstrak yang mendefinisikan metode untuk objek yang harus dibuat. Setiap kelas pabrik yang mendapatkan kelas dasar dapat membuat implementasi mereka sendiri dari setiap jenis objek.

masukkan deskripsi gambar di sini

Metode pabrik hanyalah metode sederhana yang digunakan untuk membuat objek di kelas. Ini biasanya ditambahkan dalam root agregat ( OrderKelas memiliki metode yang disebut CreateOrderLine)

masukkan deskripsi gambar di sini

Pabrik abstrak

Dalam contoh di bawah ini kami merancang antarmuka sehingga kami dapat memisahkan pembuatan antrian dari sistem pesan dan karenanya dapat membuat implementasi untuk sistem antrian yang berbeda tanpa harus mengubah basis kode.

interface IMessageQueueFactory
{
  IMessageQueue CreateOutboundQueue(string name);
  IMessageQueue CreateReplyQueue(string name);
}

public class AzureServiceBusQueueFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new AzureMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new AzureResponseMessageQueue(/*....*/);
      }

}

public class MsmqFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new MsmqMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new MsmqResponseMessageQueue(/*....*/);
      }
}

Metode pabrik

Masalahnya di server HTTP adalah kami selalu membutuhkan respons untuk setiap permintaan.

public interface IHttpRequest
{
    // .. all other methods ..

    IHttpResponse CreateResponse(int httpStatusCode);
}

Tanpa metode pabrik, pengguna server HTTP (yaitu pemrogram) akan dipaksa untuk menggunakan kelas implementasi khusus yang mengalahkan tujuan IHttpRequestantarmuka.

Oleh karena itu kami memperkenalkan metode pabrik sehingga penciptaan kelas respons juga disarikan.

Ringkasan

Perbedaannya adalah bahwa tujuan dari kelas yang berisi metode pabrik bukan untuk membuat objek , sedangkan pabrik abstrak hanya boleh digunakan untuk membuat objek.

Orang harus berhati-hati ketika menggunakan metode pabrik karena mudah untuk mematahkan LSP ( prinsip Substitusi Liskov ) saat membuat objek.

jgauffin
sumber
3
Mengapa kita membutuhkan produk beton?
Andrew S
60
Karena tidak ada yang mau berinvestasi dalam ide.
jgauffin
4
Pabrik Abstrak harus menciptakan lebih dari sekadar Button()untuk membuat "keluarga produk terkait." Misalnya, contoh GoF kanonik membuat ScrollBar()dan Window(). Keuntungannya adalah bahwa Pabrik Abstrak dapat menegakkan tema umum di berbagai produknya.
jaco0646
Jaco benar. Pertimbangkan bahwa kedua diagram UML pada dasarnya sama (di samping UML Pabrik Abstrak salah). Dalam kedua kasus klien memanggil metode pabrik untuk membuat satu produk tunggal.
cobby
1
@AndrewS: Untuk menjawab pertanyaan Anda. Jika kita tidak perlu memiliki produk beton yang berbeda (kelas) untuk abstraksi yang sama (antarmuka) kita mungkin membutuhkan pola pembangun dan bukan pola pabrik. (lebih baik terlambat daripada tidak sama sekali;))
jgauffin
95

Perbedaan antara AbstractFactory dan pola desain pabrik adalah sebagai berikut:

  • Metode Pabrik digunakan untuk membuat satu produk saja tetapi Pabrik Abstrak adalah tentang menciptakan keluarga produk terkait atau tergantung.
  • Pola Metode Pabrik memperlihatkan metode kepada klien untuk membuat objek sedangkan dalam kasus Pabrik Abstrak mereka memperlihatkan keluarga objek terkait yang mungkin terdiri dari metode Pabrik ini.
  • Pola Metode Pabrik menyembunyikan konstruksi objek tunggal sedangkan Pabrik Abstrak menyembunyikan konstruksi sekelompok objek terkait. Pabrik abstrak biasanya diimplementasikan menggunakan (satu set) metode pabrik.
  • Abstrak Pola pabrik menggunakan komposisi untuk mendelegasikan tanggung jawab membuat objek ke kelas lain saat Metode Pabrik pola desain menggunakan warisan dan bergantung pada kelas turunan atau subkelas untuk membuat objek.
  • Gagasan di balik pola Metode Pabrik adalah memungkinkan untuk kasus di mana klien tidak tahu apa kelas konkret yang diperlukan untuk membuat pada saat runtime, tetapi hanya ingin mendapatkan kelas yang akan melakukan pekerjaan sementara pola Pabrik Abstrak adalah paling baik digunakan ketika sistem Anda harus membuat banyak keluarga produk atau Anda ingin menyediakan perpustakaan produk tanpa memaparkan rincian implementasi.!

Implementasi Pola Metode Pabrik: Metode Pabrik UML

Implementasi Pola Pabrik Abstrak:

Abstrak Pabrik UML

Vibha Sanskrityayan
sumber
13
Mmm, tidak yakin tentang Contoh Pabrik Abstrak. Saya pikir pabrik bentuk dan pabrik warna harus menerapkan metode yang sama. Tapi kalau saya benar maka sampelnya tidak masuk akal.
Joaquin Iurchuk
4
Poin-poinnya benar; Namun, kedua diagram tersebut sepenuhnya salah dan sangat menyesatkan. Lihat diagram di bawah ini dari @Trying untuk model Pabrik Abstrak yang akurat.
jaco0646
1
Saya harus setuju bahwa 2 diagram memang sangat menyesatkan. Saya telah melihatnya di situs tutorialspoint dan sejujurnya saya tidak 100% setuju dengan mereka. Deskripsi terlihat bagus
SoftwareDeveloper
Ini sangat menyesatkan.
diyoda_
50+ upvotes dan diagramnya sangat salah. Bukti Anda tidak bisa mempercayai banyak jawaban pola desain di SO.
Fuhrmanator
27

Perbedaan utama antara Pabrik Abstrak dan Metode Pabrik adalah bahwa Pabrik Abstrak dilaksanakan oleh Komposisi ; tetapi Metode Pabrik diimplementasikan oleh Warisan .

Ya, Anda membacanya dengan benar: perbedaan utama antara kedua pola ini adalah komposisi lama vs warisan perdebatan .

Diagram UML dapat ditemukan di buku (GoF). Saya ingin memberikan contoh kode, karena saya pikir menggabungkan contoh dari dua jawaban teratas di utas ini akan memberikan demonstrasi yang lebih baik daripada salah satu jawaban saja. Selain itu, saya telah menggunakan terminologi dari buku di kelas dan nama metode.

Pabrik Abstrak

  1. Poin paling penting untuk dipahami di sini adalah bahwa pabrik abstrak disuntikkan ke klien. Inilah mengapa kami mengatakan bahwa Pabrik Abstrak diimplementasikan oleh Komposisi. Seringkali, kerangka kerja injeksi ketergantungan akan melakukan tugas itu; tetapi kerangka kerja tidak diperlukan untuk DI.
  2. Poin kritis kedua adalah bahwa pabrik beton di sini tidak implementasi Metode Pabrik! Kode contoh untuk Metode Pabrik ditunjukkan lebih lanjut di bawah ini.
  3. Dan akhirnya, poin ketiga yang perlu diperhatikan adalah hubungan antara produk: dalam hal ini antrian outbound dan reply. Satu pabrik beton menghasilkan antrian Azure, yang lainnya MSMQ. GoF menyebut hubungan produk ini sebagai "keluarga" dan penting untuk diketahui bahwa keluarga dalam hal ini tidak berarti hierarki kelas.
public class Client {
    private final AbstractFactory_MessageQueue factory;

    public Client(AbstractFactory_MessageQueue factory) {
        // The factory creates message queues either for Azure or MSMQ.
        // The client does not know which technology is used.
        this.factory = factory;
    }

    public void sendMessage() {
        //The client doesn't know whether the OutboundQueue is Azure or MSMQ.
        OutboundQueue out = factory.createProductA();
        out.sendMessage("Hello Abstract Factory!");
    }

    public String receiveMessage() {
        //The client doesn't know whether the ReplyQueue is Azure or MSMQ.
        ReplyQueue in = factory.createProductB();
        return in.receiveMessage();
    }
}

public interface AbstractFactory_MessageQueue {
    OutboundQueue createProductA();
    ReplyQueue createProductB();
}

public class ConcreteFactory_Azure implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new AzureMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new AzureResponseMessageQueue();
    }
}

public class ConcreteFactory_Msmq implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new MsmqMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new MsmqResponseMessageQueue();
    }
}

Metode Pabrik

  1. Poin penting yang paling untuk memahami di sini adalah bahwa ConcreteCreator adalah klien. Dengan kata lain, klien adalah subclass yang orang tuanya mendefinisikan factoryMethod(). Inilah mengapa kami mengatakan bahwa Metode Pabrik diimplementasikan oleh Inheritance.
  2. Poin kritis kedua adalah untuk mengingat bahwa Pola Metode Pabrik tidak lebih dari spesialisasi Pola Metode Templat. Kedua pola ini memiliki struktur yang sama. Mereka hanya berbeda tujuannya. Metode Pabrik bersifat kreatif (membangun sesuatu) sedangkan Metode Templat adalah perilaku (menghitung sesuatu).
  3. Dan akhirnya, poin ketiga yang perlu diperhatikan adalah bahwa kelas Creator(induk) memanggil kelasnya sendiri factoryMethod(). Jika kita menghapus anOperation()dari kelas induk, hanya menyisakan satu metode, itu bukan lagi pola Metode Pabrik. Dengan kata lain, Metode Pabrik tidak dapat diimplementasikan dengan kurang dari dua metode di kelas induk; dan yang satu harus memohon yang lain.
public abstract class Creator {
    public void anOperation() {
        Product p = factoryMethod();
        p.whatever();
    }

    protected abstract Product factoryMethod();
}

public class ConcreteCreator extends Creator {
    @Override
    protected Product factoryMethod() {
        return new ConcreteProduct();
    }
}

Lain-lain & Berbagai Pola Pabrik

Ketahuilah bahwa meskipun GoF mendefinisikan dua pola Pabrik yang berbeda, ini bukan satu-satunya pola Pabrik yang ada. Mereka bahkan belum tentu pola Pabrik yang paling umum digunakan. Contoh ketiga yang terkenal adalah Pola Pabrik Statis Josh Bloch dari Java Efektif. Buku Head First Design Patterns menyertakan pola lain yang mereka sebut Simple Factory.

Jangan terjebak dalam anggapan setiap pola Pabrik harus cocok dengan satu dari GoF.

jaco0646
sumber
3
Jawaban yang bagus dan sangat jelas berdasarkan contoh yang baik, yang terbaik dalam topik ini IMO.
Luke Duda
Penjelasan yang bagus. +1 untuk metode Pabrik harus menggunakan titik metode pabrik abstraknya. Dengan poin ini menjadi jauh lebih jelas, tanpa memahami poin ini: jika kita memiliki metode pabrik yang tidak dipanggil sendiri itu akan digunakan oleh beberapa kelas lain yang akan menyusunnya dan sub kelasnya akan disuntikkan, itu berubah menjadi pabrik abstrak , perbedaan menjadi kurang jelas jika titik bahwa metode pabrik abstrak harus dipanggil oleh pabrik itu sendiri seperti pola metode template tidak dipahami
nits.kk
Satu lagi pertanyaan-komentar. Haruskah factoryMethod()selalu menjadi protected metode dalam pola "Metode Pabrik"? (Saya pikir ya)
Yaroslav Fedoruk
1
@YaroslavFedoruk, buku GoF memungkinkan publicmetode pabrik, dan metode itu bahkan tidak perlu abstract; tetapi titik kritisnya adalah bahwa metode ini dimaksudkan untuk warisan, sehingga tidak dapat (misalnya) menjadi salah satu staticatau final. Saya telah membuat metode protecteddan di abstractsini untuk menyoroti ekstensibilitas (wajib).
jaco0646
@ nits.kk, Anda mungkin tertarik dengan jawaban yang terkait .
jaco0646
26

Abstrak Factory adalah antarmuka untuk membuat produk terkait, tetapi Metode Pabrik hanya satu metode. Abstrak Pabrik dapat diimplementasikan dengan beberapa Metode Pabrik.

Abstrak Pabrik UML

Mencoba
sumber
10
Anda sudah memposting jawaban yang sama di sini . Jika Anda merasa bahwa pertanyaan ini mirip, tandai sebagai duplikat.
Ja͢ck
11

Pertimbangkan contoh ini untuk memudahkan pemahaman.

Apa yang disediakan perusahaan telekomunikasi? Broadband, saluran telepon, dan seluler misalnya dan Anda diminta membuat aplikasi untuk menawarkan produk mereka kepada pelanggan mereka.

Secara umum apa yang akan Anda lakukan di sini adalah, menciptakan produk yaitu broadband, saluran telepon dan seluler melalui Metode Pabrik Anda mana Anda tahu properti apa yang Anda miliki untuk produk-produk itu dan itu cukup mudah.

Sekarang, perusahaan ingin menawarkan kepada pelanggan mereka satu bundel produk mereka yaitu broadband, saluran telepon, dan seluler, dan inilah Pabrik Abstrak untuk dimainkan.

Abstrak Pabrik adalah, dengan kata lain, adalah komposisi dari pabrik lain yang bertanggung jawab untuk menciptakan produk mereka sendiri dan Pabrik Abstrak tahu bagaimana menempatkan produk-produk ini dengan lebih bermakna sehubungan dengan tanggung jawabnya sendiri.

Dalam hal ini, itu BundleFactoryadalah Pabrik Abstrak BroadbandFactory,, PhonelineFactorydan MobileFactoryadalah Factory. Untuk lebih menyederhanakan, Pabrik-pabrik ini akan memiliki Metode Pabrik untuk menginisialisasi produk individu.

Lihat contoh kode di bawah ini:

public class BroadbandFactory : IFactory {
    public static Broadband CreateStandardInstance() {
        // broadband product creation logic goes here
    }
}

public class PhonelineFactory : IFactory {
    public static Phoneline CreateStandardInstance() {
        // phoneline product creation logic goes here
    }
}

public class MobileFactory : IFactory {
    public static Mobile CreateStandardInstance() {
        // mobile product creation logic goes here
    }
}

public class BundleFactory : IAbstractFactory {

    public static Bundle CreateBundle() {
        broadband = BroadbandFactory.CreateStandardInstance();
        phoneline = PhonelineFactory.CreateStandardInstance();
        mobile = MobileFactory.CreateStandardInstance();

        applySomeDiscountOrWhatever(broadband, phoneline, mobile);
    }

    private static void applySomeDiscountOrWhatever(Broadband bb, Phoneline pl, Mobile m) {
        // some logic here
        // maybe manange some variables and invoke some other methods/services/etc.
    }
}

Semoga ini membantu.

Abdul Munim
sumber
1
Tidak ada staticmetode dalam pola pabrik GoF. Ini salah.
jaco0646
5

Contoh Kehidupan Nyata. (Mudah diingat)

Pabrik

Bayangkan Anda membangun rumah dan mendekati tukang kayu untuk mendapatkan pintu. Anda memberikan ukuran untuk pintu dan kebutuhan Anda, dan dia akan membangun pintu untuk Anda. Dalam hal ini, tukang kayu adalah pabrik pintu. Spesifikasi Anda adalah input untuk pabrik, dan pintu adalah output atau produk dari pabrik.

Pabrik Abstrak

Sekarang, perhatikan contoh pintu yang sama. Anda bisa pergi ke tukang kayu, atau pergi ke toko pintu plastik atau toko PVC. Semuanya adalah pabrik pintu. Berdasarkan situasinya, Anda memutuskan pabrik apa yang perlu Anda dekati. Ini seperti Pabrik Abstrak.

Saya telah menjelaskan di sini baik pola metode Pabrik dan pola pabrik abstrak dimulai dengan tidak menggunakannya menjelaskan masalah dan kemudian menyelesaikan masalah dengan menggunakan pola di atas https://github.com/vikramnagineni/Design-Patterns/tree/master

Vikram Babu Nagineni
sumber
3

Mari kita jelaskan bahwa sebagian besar waktu dalam kode produksi, kita menggunakan pola pabrik abstrak karena kelas A diprogram dengan antarmuka B. Dan A perlu membuat instance B. Jadi A harus memiliki objek pabrik untuk menghasilkan instance B Jadi A tidak bergantung pada contoh konkret apa pun dari B. Semoga ini bisa membantu.

Adrian Liu
sumber
3

Memahami perbedaan dalam motivasi:

Misalkan Anda sedang membangun alat di mana Anda memiliki objek dan implementasi konkret dari keterkaitan objek. Karena Anda memperkirakan variasi dalam objek, Anda telah membuat tipuan dengan menetapkan tanggung jawab untuk membuat varian objek ke objek lain ( kami menyebutnya pabrik abstrak ). Abstraksi ini menemukan manfaat yang kuat karena Anda memperkirakan ekstensi di masa depan membutuhkan varian dari objek-objek tersebut.

Motivasi lain yang agak menarik dalam garis pemikiran ini adalah kasus di mana setiap-atau-tidak ada objek dari seluruh kelompok akan memiliki varian yang sesuai. Berdasarkan beberapa kondisi, salah satu varian akan digunakan dan dalam setiap kasus semua objek harus memiliki varian yang sama. Ini mungkin agak kontra intuitif untuk dipahami karena kita sering cenderung berpikir bahwa - selama varian objek mengikuti kontrak seragam yang sama ( antarmuka dalam arti yang lebih luas ), kode implementasi konkret tidak boleh rusak. Fakta menarik di sini adalah bahwa, tidak selalu ini benar terutama ketika perilaku yang diharapkan tidak dapat dimodelkan oleh kontrak pemrograman.

Sederhana ( meminjam ide dari GoF ) adalah setiap aplikasi GUI mengatakan monitor virtual yang meniru tampilan MS atau Mac atau Fedora OS. Di sini, misalnya, ketika semua objek widget seperti jendela, tombol, dll. Memiliki varian MS kecuali bilah gulir yang berasal dari varian MAC, tujuan alat gagal parah.

Kasus-kasus di atas membentuk kebutuhan mendasar Pola Pabrik Abstrak .

Di sisi lain, bayangkan Anda sedang menulis kerangka kerja sehingga banyak orang dapat membangun berbagai alat ( seperti yang ada di contoh di atas ) menggunakan kerangka kerja Anda. Dengan gagasan kerangka kerja, Anda tidak perlu, meskipun Anda tidak bisa menggunakan objek konkret dalam logika Anda. Anda lebih suka menaruh beberapa kontrak tingkat tinggi antara berbagai objek dan bagaimana mereka berinteraksi. Meskipun Anda ( sebagai pengembang kerangka kerja ) tetap pada tingkat yang sangat abstrak, setiap pembangun alat dipaksa untuk mengikuti konstruksi kerangka Anda. Namun, mereka ( pembangun alat ) memiliki kebebasan untuk memutuskan objek apa yang akan dibangun dan bagaimana semua objek yang mereka buat akan berinteraksi. Berbeda dengan kasus sebelumnya ( Pola Pabrik Abstrak ), Anda ( sebagai pembuat kerangka) tidak perlu bekerja dengan benda konkret dalam kasus ini; dan lebih tepatnya bisa tetap di level kontrak objek. Selain itu, tidak seperti bagian kedua dari motivasi sebelumnya, Anda atau pembuat alat tidak pernah memiliki situasi pencampuran objek dari varian. Di sini, sementara kode kerangka kerja tetap pada tingkat kontrak, setiap pembangun-alat dibatasi ( oleh sifat kasus itu sendiri ) untuk menggunakan objek mereka sendiri. Kreasi objek dalam hal ini didelegasikan kepada masing-masing pelaksana dan penyedia kerangka kerja hanya menyediakan metode yang seragam untuk membuat dan mengembalikan objek. Metode tersebut tidak dapat dihindari bagi pengembang kerangka untuk melanjutkan dengan kode mereka dan memiliki nama khusus yang disebut metode Pabrik ( Pola Metode Pabrik untuk pola yang mendasarinya ).

Beberapa Catatan:

  • Jika Anda terbiasa dengan 'metode templat', maka Anda akan melihat bahwa metode pabrik sering dipanggil dari metode templat jika program terkait dengan segala bentuk kerangka kerja. Sebaliknya, metode templat dari program aplikasi sering kali merupakan implementasi sederhana dari algoritma tertentu dan tidak memiliki metode pabrik.
  • Selanjutnya, untuk kelengkapan pemikiran, menggunakan kerangka kerja ( disebutkan di atas ), ketika seorang pembuat alat sedang membangun alat, di dalam setiap metode pabrik, alih-alih membuat objek konkret, ia dapat mendelegasikan tanggung jawab lebih lanjut ke abstrak objek -pabrik, asalkan pembuat-alat memperkirakan variasi objek konkret untuk ekstensi di masa mendatang.

Kode sampel:

//Part of framework-code
BoardGame {
    Board createBoard() //factory method. Default implementation can be provided as well
    Piece createPiece() //factory method

    startGame(){        //template method
         Board borad = createBoard()
         Piece piece = createPiece()
         initState(board, piece)
    }
}


//Part of Tool-builder code
Ludo inherits  BoardGame {
     Board createBoard(){ //overriding of factory method
         //Option A: return new LudoBoard() //Lodu knows object creation
         //Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory
     }
….
}

//Part of Tool-builder code
Chess inherits  BoardGame {
    Board createBoard(){ //overriding of factory method
        //return a Chess board
    }
    ….
}
KGhatak
sumber
3
  1. Pertanyaan pertama saya adalah tentang pabrik abstrak. Apakah perannya memungkinkan Anda membuat keluarga objek beton (yang dapat bergantung pada pabrik spesifik apa yang Anda gunakan) daripada hanya satu objek konkret?

Iya. Maksud dari Pabrik Abstrak adalah:

Menyediakan antarmuka untuk membuat keluarga objek terkait atau bergantung tanpa menentukan kelas konkret mereka.


  1. Apakah pabrik abstrak hanya mengembalikan satu objek yang sangat besar atau banyak objek tergantung pada metode apa yang Anda panggil?

Idealnya itu harus mengembalikan satu objek per metode yang diminta klien.

  1. Pemahaman saya adalah bahwa pola metode pabrik memiliki antarmuka Pencipta yang akan membuat ConcreteCreator bertanggung jawab untuk mengetahui produk Beton mana yang harus dipakai. Apakah ini yang dimaksud dengan menggunakan warisan untuk menangani instantiasi objek?

Iya. Metode pabrik menggunakan warisan.

  1. Abstrak Pola pabrik mendelegasikan tanggung jawab instantiasi objek ke objek lain melalui komposisi? Apa artinya ini?

AbstractFactory mendefinisikan FactoryMethod dan ConcreteFactory bertanggung jawab untuk membangun Produk Beton. Cukup ikuti contoh kode dalam artikel ini .

Anda dapat menemukan lebih banyak detail di posting SE terkait:

Apa perbedaan mendasar antara Pabrik dan Pola Pabrik Abstrak?

Pola Desain: Metode Pabrik vs Pabrik vs Pabrik Abstrak

Ravindra babu
sumber
3

Metode Pabrik bergantung pada warisan: Pembuatan objek didelegasikan ke subclass, yang menerapkan metode pabrik untuk membuat objek.

Abstrak Pabrik bergantung pada komposisi objek: pembuatan objek diimplementasikan dalam metode yang diekspos di antarmuka pabrik.

Diagram tingkat tinggi dari pabrik dan pola pabrik abstrak,

diagram

Untuk informasi lebih lanjut tentang metode Pabrik, lihat artikel ini .

Untuk informasi lebih lanjut tentang metode pabrik abstrak, lihat artikel ini .

pengguna2266614
sumber
2

Untuk membuatnya sangat sederhana dengan antarmuka minimum & tolong fokuskan "// 1":

class FactoryProgram
    {
        static void Main()
        {
            object myType = Program.MyFactory("byte");
            Console.WriteLine(myType.GetType().Name);

            myType = Program.MyFactory("float"); //3
            Console.WriteLine(myType.GetType().Name);

            Console.ReadKey();
        }

        static object MyFactory(string typeName)
        {
            object desiredType = null; //1
            switch (typeName)
            {
                case "byte": desiredType = new System.Byte(); break; //2
                case "long": desiredType = new System.Int64(); break;
                case "float": desiredType = new System.Single(); break;
                default: throw new System.NotImplementedException();
            }
            return desiredType;
        }
    }

Poin-poin penting di sini: 1. Mekanisme Factory & AbstractFactory harus menggunakan warisan (System.Object-> byte, float ...); jadi jika Anda memiliki warisan dalam program maka Pabrik (Pabrik Abstrak tidak akan ada kemungkinan besar) sudah ada dengan desain 2. Pencipta (MyFactory) tahu tentang jenis beton sehingga mengembalikan objek jenis beton ke pemanggil (Utama); Secara abstrak, jenis pengembalian pabrik adalah Interface.

interface IVehicle { string VehicleName { get; set; } }
interface IVehicleFactory
    {
        IVehicle CreateSingleVehicle(string vehicleType);
    }
class HondaFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports": return new SportsBike();
                case "Regular":return new RegularBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }
class HeroFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports":  return new SportsBike();
                case "Scooty": return new Scooty();
                case "DarkHorse":return new DarkHorseBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }

class RegularBike : IVehicle { public string VehicleName { get { return "Regular Bike- Name"; } set { VehicleName = value; } } }
class SportsBike : IVehicle { public string VehicleName { get { return "Sports Bike- Name"; } set { VehicleName = value; } } }
class RegularScooter : IVehicle { public string VehicleName { get { return "Regular Scooter- Name"; } set { VehicleName = value; } } }
class Scooty : IVehicle { public string VehicleName { get { return "Scooty- Name"; } set { VehicleName = value; } } }
class DarkHorseBike : IVehicle { public string VehicleName { get { return "DarkHorse Bike- Name"; } set { VehicleName = value; } } }

class Program
{
    static void Main(string[] args)
    {
        IVehicleFactory honda = new HondaFactory(); //1
        RegularBike hondaRegularBike = (RegularBike)honda.CreateSingleVehicle("Regular"); //2
        SportsBike hondaSportsBike = (SportsBike)honda.CreateSingleVehicle("Sports");
        Console.WriteLine("******* Honda **********"+hondaRegularBike.VehicleName+ hondaSportsBike.VehicleName);

        IVehicleFactory hero = new HeroFactory();
        DarkHorseBike heroDarkHorseBike = (DarkHorseBike)hero.CreateSingleVehicle("DarkHorse");
        SportsBike heroSportsBike = (SportsBike)hero.CreateSingleVehicle("Sports");
        Scooty heroScooty = (Scooty)hero.CreateSingleVehicle("Scooty");
        Console.WriteLine("******* Hero **********"+heroDarkHorseBike.VehicleName + heroScooty.VehicleName+ heroSportsBike.VehicleName);

        Console.ReadKey();
    }
}

Poin penting: 1. Persyaratan: Honda akan membuat "Regular", "Sports" tetapi Hero akan membuat "DarkHorse", "Sports" dan "Scooty". 2. mengapa dua antarmuka? Satu untuk tipe pabrikan (IVehicleFactory) dan satu lagi untuk pabrik produk (IVehicle); Cara lain untuk memahami 2 antarmuka adalah pabrik abstrak adalah semua tentang membuat objek terkait 2. Tangkapannya adalah anak-anak IVehicleFactory kembali dan IVehicle (bukan beton di pabrik); jadi saya mendapatkan variabel parent (IVehicle); kemudian saya membuat tipe konkret yang sebenarnya dengan memanggil CreateSingleVehicle dan kemudian casting objek induk ke objek anak yang sebenarnya. Apa yang akan terjadi jika saya melakukannya RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");; Anda akan mendapatkan ApplicationException dan itu sebabnya kami membutuhkan pabrik abstrak generik yang akan saya jelaskan jika diperlukan.

Saurabh
sumber
1

Abstrak Pabrik : Pabrik pabrik; sebuah pabrik yang mengelompokkan pabrik-pabrik individu tetapi terkait / bergantung bersama-sama tanpa menentukan kelas konkret mereka. Contoh Pabrik Abstrak

Factory : Ini menyediakan cara untuk mendelegasikan logika instantiation ke kelas anak. Contoh Pola Pabrik

Atul Jain
sumber
0

Saya lebih suka Pabrik Abstrak daripada Metode Pabrik kapan saja. Dari contoh Tom Dalling (penjelasan hebat btw) di atas, kita dapat melihat bahwa Pabrik Abstrak lebih dapat dikomposisikan dalam semua yang perlu kita lakukan adalah menyerahkan Pabrik yang berbeda ke konstruktor (injeksi ketergantungan konstruktor digunakan di sini). Tetapi Metode Pabrik mengharuskan kami untuk memperkenalkan kelas baru (lebih banyak hal untuk dikelola) dan menggunakan subclass. Selalu lebih suka komposisi daripada warisan.

he9lin
sumber
0

izinkan saya untuk menjelaskannya dengan tepat. sebagian besar jawaban sudah dijelaskan, memberikan diagram dan contoh juga. jadi jawaban saya hanya satu baris. kata-kata saya sendiri: - “pola abstrak pabrik menambahkan pada lapisan abstrak atas beberapa implementasi metode pabrik. berarti pabrik abstrak mengandung atau menggabungkan satu atau lebih dari satu pola metode pabrik ”

Raja
sumber
Ini tidak benar. Ini adalah kesalahpahaman yang terlalu umum bahwa Pabrik Abstrak tidak lebih dari sebuah pabrik pabrik.
jaco0646
0

Banyak jawaban di atas tidak memberikan perbandingan kode antara pola Abstrak Pabrik dan Metode Pabrik. Berikut ini adalah upaya saya untuk menjelaskannya melalui Java. Semoga ini bisa membantu seseorang yang membutuhkan penjelasan sederhana.

Seperti yang dikatakan GoF dengan tepat: Pabrik Abstrak menyediakan antarmuka untuk membuat keluarga objek terkait atau bergantung tanpa menentukan kelas konkretnya.

        public class Client {
            public static void main(String[] args) {
               ZooFactory zooFactory = new HerbivoreZooFactory();       
               Animal animal1 = zooFactory.animal1();
               Animal animal2 = zooFactory.animal2();
               animal1.sound();
               animal2.sound();

               System.out.println();

               AnimalFactory animalFactory = new CowAnimalFactory();
               Animal animal = animalFactory.createAnimal();
               animal.sound();
            }
        }

        public interface Animal {
            public void sound();
        }

        public class Cow implements Animal {

            @Override
            public void sound() {
                System.out.println("Cow moos");
            }

        }

        public class Deer implements Animal {

            @Override
            public void sound() {
                System.out.println("Deer grunts");
            }

        }

        public class Hyena implements Animal {

            @Override
            public void sound() {
                System.out.println("Hyena.java");
            }

        }

        public class Lion implements Animal {

            @Override
            public void sound() {
                System.out.println("Lion roars");
            }

        }

        public interface ZooFactory {
            Animal animal1();

            Animal animal2();
        }

        public class CarnivoreZooFactory implements ZooFactory {

            @Override
            public Animal animal1() {
                return new Lion();
            }

            @Override
            public Animal animal2() {
                return new Hyena();
            }

        }

        public class HerbivoreZooFactory implements ZooFactory{

            @Override
            public Animal animal1() {
                return new Cow();
            }

            @Override
            public Animal animal2() {
                return new Deer();
            }

        }

        public interface AnimalFactory {
            public Animal createAnimal();
        }

        public class CowAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Cow();
            }

        }

        public class DeerAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Deer();
            }

        }

        public class HyenaAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Hyena();
            }

        }

        public class LionAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Lion();
            }

        }
Jatin Shashoo
sumber
Ini tidak benar. Kode ini mengimplementasikan kesalahpahaman yang terlalu umum bahwa Pabrik Abstrak tidak lebih dari sebuah pabrik pabrik.
jaco0646
1
@ jaco0646 Saya percaya bahwa dalam pola metode pabrik, fokusnya adalah mendapatkan hanya satu produk konkret dari FactoryImpl. Sedangkan dalam pola pabrik abstrak, FactoryImpls bertanggung jawab untuk menyediakan beberapa Produk Beton yang serupa / terkait, yang antarmuka Pabriknya menyediakan kontrak. Jadi ZooFactory sama sekali bukan pabrik pabrik, seperti yang Anda katakan, tetapi hanya sebuah antarmuka yang Impls menyediakan Produk Beton yang terkait satu sama lain. Jangan ragu untuk mengoreksi pemahaman saya jika Anda tidak setuju.
Jatin Shashoo
Dalam Metode Pabrik, fokusnya adalah pada pewarisan melalui sub-klasifikasi, karena Metode Pabrik adalah spesialisasi pola Metode Templat. Jawaban terpilih di atas menunjukkan contoh kode yang layak.
jaco0646
@ jaco0646 1. Apakah ini berarti bahwa dalam contoh di atas, alih-alih menggunakan antarmuka untuk AnimalFactory dan menyediakan implementasinya, saya seharusnya menggunakan kelas dan menimpa metode createAnimal () dalam subkelasnya: CowAnimalFactory, LionAnimalFactory, dll. ?? 2. Juga, apa pendapat Anda tentang contoh yang ditunjukkan untuk ZooFactory ??
Jatin Shashoo
Untuk pertanyaan pertama: ya. Yang kedua, saya telah menambahkan jawaban saya sendiri di utas ini daripada terus mengkritik setiap jawaban individu.
jaco0646