Fasad Jarak Jauh (Pintu masuk depan). Pola desain fasad dalam PHP Pola desain fasad




Deskripsi Fasad Jarak Jauh

Menyediakan antarmuka serikat umum untuk satu set metode objek untuk meningkatkan efisiensi jaringan.

Pola Fasad Jarak Jauh dalam model berorientasi objek meningkatkan penanganan objek kecil yang memiliki metode kecil. Metode kecil membuka kemungkinan besar untuk mengontrol dan mengubah perilaku, serta untuk meningkatkan pemahaman klien tentang cara kerja aplikasi. Salah satu konsekuensi dari perilaku "halus" ini adalah bahwa biasanya ada banyak interaksi antar objek, dengan banyak metode yang dipanggil.

Dalam satu ruang alamat, interaksi "halus" bekerja dengan baik, tetapi banyak hal berubah ketika ada interaksi antar proses. Panggilan jarak jauh lebih mahal karena banyak yang harus dilakukan: terkadang data perlu dipesan, pemeriksaan keamanan, paket perlu dialihkan ke sakelar. Jika dua proses beroperasi di ujung dunia yang berbeda, bahkan kecepatan cahaya pun dapat berperan. Kebenaran yang sulit adalah bahwa komunikasi antar-proses apa pun merupakan urutan besarnya lebih boros daripada panggilan dalam proses. Bahkan jika kedua proses berjalan di mesin yang sama. Dampak kinerja ini tidak dapat diabaikan, bahkan oleh pengoptimal yang malas.

Akibatnya, objek apa pun yang terlibat dalam remoting memerlukan antarmuka yang lebih umum yang memungkinkan meminimalkan jumlah permintaan yang diperlukan untuk melakukan sesuatu. Ini tidak hanya memengaruhi metode, tetapi juga objek. Alih-alih meminta faktur dan semua poinnya secara terpisah, Anda perlu membaca dan memperbarui semua poin faktur dalam satu panggilan. Ini mempengaruhi seluruh struktur objek. Kita harus melupakan tujuan baik dari benda kecil dan metode kecil. Pemrograman menjadi semakin sulit, produktivitas turun dan turun.

Pola Fasad Jarak Jauh adalah "Fasad" umum (menurut GoF) di atas struktur objek yang lebih "ditumbuk halus". Tak satu pun dari objek ini memiliki antarmuka jarak jauh, dan Remote Facade tidak menyertakan logika bisnis apa pun. Yang dilakukan Remote Facade hanyalah menerjemahkan permintaan umum ke dalam sekumpulan permintaan kecil ke objek subordinat.

Tujuan Pola Fasad

  • Pola Fasad menyediakan antarmuka terpadu alih-alih satu set antarmuka subsistem. Fasad mendefinisikan antarmuka tingkat tinggi yang membuat subsistem lebih mudah digunakan.
  • Pola Fasad membungkus subsistem yang kompleks dengan antarmuka yang lebih sederhana.

Masalah sedang dipecahkan

Pelanggan menginginkan antarmuka yang disederhanakan untuk fungsionalitas keseluruhan dari subsistem yang kompleks.

Diskusi pola fasad

Pola Fasad mengenkapsulasi subsistem kompleks dalam satu objek antarmuka. Hal ini mengurangi waktu yang diperlukan untuk mempelajari subsistem, dan juga membantu mengurangi tingkat penggabungan antara subsistem dan sejumlah besar klien yang berpotensi. Di sisi lain, jika fasad adalah satu-satunya titik akses ke subsistem, maka itu akan membatasi kemampuan yang mungkin dibutuhkan oleh pengguna "tingkat lanjut".

Objek Fasad yang mengimplementasikan fungsi mediator harus tetap sederhana dan tidak menjadi "oracle" mahatahu.

Struktur pola fasad

Klien berkomunikasi dengan subsistem melalui Fasad. Saat permintaan diterima dari klien, objek Facade meneruskannya ke komponen subsistem yang benar. Bagi pelanggan, komponen subsistem tetap menjadi "misteri yang diselimuti kegelapan".

Subsistem Satu dan Subsistem Tiga subsistem tidak berinteraksi langsung dengan internal subsistem Subsistem Dua. Mereka menggunakan "fasad" SubsystemTwoWrapper (yaitu abstraksi tingkat yang lebih tinggi).

Pola Fasad mendefinisikan antarmuka terpadu tingkat tinggi ke subsistem yang membuatnya lebih mudah digunakan. Pembeli menghadapi fasad saat memesan item katalog melalui telepon. Pembeli menelepon layanan pelanggan dan mencantumkan barang yang ingin mereka beli. Perwakilan layanan bertindak sebagai "fasad", menyediakan antarmuka ke departemen pemenuhan pesanan, penjualan, dan pengiriman.

  • Tentukan antarmuka yang sederhana dan terpadu untuk subsistem.
  • Rancang kelas pembungkus yang merangkum subsistem.
  • Semua kerumitan subsistem dan interaksi komponennya disembunyikan dari klien. "facade"/"wrapper" mengalihkan permintaan pengguna ke metode subsistem yang sesuai.
  • Klien hanya menggunakan "fasad".
  • Pertimbangkan kelayakan membuat "fasad" tambahan.

Fitur Pola Fasad

  • Fasad mendefinisikan antarmuka baru, sementara Adaptor menggunakan antarmuka yang sudah ada. Ingat, Adaptor membuat dua antarmuka yang ada berfungsi bersama tanpa membuat yang baru.
  • Jika Flyweight menunjukkan cara membuat banyak objek kecil, maka Fasad menunjukkan cara membuat satu objek yang mewakili seluruh subsistem.
  • Mediator mirip dengan Fasad karena mengabstraksi fungsionalitas kelas yang ada. Namun, Mediator memusatkan fungsionalitas antara objek peer yang bukan asli dari objek tersebut. Kolega bertukar informasi satu sama lain melalui Mediator. Di sisi lain, Facade mendefinisikan antarmuka sederhana ke subsistem, tidak menambahkan fungsionalitas baru, dan tidak diketahui oleh kelas subsistem.
  • Pabrik Abstrak dapat digunakan sebagai alternatif Fasad untuk menyembunyikan kelas asli.
  • Objek fasad seringkali Singleton karena hanya diperlukan satu objek Fasad.
  • Adaptor dan Fasad adalah "pembungkus", namun "pembungkus" ini berbeda jenis. Tujuan dari Facade adalah untuk membuat interface yang lebih sederhana, tujuan dari Adapter adalah untuk mengadaptasi interface yang sudah ada. Fasad biasanya "membungkus" beberapa objek, Adaptor "membungkus" satu objek.

Implementasi pola fasad

Memecah sistem menjadi komponen dapat mengurangi kerumitannya. Anda dapat melonggarkan ikatan antara komponen sistem menggunakan pola Fasad. Objek fasad menyediakan antarmuka tunggal yang disederhanakan ke komponen sistem.

Contoh di bawah mensimulasikan sistem layanan jaringan. Fasilitas Fasad Fasad menyembunyikan struktur internal sistem. Pengguna, setelah mengajukan permintaan layanan sekali, kemudian 1-2 kali seminggu selama 5 bulan menanyakan kemajuan pekerjaan sampai permintaannya dilayani sepenuhnya.

#termasuk kelas MisDepartment ( publik: void submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _state++; if (_state == Complete) return 1; return 0; ) private: enum States ( Received, DenyAllKnowledge, ReferClientToFacilities, FacilitiesHasNotSentPaperwork, ElectricianIsNotDone , ElectricianDidItWrong, DispatchTechnician, SignedOff, DoesNotWork, FixElectriciansWiring, Complete ); int _state; ); kelas ElectricianUnion ( publik: void submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _state++; if (_state == Complete) return 1; return 0; ) private: enum States ( Received, RejectTheForm, SizeTheJob, SmokeAndJokeBreak, WaitForAuthorization , DoTheWrongJob, BlameTheEngineer, WaitToPunchOut, DoHalfAJob, ComplainToEngineer, GetClarification, CompleteTheJob, TurnInThePaperwork, Complete ); int _state; ); class FacilitiesDepartment ( public: void submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _state++; if (_state == Complete) return 1; return 0; ) private: enum States ( Received, AssignToEngineer, EngineerResearches, RequestIsNotPossible, EngineerLeavesCompany , AssignToNewEngineer, NewEngineerResearches, ReassignEngineer,EngineerReturns, EngineerResearchesAgain, EngineerFillsOutPaperWork, Complete ); int _state; ); kelas FacilitiesFacade ( publik: FacilitiesFacade() ( _count = 0; ) batal submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _count++; /* Permintaan layanan diterima */ jika (_state == Diterima) ( _state++; / * Alihkan permintaan ke engineer */ _engineer.submitNetworkRequest(); cout<< "submitted to Facilities - " << _count << " phone calls so far" << endl; } else if (_state == SubmitToEngineer) { /* Если инженер свою работу выполнил, перенаправим запрос электрику */ if (_engineer.checkOnStatus()) { _state++; _electrician.submitNetworkRequest(); cout << "submitted to Electrician - " << _count << " phone calls so far" << endl; } } else if (_state == SubmitToElectrician) { /* Если электрик свою работу выполнил, перенаправим запрос технику */ if (_electrician.checkOnStatus()) { _state++; _technician.submitNetworkRequest(); cout << "submitted to MIS - " << _count << " phone calls so far" << endl; } } else if (_state == SubmitToTechnician) { /* Если техник свою работу выполнил, то запрос обслужен до конца */ if (_technician.checkOnStatus()) return 1; } /* Запрос еще не обслужен до конца */ return 0; } int getNumberOfCalls() { return _count; } private: enum States { Received, SubmitToEngineer, SubmitToElectrician, SubmitToTechnician }; int _state; int _count; FacilitiesDepartment _engineer; ElectricianUnion _electrician; MisDepartment _technician; }; int main() { FacilitiesFacade facilities; facilities.submitNetworkRequest(); /* Звоним, пока работа не выполнена полностью */ while (!facilities.checkOnStatus()) ; cout << "job completed after only " << facilities.getNumberOfCalls() << " phone calls" << endl; }

Keluaran program:

diserahkan ke Fasilitas - 1 panggilan telepon sejauh ini diajukan ke Teknisi Listrik - 12 panggilan telepon sejauh ini diajukan ke MIS - 25 panggilan telepon sejauh ini pekerjaan diselesaikan setelah hanya 35 panggilan telepon

11 Maret 2010 pukul 10.30

Pola desain "Fasad" / "Fasad"

  • Kode sempurna

Deskripsi pola lainnya.

Masalah

Minimalkan ketergantungan subsistem dari beberapa sistem yang kompleks dan pertukaran informasi di antara mereka.

Keterangan

Saat merancang sistem yang kompleks, yang disebut. prinsip dekomposisi, di mana sistem yang kompleks dibagi menjadi subsistem yang lebih kecil dan lebih sederhana. Apalagi tingkat dekomposisi (kedalamannya) ditentukan sendiri oleh perancangnya. Berkat pendekatan ini, masing-masing komponen sistem dapat dikembangkan secara terpisah, kemudian diintegrasikan bersama. Namun, masalah yang terlihat jelas pada pandangan pertama muncul - konektivitas modul sistem yang tinggi. Ini dimanifestasikan, pertama-tama, dalam sejumlah besar informasi yang dipertukarkan oleh modul satu sama lain. Selain itu, untuk komunikasi semacam itu, beberapa modul harus memiliki informasi yang cukup tentang sifat modul lainnya.

Dengan demikian, meminimalkan ketergantungan subsistem, serta mengurangi jumlah informasi yang dikirimkan di antara mereka, adalah salah satu tugas desain utama.

Salah satu cara untuk mengatasi masalah ini adalah dengan menggunakan pola Fasad.

Pola Fasad menyediakan antarmuka terpadu alih-alih satu set antarmuka subsistem. Fasad mendefinisikan antarmuka tingkat tinggi yang
ry menyederhanakan penggunaan subsistem.

Sederhananya, "Fasad" tidak lebih dari beberapa objek yang mengumpulkan serangkaian operasi tingkat tinggi untuk bekerja dengan beberapa subsistem kompleks. Fasad mengumpulkan kelas-kelas yang mengimplementasikan fungsionalitas subsistem ini, tetapi tidak menyembunyikannya. Penting untuk dipahami bahwa klien, pada saat yang sama, tidak kehilangan akses tingkat rendah ke kelas subsistem, jika, tentu saja, dia membutuhkannya. Fasad menyederhanakan beberapa operasi dengan subsistem, tetapi tidak memaksakan penggunaannya pada klien.

Tugas praktis

Menggunakan pola Fasad, kami menerapkan antarmuka terpadu ke beberapa subsistem otorisasi pengguna. Subsistem otorisasi itu sendiri (dalam contoh ini) tentu saja tidak berpura-pura menjadi "sistem yang kompleks", tetapi dengan jelas menampilkan keunggulan utama dari pola tersebut.

diagram kelas

Pertimbangkan sebuah diagram. Kerangka kerja subsistem otorisasi, untuk kejelasan, disorot dalam persegi panjang. Fasad Authorizator menyediakan antarmuka terpadu bagi klien untuk bekerja dengan subsistem. Dalam hal ini, hanya satu metode - otorisasi(), tetapi mungkin ada lebih banyak. Dalam hal ini, klien dapat menggunakan fasad untuk bekerja dengan subsistem, atau dapat langsung menggunakan kelas yang menyusunnya. Proses otorisasi itu sendiri cukup sederhana. Berdasarkan nama pengguna, entri terkait dicari di database menggunakan antarmuka DB. Kemudian, kata sandi dari entri yang ditemukan dibandingkan dengan kata sandi yang ditentukan oleh pengguna.

Implementasi dalam C#

Dalam kode implementasi TIDAK kelas PgSQLDB.
menggunakan Sistem;
menggunakan System.Collections.Generic ;
menggunakan System.Linq;
menggunakan Sistem.Teks;
menggunakan Sistem.Keamanan;

Fasad namespace
{
// Kelas pengguna abstrak
pengguna kelas abstrak
{
nama pengguna string yang dilindungi;
kata sandi string yang dilindungi;

string abstrak publik getUserRole();

string publik getPasswdHash()
{
// Baris ini tidak memuat beban semantik.
// Tentu saja, dengan cara ini kita mendapatkan hash kata sandi yang tidak aman
return passwd.GetHashCode().ToString();
}
}

// Spesifikasi pengguna sebagai pengguna default
kelas DefaultUser:User
{
DefaultUser publik (nama pengguna string, kata sandi string)
{
ini .username = nama pengguna;
this.passwd = sandi;
}


{
kembalikan "DEFAULT_USER" ;
}
}

// Klarifikasi pengguna, sebagai administrator
Administrator kelas: Pengguna
{
Administrator publik (nama pengguna string, kata sandi string)
{
ini .username = nama pengguna;
this.passwd = sandi;
}

string penimpaan publik getUserRole()
{
kembalikan "ADMINISTRATOR" ;
}

// Antarmuka akses basis data
antarmuka DB
{
pencarian pengguna(string nama pengguna);
}

// Implementasi antarmuka database untuk SQLite
kelas SQLiteDB: DB
{
SQLiteDB publik (nama file string)
{
// Inisialisasi driver database
}

pencarian Pengguna publik (string nama pengguna)
{
// Rintisan
lempar NotImplementedException baru();
}
}

// Otorisasi pengguna
otorisasi kekosongan publik (nama pengguna string, kata sandi string)
{
DB db = new SQLiteDB("db.sqlite" );
Pengguna pengguna = db.search(namapengguna);
jika (pengguna.getPasswdHash() == passwd)
{
// semuanya baik-baik saja, pengguna teridentifikasi
}
kalau tidak
{
// Ada yang salah
throw new SecurityException("Kata sandi atau nama pengguna salah!" );
}
}
}

Program kelas
{
static void Main(string args)
{
// Pengguna fiktif
string username = "Vasya" ;
string passwd = "qwerty" .GetHashCode().ToString();

Authorizer auth = new Authorizer();
mencoba
{
auth.otorisasi(nama pengguna, sandi);
}
tangkap(SecurityExceptionex)
{
// Pengguna tidak diautentikasi
}
}
}
}


* Kode sumber ini disorot dengan Penyorot Kode Sumber .

PS: Saya punya satu habraeditor tidak bekerja?

Sebelum membaca, harap baca , yang menjelaskan konvensi dan konsep yang diterima. Artikel ini dilengkapi dengan beberapa frekuensi, jadi jika Anda pernah membacanya sebelumnya, bukan fakta bahwa datanya tidak berubah.

Fasad (Fasad) milik kelas struktural pola. Mewakili antarmuka terpadu alih-alih satu set antarmuka dari beberapa subsistem. Pola fasad mendefinisikan antarmuka tingkat tinggi yang membuat subsistem lebih mudah digunakan.

Mempartisi sistem yang kompleks ke dalam subsistem menyederhanakan proses desain, dan juga membantu meminimalkan ketergantungan satu subsistem dengan subsistem lainnya. Namun, ini mengarah pada fakta bahwa menjadi sangat sulit untuk menggunakan subsistem tersebut bersama-sama. Salah satu cara untuk mengatasi masalah ini adalah dengan memperkenalkan pola fasad.

Ini adalah salah satu pola yang tidak memiliki implementasi yang jelas, karena bergantung pada sistem tertentu. Secara umum, kita perlu melakukan transformasi berikut:

Di kotak abu-abu adalah subsistem kami, yang memiliki beberapa ketergantungan di antara mereka sendiri (mungkin tidak ada). Tiga blok teratas menunjukkan tiga bagian dari kode klien yang berinteraksi dengan subsistem ini. Tugas kita adalah membuat antarmuka yang sederhana dan terpadu yang cukup untuk berinteraksi dengan subsistem dalam ruang lingkup tugas, itu. kita tidak perlu membuat antarmuka universal untuk semua kesempatan, karena dalam banyak kasus hal ini tidak diperlukan dan mengarah pada interaksi yang lebih kompleks, peningkatan waktu pengembangan.

Di bawah ini adalah sketsa salah satu implementasinya:

/** * SystemA */ class Bank ( public function OpenTransaction() () public function CloseTransaction() () public function transferMoney($amount) () ) /** * SystemB */ class Client ( public function OpenTransaction() ( ) fungsi publik CloseTransaction() () fungsi publik transferMoney($jumlah) () ) /** * SystemC */ Log kelas ( fungsi publik logTransaksi() () ) Fasad kelas ( transfer fungsi publik($jumlah) ( $Bank = Bank baru(); $Klien = Klien baru(); $Log = Log baru(); $Bank->OpenTransaction(); $Klien->OpenTransaction(); $Log->logTransaction("Transaksi terbuka"); $ Bank->transferMoney(-$amount); $Log->logTransaction("Transfer uang dari bank"); $Client->transferMoney($amount); $Log->logTransaction("Transfer uang ke klien"); $Bank ->CloseTransaction(); $Client->CloseTransaction(); $Log->logTransaction("Transaction close"); ) ) // Kode klien $Transfer = new Facade(); $transfer->transfer(1000);

Tatapan.

Jenis

Pola desain struktur (Structural).

Keterangan

Pola Fasad mengelompokkan sekelompok objek dalam satu antarmuka khusus dan meneruskan pemanggilan metodenya ke objek tersebut.

Templat digunakan jika perlu:

  • menyederhanakan akses ke sistem yang kompleks;
  • (atau) membuat berbagai tingkat akses ke sistem;
  • (atau) mengurangi jumlah ketergantungan antara sistem dan klien.

Pertama-tama, kita perlu mengklarifikasi bahwa antarmuka yang disediakan template bukanlah jumlah dari semua metode objek yang termasuk dalam sistem. Membuat versi umum seperti itu akan mengarah pada munculnya "antarmuka ilahi". Itu. antarmuka dengan sejumlah besar metode, tanpa tujuan yang jelas dan menghasilkan banyak ketergantungan. Akibatnya, hasilnya berlawanan langsung dengan polanya.

Tujuan dari Fasad adalah untuk membuat antarmuka yang berisi metode untuk memecahkan masalah tertentu atau memberikan abstraksi spesifik dari sistem aslinya. Dalam hal ini, berikut ini mungkin:

  • meneruskan panggilan antarmuka templat ke objek sistem;
  • mengurangi jumlah parameter metode dengan mengganti nilai yang telah ditentukan sebelumnya;
  • pembuatan metode baru yang menggabungkan panggilan ke objek sistem dan/atau menambahkan logikanya sendiri;
  • beberapa metode dan properti asli tidak dapat diakses melalui Fasad, karena tidak berperan dalam memecahkan masalah.

Pendekatan ini menyederhanakan penggunaan sistem yang kompleks. Pada saat yang sama, ini mengurangi jumlah metode yang dipanggil dan jumlah total panggilannya. Hasilnya adalah pengurangan jumlah dependensi dalam aplikasi.

Penting untuk diperhatikan bahwa Facade tidak mengharuskan Anda menyembunyikan objek yang digunakan oleh sistem. Tetapi ada satu syarat penting: bagian klien, yang untuknya antarmuka Facade dibuat, harus menggunakannya saja dan tidak mengakses objek sistem secara langsung. Ini berkontribusi pada refleksi tugas klien yang lebih akurat di antarmuka.

Selain itu, sistem dapat menyediakan beberapa Fasad untuk menyelesaikan berbagai macam tugas. Ini memungkinkan Anda untuk membuat beberapa level abstraksi, yang bisa berada di atas yang lain, atau berada di bidang yang sama. Klien dapat menggunakan Fasad tertentu untuk pekerjaan mereka, atau bekerja dengan objek tertentu secara langsung.

Pilihan yang menarik adalah berbagi template Fasad dan Pabrik Abstrak. Dalam hal ini, antarmuka Fasad tidak dikaitkan dengan objek itu sendiri, tetapi dengan antarmukanya. Ini menyembunyikan implementasi dan memberi Pabrik Abstrak kemampuan untuk memodifikasinya. Pendekatan ini dapat ditemukan, misalnya, ketika sistem menggunakan kelas khusus platform atau perangkat keras.

Template serupa dan perbedaannya

Tatapan Menyatukan sekelompok objek di bawah satu antarmuka khusus. Menyederhanakan pekerjaan dengan sekelompok objek, memperkenalkan tingkat abstraksi baru. Berisi atau merujuk ke objek yang diperlukan untuk mengimplementasikan antarmuka khusus.
Adaptor Mengubah antarmuka objek tanpa mengubah fungsinya. Dapat mengadaptasi banyak objek ke antarmuka yang sama. Memungkinkan Anda untuk menggunakan kembali kode yang ada. Berisi atau mewarisi objek yang dapat diadaptasi.
Menjembatani Memisahkan objek menjadi abstraksi dan implementasi. Digunakan untuk hierarki objek. Memungkinkan Anda mengubah (mewarisi) abstraksi dan implementasi secara terpisah, meningkatkan fleksibilitas sistem. Berisi objek (implementasi) yang menyediakan metode untuk abstraksi yang diberikan dan penyempurnaannya (pewaris).
Penghias Memperluas kemampuan suatu objek, mengubah perilakunya. Mempertahankan antarmuka objek yang sedang didekorasi, tetapi dapat menambahkan metode dan properti baru. Memberikan kemampuan untuk secara dinamis mengubah fungsionalitas suatu objek. Ini adalah alternatif untuk pewarisan (termasuk pewarisan berganda). Berisi objek yang akan dihias. Rangkaian objek yang dipanggil secara berurutan dimungkinkan.
Proksi Secara transparan mengganti objek dan mengontrol akses ke sana. Tidak mengubah antarmuka atau perilaku. Menyederhanakan dan mengoptimalkan pekerjaan dengan objek. Dapat menambahkan fungsinya sendiri, menyembunyikannya dari klien. Berisi objek atau referensi untuk itu, dapat mengontrol keberadaan objek yang diganti.
Penghubung Menyediakan antarmuka tunggal untuk berinteraksi dengan objek komposit dan bagian-bagiannya. Menyederhanakan pekerjaan klien, memungkinkan Anda dengan mudah menambahkan opsi baru untuk objek komposit dan bagiannya. Itu disertakan sebagai antarmuka dalam objek komposit dan bagian-bagiannya.
oportunis

Itu tidak bertujuan untuk mengubah antarmuka suatu objek. Tetapi mungkin diperlukan untuk mendapatkan kembali data dari bagian negara bagian yang dirender.

Memungkinkan Anda mengurangi jumlah instance objek dalam aplikasi dan dengan demikian menghemat sumber dayanya. Memunculkan bagian peka konteks dari status objek, menggantikan beberapa instance-nya dengan satu.

Secara terpisah, kami memikirkan dua pola yang sangat mirip - Fasad dan Adaptor, menggunakan beberapa objek yang dapat disesuaikan. Mungkin timbul pertanyaan: apa bedanya? Perhatikan tujuan mereka. Jika gabungan objek digunakan untuk mengimplementasikan antarmuka yang ada dan menggunakan kembali kode, maka itu adalah Adaptor. Menyoroti esensi tugas, menyederhanakan operasi, munculnya antarmuka baru - semua ini adalah tanda Fasad.

Omong-omong, dalam situasi nyata, pola harus diterapkan berdasarkan tujuan, bukan "kesamaan". Oleh karena itu, pertanyaan seperti itu hanya dapat muncul selama penelitian.

Penerapan template secara umum

Pendekatan berikut untuk implementasi template dimungkinkan:

  1. Membuat kelas terpisah yang merujuk ke instance sistem. Ini adalah versi klasik dan penerapannya disorot dengan jelas, karena adalah entitas yang terpisah. public class FacadeImpl: IFacade ( private AppSubSystem _system; public FacadeImpl(AppSubSystem s) ( this._system = s; ) /* Skipped */ ) Atau, instance sistem dapat dibuat di dalam Facade: public class FacadeImpl: IFacade ( private readonly AppSubSystem _system = new AppSubSystem(); /* Dilewati */ )
  2. Menambahkan antarmuka Fasad ke sistem. Ini bisa berguna jika Fasad memiliki banyak klien dan tidak masuk akal bagi masing-masing klien untuk membuat instance penerapan template sendiri. AppSubSystem kelas publik ( public IFacade FacadeInterface ( get; set pribadi; ) AppSubSystem publik () ( this.FacadeInterface = new FacadeImpl(this); ) /* Skipped */ )
  3. Dukungan antarmuka fasad di kelas sistem itu sendiri, menggunakan pewarisan. Implementasinya "kabur" menurut sistem. Namun, contoh sekarang dapat digunakan di mana antarmuka Façade diperlukan. Selain itu, dimungkinkan untuk mengakses bidang pribadi dan metode sistem, dan tidak perlu mengalihkan panggilan ke metode yang sama. AppSubSystem kelas publik: IFacade ( /* Skipped */ )

Semua pendekatan ini dapat ditulis sebagai berikut:

  • kami menentukan fungsi tugas yang dialokasikan atau abstraksi baru;
  • mengoordinasikannya dengan objek yang ada dalam sistem;
  • mengembangkan antarmuka template ;
  • melaksanakan di salah satu opsi:
    • kelas terpisah yang meneruskan panggilan ke objek sistem;
    • di kelas sistem itu sendiri;
  • klien, alih-alih berinteraksi dengan banyak kelas, bekerja dengan satu antarmuka baru.

Contoh implementasi

Mari kita lihat contoh membuat editor posting blog sederhana dalam sistem manajemen konten. Mari buat daftar objek apa yang akan menjadi bagian dari subsistem ini. Otorisasi dan metode tidak penting lainnya untuk contoh akan dihapus untuk singkatnya.

Mari kita mulai dengan yang dasar, postingan blog yang diwakili oleh kelas posting blog. Kelas ini menyimpan properti dan konten dari satu entri.

BlogPost kelas publik( ///

Mendapat atau mengatur properti posting. Properti BlogPostProperties publik ( get; set; ) /// Mendapat atau mengatur konten posting. Konten BlogPostContent publik ( dapatkan; atur; ))

Kelas selanjutnya BlogPostStorage- penyimpanan untuk entri blog di server. Ini memungkinkan Anda untuk mengatur data otorisasi, mengunggah dan menerbitkan entri.

BlogPostStorage kelas publik( ///

string publik Server ( dapatkan; atur; ) /// Mendapat atau mengatur login blogger. string publik Login ( dapatkan; set; ) /// Mendapat atau menetapkan kata sandi blogger. kata sandi string publik ( dapatkan pribadi; set; ) /// /// Tanggal mulai. /// tanggal akhir. /// Daftar publik GetPostList(DateTime startDate, DateTime endDate) ( /* Dilewati */ ) /// Mendapat postingan yang terkait dengan id yang ditentukan. /// ID postingan yang akan diambil. /// Contoh untuk id. publik BlogPost GetPost(int postId) ( /* Dilewati */ ) /// Menghapus postingan yang terkait dengan id yang ditentukan. /// ID postingan yang akan dihapus. public void DeletePost(int postId) ( /* Dilewati */ ) /// Menerbitkan posting yang ditentukan. /// Posting untuk diterbitkan. public void Publish(Posting BlogPost) ( /* Dilewati */ ) )

Ada kelas sederhana untuk memeriksa ejaan SimpleSpellChecker.

SimplepellChecker kelas publik( ///

Memeriksa kata untuk kesalahan ejaan. /// Kata untuk memeriksa. /// Saat metode ini kembali, berisi saran /// untuk kata yang ditentukan. /// benar pada kata yang benar; jika tidak, salah public bo Check (string word, out List saran) ( /* Dilewati */ ) )

Dan komponen terakhir adalah editor teks. Kami akan menghapus hampir semua metodenya untuk singkatnya.

PostEditor kelas publik( ///

Pemeriksa ejaan. pribadi readonly SimpleSpellChecker _spellChecker = new SimpleSpellChecker(); /// publik bool IsSpellCheckComplete ( dapatkan; set pribadi; ) /// Mendapat atau menyetel postingan untuk diedit. Posting BlogPost publik ( dapatkan; atur; ) /// Mendapatkan properti pos. Public BlogPostProperties PostProperties ( dapatkan ( if (this.Post == null) ( return null; ) kembalikan this.Post.Properties; ) ) /// Mendapat konten posting. Publik BlogPostContent PostContent ( dapatkan ( if (this.Post == null) ( return null; ) kembalikan this.Post.Content; ) ) )

Mari beralih ke editor posting blog. Subsistemnya akan terlihat seperti ini:

BlogEditor kelas publik (BlogPostStorage _storage hanya baca pribadi = BlogPostStorage baru(); Penyimpanan BlogPostStorage publik ( dapatkan ( kembalikan this._storage; ) ) PostEditor _editor hanya baca pribadi = PostEditor baru(); Editor PostEditor publik ( dapatkan ( kembalikan ini._editor; ) ) )

Klien dapat menggunakan objek ini secara langsung. Tapi apakah dia membutuhkannya? Jika diperhatikan dengan seksama, ternyata dibutuhkan fungsi-fungsi berikut ini:

  • tentukan detail untuk masuk ke server: server, Gabung, Kata sandi;
  • memuat daftar rekaman: DapatkanPostList();
  • unggah postingan untuk diedit: LoadPost();
  • dapatkan properti entri dan teksnya: PostProperties, memposting konten;
  • pastikan ejaan entri dicentang: IsSpellCheckComplete;
  • pos pos: Menerbitkan();
  • hapus entri: HapusPost().

Semua ini dapat ditulis sebagai antarmuka untuk Fasad:

Antarmuka publik IBlogEditorFacade( ///

Mendapat atau menetapkan alamat server. string Server ( dapatkan; atur; ) /// Mengatur login blogger. string Masuk ( set; ) /// Menetapkan kata sandi blogger. string Kata Sandi ( set; ) /// Mendapat nilai yang menunjukkan apakah pemeriksaan ejaan selesai. bool IsSpellCheckComplete ( dapatkan; ) /// Mendapat properti posting saat ini. BlogPostProperties PostProperties ( dapatkan; ) /// Mendapat konten posting saat ini. BlogPostContent PostContent ( dapatkan; ) /// Mengembalikan daftar yang mewakili kumpulan posting di server /// untuk jangka waktu tertentu. /// Tanggal mulai. /// tanggal akhir. /// Daftar yang mewakili kumpulan postingan di server. Daftar GetPostList(DateTime startDate, DateTime endDate); /// Memuat pos yang ditentukan. /// ID postingan yang akan diambil. batal LoadPost(int postId); /// Menerbitkan posting saat ini ke blog. batal Publikasikan(); /// Menghapus posting yang ditentukan. /// ID postingan yang akan dihapus. batal HapusPost(int postId); )

Mari terapkan antarmuka ini. Metode dan properti yang dihasilkan cukup sederhana. Mereka hanya mengarahkan permintaan ke objek yang benar dalam sistem. Oleh karena itu, kami akan mengurangi kode di atas untuk singkatnya. kita hanya akan meninggalkan konstruktor, dan masing-masing satu properti dan satu metode.

BlogEditorFacade kelas publik: IBlogEditorFacade ( BlogEditor pribadi _blogEditor; ///

Menginisialisasi instance baru dari /// kelas. /// Referensi ke instance editor blog. public BlogEditorFacade(BlogEditor blogEditor) ( if (blogEditor == null) ( throw new ArgumentNullException("blogEditor can"t be null"); ) this._blogEditor = blogEditor; ) public string Server ( dapatkan ( kembalikan this._blogEditor.Storage. Server; ) atur ( this._blogEditor.Storage.Server = value; ) ) public void LoadPost(int postId) ( BlogPost post = this._blogEditor.Storage.GetPost(postId); if (post != null) ( this._blogEditor .Editor.Post = post;) ) /* implementasi IBlogEditorFacade dilewati */ )

Konstruktor kelas menentukan instance sistem yang harus disediakan aksesnya oleh Fasad. Kode klien sekarang dapat menggunakan antarmuka untuk membuatnya lebih mudah diakses:

BlogClient kelas publik ( IBlogEditorFacade _blogEditor = null; public BlogClient(IBlogEditorFacade iBlogEditor) ( this._blogEditor = iBlogEditor; ) public bool ValidateAndPublish() ( bool isPostValid = true; Konten BlogPostContent = this._blogEditor.PostContent; /// TODO: Validasi konten jika (isPostValid) ( this._blogEditor.Publish(); ) kembalikan isPostValid; ) )

Penggunaan BlogClient sebagai berikut:

BlogEditor blogEditorObject = new BlogEditor(); /// ... BlogClient blogClient = BlogClient baru(BlogEditorFacade baru(blogEditorObject));

Perhatikan bahwa antarmuka diteruskan ke konstruktor Fasad. Selain itu, membuat objek sistem ( editor blog) dikeluarkan dari implementasi template.

Dengan demikian, klien hanya menggunakan antarmuka yang dibuat untuk bekerja dengan sistem. Ketergantungan implementasi template pada implementasi sistem juga telah berkurang. Memang, bukan contoh editor blog salah satu keturunannya dapat diwariskan.

Namun, dalam beberapa kasus lebih bermanfaat untuk membuat objek di dalam template itu sendiri. Misalnya, agar setiap instance Facade memiliki instance sistemnya sendiri atau, jika perlu, menyembunyikan sistem yang digunakan dari klien.

Kembali ke contoh yang sedang dipertimbangkan, dapat dicatat bahwa interaksi dengan sistem menjadi lebih mudah. Jumlah metode dan pemanggilan metode pada objeknya telah berkurang. Tujuan penerapan template telah tercapai.