Pola metode pabrik c. Pola Metode Pabrik - tingkat kelas. Deskripsi Metode Pabrik




Metode Pabrik memungkinkan subkelas membuat beberapa kelas menggunakan antarmuka umum, dengan subkelas menentukan objek induk mana yang harus diimplementasikan. Artinya, kita memerlukan semacam antarmuka umum. Antarmuka dalam bahasa pemrograman C# ini dapat berupa kelas abstrak atau antarmuka.

Bayangkan kelas abstrak seperti ini:

Kelas abstrak Produk ( desimal abstrak publik Harga Pembelian (dapatkan; set;) Desimal abstrak publik Harga (dapatkan; set;) string abstrak publik Deskripsi (dapatkan; set;) )

Jika kita mewarisi kelas ini, kita harus berpegang pada prinsip polimorfisme. Artinya, definisikan ulang semua properti kelas ini menggunakan kata override. Mari kita lakukan hal itu. Kami membuat kelas yang diwarisi dari kelas Produk, yang akan merangkum logika produk tertentu:

Komputer Kelas: Produk ( desimal pribadi _harga_pembelian; desimal pribadi _harga; string pribadi _deskripsi; Komputer publik() : ini(null) ( ) Komputer publik(string _deskripsi): ini(_deskripsi, 0) ( ) Komputer publik(string _deskripsi, desimal _purchase_price) : ini (_deskripsi, _purchase_price, 0) ( ) Komputer publik(string _description, desimal _purchase_price, desimal _price) ( this._description = _description; this._purchase_price = _purchase_price; this._price = _price; ) public override string Deskripsi ( dapatkan ( return _description; ) set ( _description = nilai; ) ) public override desimal Harga ( get ( return _price; ) set ( _price = value; ) ) public override desimal Harga Pembelian ( get ( return _purchase_price; ) set ( _purchase_price = nilai; ) ) )

Kelas Produk dimaksudkan untuk mendefinisikan antarmuka objek yang dibuat oleh metode pabrik. Ini seperti cangkang dasar sebuah produk. Produk memiliki harga, dll. Jika Anda mau, tambahkan beberapa properti dan metode lagi ke kelas Produk dan definisikan ulang properti dan metode tersebut di kelas yang diwarisi. Saya harap semuanya jelas untuk saat ini. Sebelum saya melanjutkan, saya akan menyampaikan beberapa patah kata tentang pola itu sendiri. Biasanya kami menggunakan kelas konkret dan menulisnya seperti ini:

Komputer komputer = Komputer baru();

Tetapi pola ini menyatakan bahwa dalam teks program Anda tidak dapat beroperasi dengan kelas tertentu, tetapi dengan representasi abstraknya. Berikut adalah kasus paling populer yang masuk akal untuk menggunakan pola yang dibahas di sini:

  • kelas yang membuat subkelas tidak mengetahui sebelumnya akan menjadi subkelas apa;
  • kelas dirancang sedemikian rupa sehingga objek yang dibuatnya ditentukan oleh subkelas;
  • kelas mendelegasikan tanggung jawabnya kepada salah satu subkelas tambahan, setelah itu direncanakan untuk melokalisasi pengetahuan kelas mana yang memikul tanggung jawab ini;

Inilah yang kami maksud:

Dua kelas lagi telah ditambahkan ke diagram. Mengikuti pola tersebut, harus ada kelas abstrak lain, yang akan berisi metode pabrik. Ini seperti sebuah pabrik yang menciptakan produk dengan jenis tertentu. Setelah pembuat kelas abstrak dengan metode pabrik ditentukan, kita dapat membuat kelas warisan kita sendiri untuk produk tertentu. Agar lebih mudah memahaminya, mari kita sederhanakan diagramnya:

Itu semua painya. Ada kelas produk dan pembuat abstrak yang memiliki metode pabrik. Kami membuat kelas untuk balapan produk tertentu (diwarisi dari Product ), membuat kelas khusus untuk pencipta produk tertentu (diwarisi dari Creator ) dua.

Inilah yang tampak seperti Pencipta kelas abstrak:

Pencipta kelas abstrak ( public abstract Product FactoryMethod(); public abstract Product FactoryMethod(string _description); public abstract Product FactoryMethod(string _description, desimal _purchase_price); public abstract Product FactoryMethod(string _description, desimal _purchase_price, desimal _price); ) Dalam hal ini kelas, Saya telah mendefinisikan metode untuk semua jenis konstruktor di kelas Komputer. Dan berikut adalah kelas pencipta untuk kelas Komputer: class ComputerCreator: Creator ( public override Product FactoryMethod() ( return new Computer(); ) public override Product FactoryMethod(string _description) ( return new Computer(_description); ) public override Product FactoryMethod( string _description, desimal _purchase_price) ( kembalikan Komputer baru(_deskripsi, _purchase_price); ) public override Product FactoryMethod(string _description, desimal _purchase_price, desimal _price) ( kembalikan Komputer baru(_description,_purchase_price,_price); ) )

Itu saja, sekarang semuanya seperti pada Gambar. 1. Kita melihat bahwa metode pabrik kelebihan beban agar dapat memanggil konstruktor kelas Komputer yang diperlukan.

Mari kita buat kelas CDPlayer lain dan kelas pembuatnya dengan cara serupa:

Kelas Pemutar CD:

Kelas CDPlayer: Produk ( desimal pribadi _harga_pembelian; // harga beli desimal pribadi _harga; // harga jual // susunan format yang didukung oleh pemutar CD string pribadi _deskripsi; CDPlayer publik() : this(null) ( ) public CDPlayer(string _deskripsi ) : ini(_deskripsi, 0) ( ) CDPlayer publik(string _deskripsi, desimal _harga_pembelian) : ini(_deskripsi, _harga_pembelian, 0) ( ) CDPlayer publik(string _deskripsi, desimal _harga_pembelian, desimal _harga) ( this._deskripsi = _deskripsi; ini ._purchase_price = _purchase_price; this._price = _price; ) string penggantian publik Deskripsi ( dapatkan ( return _description; ) set ( _description = nilai; ) ) harga desimal override publik ( dapatkan ( return _price; ) set( _price = nilai;) ) public override desimal Harga Pembelian ( dapatkan ( return _purchase_price; ) set ( _purchase_price = value;) ) )

Kelas pembuat untuk kelas CDPlayer:

Kelas CDPlayerCreator: Pencipta ( public override Product FactoryMethod() ( return new CDPlayer(); ) public override Product FactoryMethod(string _description) ( return new CDPlayer(_description); ) public override Product FactoryMethod(string _description, desimal _purchase_price) ( return new CDPlayer(_description, _purchase_price); ) public override Product FactoryMethod(string _description, desimal _purchase_price, desimal _price) ( kembalikan CDPlayer baru(_description, _purchase_price, _price); ) )

Yang tersisa hanyalah menulis kode klien untuk mengagumi pekerjaan kami.

Kekosongan statis Utama (string args) ( Daftar Daftar Produk = Daftar baru (); Pencipta pencipta = Pencipta baru; pencipta = ComputerCreator baru(); pencipta = CDPlayerCreator baru(); foreach (Pembuat cr dalam pembuat) ( if (cr adalah ComputerCreator) productList.Add(cr.FactoryMethod("Laptop", 600, 800)); if (cr adalah CDPlayerCreator) productList.Add(cr.FactoryMethod("audio, mp3 ,mp4",250,360)); ) foreach (Produk pr di productList) ( Console.WriteLine("Objek kelas (0);\n" + "Deskripsi: (1);\n" + "Harga pembelian: (2 ) ;\n" + "Harga Jual: (3);\n", pr.GetType().Name, pr.Description, pr.PurchasePrice, pr.Price); ) Console.ReadLine(); )

Berikut hasil programnya:

Bagi saya, ini adalah fakta yang menarik. Sebuah instance dari kelas abstrak tidak dapat dibuat. Tapi tidak ada yang mengatakan bahwa itu tidak bisa dijadikan pangkalan. Jika Anda menulisnya seperti ini, semuanya akan baik-baik saja:

Produk pr = Komputer baru();

Ini tautannya pr(kelas abstrak) mengacu pada objek kelas Komputer. Untuk alasan ini, saya dapat dengan mudah membuat koleksi khusus, seperti yang telah dilakukan. Ketika saya melihat template ini, saya langsung memperhatikan tahapan pengembangannya sebagai berikut:

  • Kelas abstrak untuk objek -> sebaliknya, kelas yang mengimplementasikannya untuk tujuannya sendiri.
  • Kelas abstrak untuk membuat objek -> sebaliknya, kelas yang mengimplementasikannya untuk membuat objeknya sendiri.
Dengan kata lain:

Produk- produk itu sendiri. Dirancang untuk menentukan antarmuka objek yang dibuat dengan metode pabrik;

Produk Beton(Komputer, CDPlayer) - produk spesifik yang berpartisipasi dalam skema dan bertanggung jawab untuk mengimplementasikan Produk kelas abstrak (antarmuka).

Pencipta adalah penciptanya, dan namanya berbicara sendiri. Objek ini dimaksudkan untuk mendeklarasikan metode pabrik yang mengembalikan objek bertipe Produk.

Pencipta Beton- pencipta tertentu. Semuanya jelas di sini: implementasi spesifik pencipta terlibat dalam pengembalian produk tertentu. Dalam contoh kita, dua implementasi kreator yang konkrit adalah ComputerCreator dan CDPlayerCreator.

Pencipta memercayai subkelasnya untuk mengimplementasikan produk spesifik yang sesuai. Itulah intinya Metode Pabrik.

Sekarang mari kita perhatikan pro dan kontra dari pola ini:

Kerugian yang paling jelas dari Metode Pabrik adalah kebutuhan untuk membuat penerus Pencipta setiap kali Anda berencana untuk mendapatkan jenis produk baru (yaitu Produk Beton baru). Dan sayangnya, ini tidak dapat dihindari. Namun masalah serupa terjadi pada banyak pola generatif. Kelebihannya antara lain kemampuan membuat objek secara lebih universal, tanpa berfokus pada kelas tertentu dan menggunakan antarmuka umum.

1. Nama: Metode Pabrik

2. Tugas:

    Sistem harus tetap dapat diperluas dengan menambahkan tipe objek baru. Menggunakan ekspresi baru secara langsung tidak disarankan karena dapat menyebabkan kode untuk membuat objek dengan tipe tertentu tersebar di seluruh aplikasi. Maka operasi seperti menambahkan objek tipe baru ke sistem atau mengganti objek dari satu tipe dengan tipe lain akan menjadi sulit (detail lebih lanjut di bagian Pola Generatif). Pola Metode Pabrik memungkinkan sistem untuk tetap independen terhadap proses pembuatan objek dan tipenya.

    Diketahui sebelumnya kapan harus membuat suatu objek, namun jenisnya tidak diketahui.

3. Solusi:

Untuk memastikan bahwa sistem tetap independen terhadap tipe objek yang berbeda, pola Metode Pabrik menggunakan mekanisme polimorfisme - kelas dari semua tipe akhir mewarisi dari satu kelas dasar abstrak yang dimaksudkan untuk penggunaan polimorfik. Kelas dasar ini mendefinisikan antarmuka tunggal yang melaluinya pengguna akan mengoperasikan objek tipe akhir.

Untuk mempermudah penambahan tipe baru ke sistem, pola Metode Pabrik melokalisasi pembuatan objek tipe tertentu di kelas pabrik khusus. Metode kelas ini, yang melaluinya objek kelas tertentu dibuat, disebut metode pabrik.

Antarmuka metode pabrik dideklarasikan dalam kelas pabrik independen, dan implementasinya ditentukan oleh subkelas tertentu dari kelas ini.

4. Diagram kelas UML pola Metode Pabrik. Implementasi klasik

Produk- produk itu sendiri. Dirancang untuk menentukan antarmuka objek yang dibuat dengan metode pabrik;

Produk Beton(Komputer) - produk spesifik yang berpartisipasi dalam skema dan bertanggung jawab untuk mengimplementasikan Produk kelas abstrak (antarmuka).

Pencipta adalah penciptanya, dan namanya berbicara sendiri. Objek ini dimaksudkan untuk mendeklarasikan metode pabrik yang mengembalikan objek bertipe Produk.

Pencipta Beton- pencipta tertentu. Semuanya jelas di sini: implementasi spesifik pencipta terlibat dalam pengembalian produk tertentu. Dalam contoh kita, implementasi konkrit dari pembuatnya adalah ComputerCreator.

Pencipta memercayai subkelasnya untuk mengimplementasikan produk spesifik yang sesuai. Itulah intinya Metode Pabrik.

5. Contoh penerapan Metode Pabrik:

Kelas Produk dimaksudkan untuk mendefinisikan antarmuka objek yang dibuat dengan metode pabrik. Ini seperti cangkang dasar sebuah produk. Produk memiliki harga, dll.

    abstrak kelas Produk

    publik abstrak desimal Harga pembelian( mendapatkan; mengatur;}

    publik abstrak desimal Harga ( mendapatkan; mengatur;}

    publik abstrak rangkaian Keterangan ( mendapatkan; mengatur;}

Kami membuat kelas yang diwarisi dari kelas Produk, yang akan merangkum logika produk tertentu:

    kelas Komputer: Produk

    pribadi desimal _harga pembelian;

    pribadi desimal _harga;

    pribadi rangkaian _keterangan;

    publik Komputer( rangkaian _keterangan, desimal _harga pembelian,

    desimal _harga)

    ini._deskripsi = _deskripsi;

    ini._harga_pembelian = _harga_pembelian;

    ini._harga = _harga;

    publik mengesampingkan rangkaian Keterangan

    mendapatkan { kembali _keterangan; )

    mengatur( _deskripsi = nilai; )

    publik mengesampingkan desimal Harga

    mendapatkan { kembali _harga; )

    mengatur( _harga = nilai; )

    publik mengesampingkan desimal Harga pembelian

    mendapatkan { kembali _harga pembelian; )

    mengatur( _harga_pembelian = nilai; )

Mari kita jelaskan kelas pembuat abstrak yang memiliki metode pabrik.

    abstrak kelas Pencipta

    publik abstrak Metode Pabrik Produk( rangkaian _keterangan,

    desimal _harga pembelian, desimal _harga);

Kami membuat kelas khusus untuk pencipta produk tertentu (diwarisi dari Pencipta). Kelas ini mendefinisikan metode untuk konstruktor kelas Komputer (jika terdapat beberapa konstruktor, maka setiap konstruktor memiliki metode pabriknya sendiri):

    kelas Pencipta Komputer: Pencipta

    publik mengesampingkan Metode Pabrik Produk( rangkaian _keterangan,

    desimal _harga pembelian, desimal _harga)

    kembali baru Komputer(_deskripsi,_harga_pembelian,_harga);

Kode klien:

    statis ruang kosong Utama( rangkaian argumen)

    Daftar Daftar Produk = baru Daftar

    Pencipta pencipta = baru Pencipta;

    pencipta = baru Pencipta Komputer();

    untuk setiap(Pencipta kr di dalam pencipta)

    jika(kr adalah Pencipta Komputer)

    productList.Add(cr.FactoryMethod("Laptop", 600, 800));

    untuk setiap(Produk pr di dalam Daftar Produk)

    Console.WriteLine("Objek kelas (0);\n" +

    "Deskripsi: (1);\n" +

    "Harga pembelian: (2);\n" +

    "Harga jual: (3);\n",

    pr.GetType().Nama,

  1. pr.Harga Pembelian,

Hasil program:

6. Kelebihan dan kekurangan pola ini:

Kerugian yang paling jelas dari Metode Pabrik adalah kebutuhan untuk membuat penerus Pencipta setiap kali Anda berencana untuk mendapatkan jenis produk baru (yaitu Produk Beton baru). Dan sayangnya, ini tidak dapat dihindari. Namun masalah serupa terjadi pada banyak pola generatif. Kelebihannya antara lain kemampuan membuat objek secara lebih universal, tanpa berfokus pada kelas tertentu dan menggunakan antarmuka umum.

Metode pabrik- pola yang menghasilkan kelas - merujuk ke pola generatif (templat)

Tujuan

Mendefinisikan antarmuka untuk membuat objek, tetapi menyerahkannya kepada subkelas untuk memutuskan kelas (produk) mana yang akan dibuat instance-nya.
Metode pabrik memungkinkan kelas untuk mendelegasikan pembuatan instance ke subkelas.

Nama panggilan

Pola Metode Pabrik juga dikenal sebagai VirtualConstructor.

Motivasi

Mari kita punya aplikasi - baiklah, atau kami ingin menulisnya - apa maksudnya bisa membuat dokumen dari berbagai jenis- Tetapi kita tidak mengetahui sebelumnya jenis dokumen apa (= produk) pengguna akan memilih-
namun mekanisme pembuatan dokumen-dokumen ini - jika dilihat dari luar - terlihat serupa - kesamaan ini dijelaskan oleh kelas abstrak, sedangkan kelas abstrak tidak dapat dipakai - yaitu, objek dari kelas ini tidak dapat dibuat.
Bagaimana menjadi?

Pola ini memberi kita solusi Metode pabrik, yang menyembunyikan nama dokumen tertentu di kelas aplikasi yang membuatnya.

Seperti yang bisa kita lihat, di sini diusulkan untuk membangun hierarki objek - atau lebih tepatnya, dua hierarki paralel - hierarki produk dan hierarki pembuat produk ini.

Omong-omong, ini lebih jelas ditunjukkan oleh diagram gratis ini:

Penerapan

Gunakan pola metode pabrik ketika:

  1. kelas tidak diketahui sebelumnya objek kelas mana yang perlu dibuat;
  2. kelas dirancang sedemikian rupa objek yang dibuatnya ditentukan oleh subkelas;
  3. kelas mendelegasikan tanggung jawabnya ke salah satu dari beberapa subkelas pembantu, dan Anda membuat rencana melokalisasi pengetahuan tentang kelas mana yang mengambil tanggung jawab ini.

Struktur

Struktur template ini dapat direpresentasikan sebagai diagram berikut:

Peserta

  1. Produk(Dokumen) - produk: mendefinisikan antarmuka objek yang dibuat dengan metode pabrik;
  2. Produk Beton(MyDocument) produk spesifik: mengimplementasikan interfaceProduct;
  3. Pencipta(Aplikasi) = pencipta: mendeklarasikan metode pabrik yang mengembalikan objek bertipe Produk. Pencipta juga dapat menentukan implementasi default metode pabrik, yang mengembalikan objek ConcreteProduct; dapat memanggil metode pabrik untuk membuat objek Produk.
  4. Pencipta Beton(Aplikasi Saya) = pembuat beton: mengganti metode pabrik yang mengembalikan objek Produk Beton.

Hubungan

Pencipta "bergantung" pada subkelasnya(implementasi Pencipta tertentu) dalam menentukan metode pabrik yang akan mengembalikan sebuah instance dari produk spesifik yang sesuai.

hasil

Metode Pabrik meringankan perancang dari kebutuhan untuk menanamkan kelas yang bergantung pada aplikasi ke dalam kode. Kode ini hanya berhubungan dengan antarmuka kelas Produk, sehingga dapat bekerja dengan kelas produk konkret apa pun yang ditentukan pengguna.

Potensi kerugian

Kerugian potensial dari metode pabrik adalah klien mungkin harus membuat subkelas Creator untuk membuat hanya satu objek ConcreteProduct. Subkelas dibenarkan jika klien entah bagaimana harus membuat subkelas Pencipta, sebaliknya kepada klien Anda harus berurusan dengan lapisan subkelas tambahan.

Dua kemungkinan penerapan pola metode frabrik:

Menyediakan subkelas dengan operasi kait

Membuat objek di dalam kelas menggunakan metode pabrik selalu lebih fleksibel daripada membuatnya secara langsung. Metode pabrik membuat operasi kait di subkelas untuk menyediakan versi yang diperluas
obyek.

Dalam contoh dokumen, kelas Dokumen dapat mendefinisikan metode pabrik CreateFileDialog yang membuat kotak dialog untuk memilih file dari dokumen yang sudah ada. Subkelas dari kelas ini dapat didefinisikan
kotak dialog khusus aplikasi, menggantikan metode pabrik ini. Dalam hal ini, metode pabrik tidak abstrak, tetapi berisi implementasi default yang masuk akal;

Metode pabrik tidak hanya dapat dipanggil oleh pembuatnya: klien juga dapat menggunakan metode pabrik, khususnya di hadapan.

Misalnya, bentuk grafik yang dapat dimanipulasi secara interaktif: diregangkan, dipindahkan, atau diputar menggunakan mouse.
Menerapkan interaksi pengguna seperti itu tidak selalu mudah. Seringkali perlu untuk menyimpan dan memperbarui informasi tentang keadaan manipulasi saat ini. Namun keadaan ini hanya diperlukan pada saat manipulasi itu sendiri, sehingga tidak boleh ditempatkan pada objek yang mewakili gambar tersebut. Selain itu, tokoh-tokoh tersebut berperilaku sesuai

Misalnya, merentangkan suatu segmen dapat direduksi menjadi mengubah posisi titik akhir, dan merenggangkan teks dapat direduksi menjadi berubah
spasi baris.

Dengan batasan seperti itu, lebih baik menggunakan objek Manipulator terpisah, yang mengimplementasikan interaksi dan mengontrol statusnya saat ini. Bentuk yang berbeda akan memiliki manipulator yang berbeda, yang merupakan subkelas dari Manipulator. Hierarki kelas Manipulator yang dihasilkan sejajar (setidaknya sebagian) dengan hierarki kelas Gambar. Kelas Gambar menyediakan metode pabrik CreateManipulator yang memungkinkan klien membuat manipulator yang sesuai dengan gambar. Subkelas Gambar menggantikan metode ini sehingga mengembalikan subkelas Manipulator yang sesuai untuknya. Sebaliknya, kelas Gambar dapat mengimplementasikan CreateManipulator sehingga mengembalikan instance default kelas Manipulator, dan subkelas Gambar dapat mewarisi
ini adalah bawaannya.

Kelas-kelas bentuk yang berfungsi sesuai dengan prinsip yang dijelaskan tidak memerlukan manipulator khusus, begitu juga hierarki
hanya sebagian paralel. Perhatikan bagaimana metode pabrik mendefinisikan hubungan antara keduanya
hierarki kelas. Ini berisi pengetahuan tentang kelas mana yang dapat bekerja sama.

Berikut diagramnya:

Jadi sekali lagi (tentang hasilnya):

  1. Metode pabrik menghilangkan kebutuhan perancang untuk membangun kelas khusus aplikasi ke dalam kode.
  2. Anda dapat membuat (Jika diinginkan) objek yang diperluas - memungkinkan implementasi spesifik dari Pencipta abstrak untuk menimpa - jika perlu, sejumlah metode (seperti pada contoh dialog file)
  3. Koneksi hierarki paralel

Penerapan

Pada bagian ini perlu disebutkan fitur-fitur implementasinya, yaitu sebagai berikut:

  • Ada dua kasus mendasar untuk implementasi:
    1. ketika kelas pencipta bersifat abstrak
    2. ketika Pencipta adalah kelas konkret ("reguler").
    3. Ya, masih ada tipe campuran - ketika kelas abstrak berisi implementasi default
  • metode pabrik yang diparameterisasi- fitur ini menyiratkan bahwa, secara umum, dengan menggunakan metode pabrik, Anda dapat membuat berbagai jenis produk tergantung pada parameter yang dilewati
  • berbagai fitur yang terkait dengan bahasa implementasi tertentu

Kode contoh

Aplikasi yang Diketahui

Metode pabrik ditemukan di mana-mana - Sebagian besar perpustakaan dan kerangka kerja menggunakan pola Metode Pabrik dalam satu atau lain cara- khususnya perpustakaan ET++

Pola terkait

Sering diimplementasikan menggunakan metode pabrik.

Contoh pada bagian Motivasi dari deskripsi abstrak pabrik juga menggambarkan pola metode pabrik.
Pola metode pabrik sering disebut dalam metode templat.

Prototipe tidak perlu disubkelaskan dari kelas Creator. Namun, mereka sering kali memerlukan operasi Inisialisasi pada kelas Produk.
Pencipta menggunakan Inisialisasi untuk menginisialisasi suatu objek. Pabrik
metode ini tidak memerlukan operasi seperti itu.

Metode pabrik adalah pola desain generatif yang mendefinisikan antarmuka umum untuk membuat objek dalam superkelas, memungkinkan subkelas mengubah jenis objek yang dibuat.

Masalah

Bayangkan Anda sedang membuat program manajemen pengangkutan. Pada awalnya, Anda berharap untuk mengangkut barang hanya dengan mobil. Oleh karena itu, semua kode Anda berfungsi dengan objek kelas Truck.

Pada titik tertentu, program Anda menjadi begitu terkenal sehingga maskapai penerbangan mengantri dan meminta untuk menambahkan dukungan logistik maritim ke dalam program tersebut.


Menambahkan kelas baru tidaklah mudah jika semua kode sudah terikat ke kelas tertentu.

Berita bagus, bukan?! Tapi bagaimana dengan kodenya? Sebagian besar kode yang ada terikat erat dengan kelas Truk. Untuk menambahkan kelas kapal laut ke dalam program, Anda perlu menggali keseluruhan program. Selain itu, jika nanti Anda memutuskan untuk menambahkan jenis transportasi lain ke dalam program, maka semua pekerjaan ini harus diulangi.

Akibatnya, Anda akan mendapatkan kode menakutkan yang berisi pernyataan kondisional yang melakukan tindakan tertentu, bergantung pada kelas kendaraan.

Larutan

Pola metode Pabrik menyarankan pembuatan objek tidak secara langsung menggunakan operator baru, tetapi melalui pemanggilan operator khusus pabrik metode. Jangan khawatir, objek akan tetap dibuat menggunakan new , tetapi metode pabrik akan melakukannya.


Subkelas dapat mengubah kelas objek yang dibuatnya.

Pada pandangan pertama, ini mungkin tampak tidak ada gunanya: kita hanya memindahkan panggilan konstruktor dari satu ujung program ke ujung lainnya. Namun sekarang Anda dapat mengganti metode pabrik di subkelas untuk mengubah jenis produk yang Anda buat.

Agar sistem ini berfungsi, semua objek yang dikembalikan harus memiliki antarmuka yang sama. Subkelas akan dapat menghasilkan objek dari kelas berbeda dengan mengikuti antarmuka yang sama.


Semua objek produk harus memiliki antarmuka yang sama.

Misalnya, kelas Truk dan Kapal mengimplementasikan antarmuka Transport dengan metode pengiriman. Masing-masing kelas menerapkan metodenya dengan caranya sendiri: truk membawa barang melalui darat, dan kapal membawa barang melalui laut. Metode pabrik di kelas RoadLogistics akan mengembalikan objek truk, dan kelas MarineLogistics akan mengembalikan objek kapal.


Selama semua produk menerapkan antarmuka yang sama, objeknya dapat dipertukarkan dalam kode klien.

Untuk klien metode pabrik tidak ada perbedaan antara objek-objek ini, karena ia akan memperlakukannya sebagai semacam Transport abstrak. Penting baginya bahwa objek tersebut memiliki metode pengiriman, tetapi cara kerjanya tidak penting.

Struktur



    Produk mendefinisikan antarmuka umum untuk objek yang dapat dihasilkan oleh pembuat dan subkelasnya.

    Produk Tertentu berisi kode untuk berbagai produk. Produk-produk tersebut akan berbeda dalam implementasinya, namun mereka akan memiliki antarmuka yang sama.

    Pencipta mendeklarasikan metode pabrik yang harus mengembalikan objek produk baru. Jenis hasil harus sesuai dengan antarmuka umum produk.

    Seringkali metode pabrik dideklarasikan abstrak untuk memaksa semua subkelas mengimplementasikannya secara berbeda. Namun bisa juga mengembalikan produk standar tertentu.

    Terlepas dari namanya, penting untuk dipahami bahwa menciptakan produk tidak satu-satunya fungsi pencipta. Biasanya berisi kode lain yang berguna untuk bekerja dengan produk. Analoginya: sebuah perusahaan perangkat lunak besar mungkin memiliki pusat pelatihan pemrogram, tetapi tugas utama perusahaan adalah menciptakan produk perangkat lunak, dan bukan melatih pemrogram.

    Pencipta Tertentu menerapkan metode pabrik dengan caranya sendiri, menghasilkan produk tertentu yang spesifik.

    Metode pabrik tidak harus membuat objek baru setiap saat. Itu dapat ditulis ulang untuk mengembalikan objek yang ada dari beberapa penyimpanan atau cache.

kodesemu

Dalam contoh ini Metode pabrik membantu membuat elemen antarmuka lintas platform tanpa mengikat kode program utama ke kelas elemen tertentu.


Contoh dialog lintas platform.

Metode pabrik dideklarasikan di kelas dialog. Subkelasnya berhubungan dengan berbagai sistem operasi. Berkat metode pabrik, Anda tidak perlu menulis ulang logika dialog untuk setiap sistem. Subkelas dapat mewarisi hampir semua kode dari dialog dasar, mengubah jenis tombol dan elemen lain yang menjadi dasar kode dasar membangun jendela GUI.

Kelas dialog dasar bekerja dengan tombol melalui antarmuka pemrograman umumnya. Oleh karena itu, apa pun variasi tombol yang dikembalikan metode pabrik, dialog akan tetap berfungsi. Kelas dasar tidak bergantung pada kelas tombol tertentu, menyerahkan kepada subkelas untuk memutuskan jenis tombol apa yang akan dibuat.

Pendekatan ini dapat digunakan untuk membuat elemen antarmuka lainnya. Meskipun setiap tipe elemen baru akan membawa Anda lebih dekat ke Pabrik Abstrak.

// Pola metode Pabrik berlaku ketika program // memiliki hierarki kelas produk. antarmuka Tombol adalah metode render() metode onClick(f) kelas WindowsButton mengimplementasikan Tombol adalah metode render(a, b) adalah // Render tombol dalam gaya Windows. metode onClick(f) adalah // Lampirkan event handler Windows ke tombol. class HTMLButton mengimplementasikan Tombol adalah metode render(a, b) adalah // Mengembalikan kode HTML tombol. metode onClick(f) adalah // Lampirkan event handler browser ke tombol. // Kelas dasar pabrik. Perhatikan bahwa "pabrik" hanyalah // peran tambahan untuk kelas. Kemungkinan besar, // sudah memiliki semacam logika bisnis yang memerlukan pembuatan // berbagai produk. Dialog kelas adalah metode render() adalah // Untuk menggunakan metode pabrik, Anda harus // memastikan bahwa logika bisnis ini tidak bergantung pada // kelas produk tertentu. Button adalah antarmuka // tombol umum, jadi semuanya baik-baik saja. Button okButton = createButton() okButton.onClick(closeDialog) okButton.render() // Kita memasukkan semua kode pembuatan produk ke dalam metode khusus // yang disebut "pabrik". metode abstrak createButton() // Pabrik beton mengganti metode pabrik dan // mengembalikan produk mereka sendiri dari metode tersebut. class WindowsDialog extends Dialog adalah metode createButton() yang mengembalikan kelas WindowsButton() baru WebDialog extends Dialog adalah metode createButton() yang mengembalikan kelas HTMLButton() baru Aplikasi adalah dialog field: Dialog // Aplikasi membuat pabrik tertentu bergantung pada // konfigurasi atau lingkungan. metode inisialisasi() adalah config = readApplicationConfigFile() if (config.OS == "Windows") lalu dialog = new WindowsDialog() else if (config.OS == "Web") lalu dialog = new WebDialog() else lempar yang baru Pengecualian("Kesalahan! Sistem operasi tidak dikenal.") // Jika semua kode klien lainnya berinteraksi dengan pabrik dan // produk hanya melalui antarmuka umum, maka // tidak masalah pabrik mana yang awalnya dibuat. metode main() adalah this.initialize() dialog.render()

Penerapan

Ketika jenis dan ketergantungan objek yang harus digunakan kode Anda tidak diketahui sebelumnya.

Metode pabrik memisahkan kode untuk memproduksi produk dari kode lainnya yang menggunakan produk tersebut.

Berkat ini, kode produksi dapat diperluas tanpa menyentuh kode utama. Jadi, untuk menambahkan dukungan pada produk baru, Anda perlu membuat subkelas baru dan menentukan metode pabrik di dalamnya, yang mengembalikan instance produk baru dari sana.

Saat Anda ingin memungkinkan pengguna memperluas bagian kerangka kerja atau pustaka Anda.

Pengguna dapat memperluas kelas kerangka kerja Anda melalui pewarisan. Tapi bagaimana Anda bisa membuat kerangka kerja membuat objek dari kelas-kelas baru ini, bukan dari kelas standar?

Solusinya adalah memberikan pengguna kemampuan untuk memperluas tidak hanya komponen yang diinginkan, tetapi juga kelas yang membuat komponen tersebut. Dan untuk melakukan ini, pembuatan kelas harus memiliki metode pembuatan khusus yang dapat ditentukan.

Misalnya, Anda menggunakan kerangka UI yang sudah jadi untuk aplikasi Anda. Tapi inilah masalahnya - Anda harus memiliki tombol bulat, bukan tombol persegi panjang standar. Anda membuat kelas RoundButton. Namun bagaimana Anda memberi tahu kelas utama UIFramework untuk membuat tombol bulat, bukan tombol standar?

Untuk melakukan ini, Anda membuat subkelas UIWithRoundButtons dari kelas dasar kerangka kerja, mengganti metode pembuatan tombol di dalamnya (ala createButton) dan memasukkan pembuatan kelas tombol Anda di sana. Kemudian gunakan UIWithRoundButtons alih-alih UIFramework standar.

Saat Anda ingin menghemat sumber daya sistem dengan menggunakan kembali objek yang sudah dibuat alih-alih membuat objek baru.

Masalah ini biasanya terjadi ketika bekerja dengan objek yang membutuhkan banyak sumber daya, seperti menghubungkan ke database, sistem file, dll.

Bayangkan berapa banyak langkah yang perlu Anda ambil untuk menggunakan kembali objek yang ada:

  1. Pertama, Anda harus membuat penyimpanan bersama untuk menyimpan semua objek yang Anda buat.
  2. Saat meminta objek baru, Anda perlu melihat ke dalam penyimpanan dan memeriksa apakah ada objek yang tidak terpakai di sana.
  3. Dan kemudian mengembalikannya ke kode klien.
  4. Namun jika tidak ada objek gratis, buat yang baru, jangan lupa menambahkannya ke penyimpanan.

Semua kode ini perlu ditempatkan di suatu tempat agar tidak mengacaukan kode klien.

Tempat yang paling nyaman adalah konstruktor objek, karena semua pemeriksaan ini diperlukan hanya saat membuat objek. Namun sayang, sang desainer selalu menciptakan baru objek, ia tidak dapat mengembalikan instance yang sudah ada.

Ini berarti kita memerlukan metode lain yang dapat mengembalikan objek yang sudah ada dan objek baru. Ini akan menjadi metode pabrik.

Langkah-langkah implementasi

    Bawa semua produk yang dibuat ke antarmuka umum.

    Di kelas yang menghasilkan produk, buat metode pabrik kosong. Tentukan antarmuka umum produk sebagai tipe pengembalian.

    Kemudian telusuri kode kelas dan temukan semua wilayah yang membuat produk. Ganti bagian ini satu per satu dengan panggilan ke metode pabrik, transfer kode untuk membuat berbagai produk ke dalamnya.

    Anda mungkin harus menambahkan beberapa parameter ke metode pabrik untuk mengontrol produk mana yang harus dibuat.

    Pada titik ini, metode pabrik kemungkinan besar akan terlihat menyedihkan. Ini akan berisi operator kondisional besar yang memilih kelas produk yang dibuat. Tapi jangan khawatir, kami akan memperbaikinya.

    Untuk setiap jenis produk, buat subkelas dan ganti metode pabrik di dalamnya. Pindahkan kode untuk membuat produk terkait dari superclass ke sana.

    Jika produk yang dibuat terlalu banyak untuk subkelas pembuat yang ada, Anda dapat mempertimbangkan untuk memasukkan parameter ke metode pabrik yang memungkinkan produk berbeda dikembalikan dalam subkelas yang sama.

    Misalnya, Anda memiliki kelas Mail dengan subkelas AirMail dan SurfaceMail, serta kelas produk Pesawat, Truk, dan Kereta Api. Air sama dengan Airplanes, tapi untuk Surface Mail ada dua produk sekaligus. Anda dapat membuat subkelas email baru untuk kereta api, tetapi ada cara lain untuk menyelesaikan masalah tersebut. Kode klien dapat meneruskan argumen ke metode pabrik SurfaceMail yang mengontrol jenis produk yang dibuat.

    Jika setelah semua pemindahan metode pabrik kosong, Anda dapat membuatnya abstrak. Jika masih ada yang tersisa di dalamnya, tidak masalah, ini akan menjadi implementasi defaultnya.

    Sebaliknya, metode pabrik dibangun berdasarkan warisan tetapi tidak memerlukan inisialisasi yang rumit.

    Metode Pabrik dapat dianggap sebagai kasus khusus dari Metode Templat. Di samping itu, Metode pabrik sering menjadi bagian dari kelas besar dengan Metode templat.

    Deskripsi Metode Pabrik

    Metode Pabrik (juga dikenal sebagai Konstruktor Virtual) adalah pola desain generatif yang menyediakan antarmuka kepada subkelas untuk membuat instance kelas. Pada saat penciptaan, ahli waris dapat menentukan kelas mana yang akan dibuat. Dengan kata lain, Pabrik mendelegasikan pembuatan objek kepada keturunan kelas induk. Ini memungkinkan Anda untuk tidak menggunakan kelas tertentu dalam kode program, tetapi memanipulasi objek abstrak pada tingkat yang lebih tinggi.

    Mendefinisikan antarmuka untuk membuat objek, tetapi menyerahkannya kepada subkelas untuk memutuskan kelas mana yang akan dibuat instance-nya. Metode pabrik memungkinkan suatu kelas untuk mendelegasikan pembuatan subkelas. Digunakan ketika:

    • kelas tidak mengetahui sebelumnya objek mana dari subkelas mana yang perlu dibuat.
    • sebuah kelas dirancang sedemikian rupa sehingga objek yang dibuatnya ditentukan oleh subkelas.
    • sebuah kelas mendelegasikan tanggung jawabnya kepada salah satu dari beberapa subkelas tambahan, dan rencananya adalah untuk melokalisasi pengetahuan kelas mana yang memikul tanggung jawab ini

    Struktur

    • Produk- produk
      • mendefinisikan antarmuka objek yang dibuat dengan metode abstrak;
    • Produk Beton- produk tertentu
      • mengimplementasikan antarmuka Produk;
    • Pencipta- pencipta
      • mendeklarasikan metode pabrik yang mengembalikan objek bertipe Produk. Mungkin juga berisi implementasi "default" dari metode ini;
      • dapat memanggil metode pabrik untuk membuat objek bertipe Produk;
    • Pencipta Beton- pencipta tertentu
      • menimpa metode pabrik sehingga membuat dan mengembalikan objek kelas Produk Beton.