Mengapa pola desain metode pabrik lebih berguna daripada memiliki kelas dan memanggil mereka secara individual?

32

Dari pola desain "Gang Empat", ada metode Pabrik:

class Factory(product)
  case product
  when a
    new A
  when b
    new B
  when c
    new C
end

new Factory(a)

Mengapa ini lebih berguna daripada memiliki tiga kelas, a, b, dan cdan memanggil mereka secara individu?

alt
sumber
1
Apa maksud Anda tepatnya? Mengapa tidak instantiate ketiganya? Apakah itu yang Anda maksud?
Neil
1
@Neil No, dalam pola pabrik semua kelas ada sebagai saudara kandung. Mengapa menelepon pabrik untuk secara tidak langsung mengakses kelas a, b, c?
alt
3
ini tidak benar-benar terlihat seperti pola metode pabrik untuk saya, jika ada yang lebih dekat ke pabrik abstrak
jk.
2
Karena pada waktu desain Anda tidak tahu yang mana dari 3 kelas yang Anda butuhkan untuk instantiate.
MrWhite
2
@ jk: Tidak, sebenarnya tidak. programmers.stackexchange.com/questions/81838/...
pdr

Jawaban:

54

Karena contoh Anda tidak cukup rumit. Untuk skenario sederhana seperti itu, bahkan tidak masuk akal untuk menggunakan pola tingkat lanjut.

Tetapi jika Anda harus tahu lebih banyak daripada produk untuk membangun A, B atau C, dan Anda tidak dapat memiliki akses langsung ke pengetahuan itu, maka itu berguna. Kemudian Anda menggunakan pabrik untuk bertindak sebagai pusat pengetahuan untuk menghasilkan objek yang dibutuhkan.

Mungkin objek-objek itu memerlukan referensi ke beberapa objek X, yang dapat disediakan pabrik, tetapi kode Anda di tempat Anda ingin membangun A, B atau C tidak dapat atau tidak boleh memiliki akses ke X. Mungkin ketika Anda memiliki X Anda membuat A dan B tetapi jika Anda memiliki tipe Y maka Anda membuat C.

Juga pertimbangkan bahwa beberapa objek mungkin membutuhkan 20 dependensi untuk dibuat; lalu bagaimana? Pergi untuk mencari ketergantungan itu di tempat yang seharusnya tidak dapat diakses mungkin menjadi masalah.

Mateusz
sumber
13
+1 untuk menjelaskan bahwa pola Pabrik tidak selalu merupakan pendekatan terbaik.
Neil
1
Karena contoh Anda tidak cukup rumit. Untuk skenario sederhana seperti itu, bahkan tidak masuk akal untuk menggunakan pola tingkat lanjut. Jadi apa yang akan Anda lakukan dalam kasus ini? Sebaris konstruksi bersyarat?
pdr
Itu bisa saja metode yang mengambil produk dan mengembalikan apa yang Anda butuhkan agar dapat digunakan kembali, sehingga tidak harus sejajar. Jika metode seperti itu tumbuh menjadi sesuatu yang lebih besar, atau digunakan di beberapa kelas lain, Anda bisa merefleksikannya ke kelas yang berbeda.
Mateusz
Pola ini disebut Metode Pabrik karena suatu alasan. Metode ini tidak harus berada di kelas yang berbeda untuk menjadi Metode Pabrik (meskipun sering terjadi).
pdr
Saya telah melewatkan "Metode" di dalamnya, jadi Anda benar tuan.
Mateusz
23

Pola pabrik biasanya lebih kompleks dari itu. Pabrik memutuskan kriteria tertentu yang dibuat / dikembalikan. Sebaliknya, ketika Anda tidak menggunakan pabrik, Anda akan memiliki kode yang berulang kali digunakan di beberapa lokasi dalam kode Anda.

Sebagai contoh pertimbangkan hal berikut: Anda perlu memuat data dari DB, tetapi Anda memiliki satu pusat DB untuk integrasi dengan banyak data, dan satu yang lebih kecil di memori pada setiap dev-PC. Dalam kode Anda Anda bertanya pabrik untuk mendapatkan sebuah DB-pegangan dan kembali pabrik salah satu dari mereka tergantung pada misalnya file konfigurasi.

Andy
sumber
20

Pola Metode Pabrik mengabstraksi proses pengambilan keputusan dari kelas panggilan. Ini memiliki beberapa keunggulan:

Penggunaan kembali. Jika saya ingin membuat instantiate di banyak tempat, saya tidak perlu mengulangi kondisi saya, jadi ketika saya datang untuk menambah kelas baru, saya tidak berisiko kehilangan yang baru.

Unit-Testability. Saya dapat menulis 3 tes untuk pabrik, untuk memastikan itu mengembalikan jenis yang benar pada kondisi yang benar, maka kelas panggilan saya hanya perlu diuji untuk melihat apakah itu memanggil pabrik dan kemudian metode yang diperlukan pada kelas yang dikembalikan. Perlu tahu apa-apa tentang implementasi pabrik itu sendiri atau kelas beton.

Kemungkinan diperpanjang. Ketika seseorang memutuskan kita perlu menambahkan kelas D baru ke pabrik ini, tidak ada kode panggilan, baik tes unit atau implementasi, yang perlu diceritakan. Kami cukup membuat kelas D baru dan memperluas metode pabrik kami. Ini adalah definisi dari Prinsip Terbuka-Tertutup .

Anda bahkan dapat membuat kelas pabrik baru dan membuatnya hot-swappable, jika situasinya mengharuskannya - misalnya, jika Anda ingin dapat mengaktifkan dan menonaktifkan kelas D, saat pengujian. Saya pernah mengalami situasi ini hanya sekali, tetapi itu sangat berguna.

Seperti yang telah dikatakan, Pola Pabrik tidak selalu cara untuk pergi. Tapi, di mana pun Anda melihat instantiation bersyarat, Anda harus memikirkannya sejenak.

pdr
sumber
14

Keuntungan utama dari pola Pabrik ada dua:

  1. Tempat-tempat yang membutuhkan implementasi produk tidak perlu tahu cara membangunnya. Pabrik menyimpan informasi itu.

    Apakah Anda ingin tahu argumen apa yang harus diberikan kepada konstruktor tertentu? Atau dependensi apa yang Anda harus menyuntikkan? Atau bagaimana cara mendaftar kelas implementasi dengan database setelah dikonfigurasi sepenuhnya? Tidak? Biarkan pabrik mengurus semua barang itu.

  2. Tempat-tempat yang membutuhkan implementasi produk tidak perlu tahu pada saat deskripsi modul (yaitu, pada waktu kompilasi) apa nama kelas implementasi.

    Jadi, atidak perlu ada hubungannya dengan A; "apa yang harus dibangun" dapat dijelaskan dalam hal properti non-fungsional yang diinginkan, dan bukan hanya namanya. Ini jauh lebih fleksibel.

Kelemahannya adalah di mana Anda tahu apa yang harus dibuat dan bagaimana melakukannya, Anda mendapatkan lebih banyak kompleksitas ketika Anda menggunakan pabrik. Cara mengatasinya sederhana: jangan gunakan pabrik saat itu tidak masuk akal!

Donal Fellows
sumber
2

Saya ingin berpikir tentang pola desain dalam hal kelas sebagai 'orang,' dan pola adalah cara orang berbicara satu sama lain.

Jadi, bagi saya pola pabrik seperti agen perekrutan. Anda memiliki seseorang yang membutuhkan sejumlah pekerja variabel. Orang ini mungkin mengetahui beberapa info yang mereka butuhkan pada orang yang mereka sewa, tapi hanya itu.

Jadi, ketika mereka membutuhkan karyawan baru, mereka memanggil agen perekrutan dan memberi tahu mereka apa yang mereka butuhkan. Sekarang, untuk benar-benar merekrut seseorang, Anda perlu mengetahui banyak hal - manfaat, verifikasi kelayakan, dll. Tetapi orang yang direkrut tidak perlu mengetahui semua ini - agen perekrutan menangani semua itu.

Dengan cara yang sama, menggunakan Pabrik memungkinkan konsumen untuk membuat objek baru tanpa harus mengetahui detail bagaimana mereka dibuat, atau apa dependensi mereka - mereka hanya perlu memberikan informasi yang mereka inginkan.

Kesopanan

Premraj
sumber
1

Pola Pabrik adalah pola desain yang paling sering digunakan dan disalahgunakan.

Saya telah menemukan banyak kasus di mana kelas Pabrik dikodekan ketika konstruktor sederhana akan memadai.

Jangan gunakan kelas pabrik kecuali: -

  • Anda bergantung pada sumber daya eksternal tetapi Anda belum tahu persis yang mana.
  • Konstruksi mahal dan Anda ingin membangun sekali dan menggunakan kembali berkali-kali.
  • Membangun instance baru tergantung pada instance apa yang telah dibangun (mis. Anda hanya dapat memiliki lima koneksi, atau, Anda harus menggunakan nomor id koneksi satu lebih banyak daripada nomor terakhir yang digunakan).
James Anderson
sumber
0

Gunakan Metode Pabrik saat membuat instance subclass dan kode klien tidak seharusnya bertanggung jawab untuk memutuskan subclass tertentu yang dipakai.

Ini berguna karena mencegah Anda dari harus mengubah kode klien ketika Anda perlu mengubah kelas apa yang dipakai. Mengubah kode yang ada adalah praktik buruk karena biasanya rawan kesalahan.

Contoh akan memiliki subclass, di mana masing-masing mengurutkan data dalam urutan menaik, tetapi dengan cara yang berbeda. Setiap cara optimal untuk jenis data tertentu. misalnya: data yang diurutkan sebagian, data yang berupa angka, dll. Kode klien adalah kelas yang hanya menangani pencetakan data. Memiliki kode yang memutuskan kelas penyortiran mana yang akan dipakai di kelas klien akan membuatnya menjadi kelas yang kompleks. Dengan kata lain memiliki lebih dari satu tanggung jawab, dalam hal ini, memutuskan kelas pemilahan mana yang optimal dan mencetak data. Dengan meletakkan kode yang memutuskan kelas sortasi mana yang akan dipakai menjadi kelas Factory itu memisahkan masalah sehingga Anda tidak perlu mengubah kelas klien setiap kali Anda perlu mengubah subklas sortasi mana yang akan dipakai.

Ini adalah cara untuk menutupi pantat Anda, jika Anda dapat melihat perubahan yang Anda buat sendiri di garis bagaimana kelas apa yang akan dipakai maka kelas pabrik masuk akal untuk digunakan. Ini membantu menjaga kelas Anda fokus pada satu tanggung jawab mereka dan sebagai hasilnya memastikan bahwa Anda cenderung harus memodifikasi kode yang ada yang tidak terkait.

kiwicomb123
sumber