paint-brush
11 Pola Desain Utama: Panduan Pentingoleh@ssukhpinder
1,424 bacaan
1,424 bacaan

11 Pola Desain Utama: Panduan Penting

oleh Sukhpinder Singh33m2024/09/08
Read on Terminal Reader

Terlalu panjang; Untuk membaca

Ungkap rahasia arsitektur perangkat lunak dengan *Mastering Software Architecture: 11 Key Design Patterns Explained*. Buku ini ditulis dalam bahasa pemrograman C# C# 8.0. Ada 11 pola desain yang dapat digunakan untuk membuat pabrik. Pola pabrik abstrak merupakan metode pabrik tambahan; disarankan untuk mempelajari metode pabrik.
featured image - 11 Pola Desain Utama: Panduan Penting
Sukhpinder Singh HackerNoon profile picture
0-item
1-item
2-item
3-item
4-item

Ungkap rahasia arsitektur perangkat lunak dengan Menguasai Arsitektur Perangkat Lunak: 11 Pola Desain Utama Dijelaskan .

Daftar isi

  1. Pola Desain — Pabrik Abstrak
  • Tujuan pembelajaran
  • Memulai
  • Bagaimana cara menggunakan penyedia pabrik abstrak?
  • Keluaran

2. Pola Desain — Adaptor

  • Kasus Penggunaan
  • Tujuan pembelajaran
  • Memulai

3. Pola Desain — Pembangun

  • Kasus Penggunaan
  • Tujuan pembelajaran
  • Memulai
  • Cara menggunakan pola pembangun dari metode Main()
  • Keluaran

4. Cara Menggunakan Pola Rantai Tanggung Jawab

  • Kasus Penggunaan
  • Memulai
  • Bagaimana cara menggunakan pola Rantai Tanggung Jawab?
  • Keluaran

5. Pola Desain — Dekorator

  • Kasus Penggunaan
  • Tujuan pembelajaran
  • Memulai
  • Pola Dekorator sedang beraksi
  • Kode Lengkap
  • Keluaran

6. Pola Desain — Metode Pabrik

  • Tujuan pembelajaran
  • Memulai
  • Bagaimana cara menggunakan metode pabrik?
  • Keluaran

7. Pola Desain — Iterator

  • Kasus Penggunaan
  • Memulai
  • Pola Iterator dalam Aksi
  • Keluaran

8. Pola Desain — Mediator

  • Kasus Penggunaan
  • Tujuan pembelajaran
  • Memulai
  • Cara menggunakan pola mediator dari metode utama

9. Pola Desain — Pengamat

  • Kasus Penggunaan
  • Tujuan pembelajaran
  • Memulai
  • Bagaimana cara menggunakan pola pengamat?
  • Keluaran

10. Pola Properti Lanjutan C# 8.0

  • Ayo Mulai
  • Program pencocokan pola dengan sintaks sakelar baru
  • Program pengujian
  • Keluaran Konsol

11. Pola Desain — Singleton

  • Tujuan pembelajaran
  • Memulai
  • Keluaran
  • Keamanan Benang

Pola Desain — Pabrik Abstrak

Menurut Gang of Four, pola pabrik abstrak dapat diasumsikan sebagai pabrik untuk menciptakan pabrik.


Tujuan pembelajaran

  • Apa pola desain pabrik abstrak?
  • Bagaimana cara menulis kode menggunakan pola desain pabrik abstrak?
  • Bagaimana cara membuat penyedia pabrik?
  • Cara membuat aplikasi klien (dari metode Utama) yang menggunakan penyedia pabrik

Prasyarat

Pola pabrik abstrak hanyalah perluasan metode pabrik; sebaiknya pelajari metode pabrik sebelum memahami desain pabrik abstrak.

  • Pengetahuan dasar tentang konsep OOPS.
  • Pengetahuan bahasa pemrograman apa pun.

Memulai

Mari kita pertimbangkan contoh yang sama dari Bank mana pun dengan jenis akun seperti rekening Tabungan dan Giro. Sekarang, mari kita terapkan contoh di atas menggunakan pola desain pabrik abstrak.


Pertama, terapkan antarmuka ISavingAccount dan ICurrentAccount sebagai berikut:


 public interface ISavingAccount{ } public interface ICurrentAccount{ }


Mewarisi antarmuka di kelas di bawah ini


 public class CurrentAccount : ICurrentAccount { public CurrentAccount(string message) { Console.WriteLine(message); } } public class SavingsAccount : ISavingAccount { public SavingsAccount( string message) { Console.WriteLine(message); } }


Mari menulis kelas abstrak dengan metode abstrak untuk setiap jenis akun.


 public abstract class AccountTypeFactory { public abstract ISavingAccount SavingAccountFactory(string message); public abstract ICurrentAccount CurrentAccountFactory(string message); }


Sekarang, mari kita buat implementasi pabrik bernama “Bank1Factory,” yang menyediakan implementasi metode abstrak.


 public class Bank1Factory : AccountTypeFactory { public override ICurrentAccount CurrentAccountFactory(string message) { return new CurrentAccount(message); } public override ISavingAccount SavingAccountFactory(string message) { return new SavingsAccount(message); } }


Pola desain pabrik abstrak berbeda dari metode pabrik yang perlu menerapkan penyedia pabrik, yang mengembalikan pabrik sesuai definisi.


Sekarang setelah kita membuat semua abstraksi dan pabrik. Mari kita rancang penyedia pabrik. Berikut ini cuplikan kode untuk penyedia pabrik, di mana metode statis akan membuat pabrik berdasarkan nama akun.


 public class AccountFactoryProvider { public static AccountTypeFactory GetAccountTypeFactory(string accountName) { if (accountName.Contains("B1")) { return new Bank1Factory(); } else return null; } }

Bagaimana Cara Menggunakan Penyedia Pabrik Abstrak?

Mari kita ambil contoh daftar nomor akun, jika nama akunnya secara harfiah terdiri dari “ B1 ”, maka ia akan menggunakan instance Bank1Factory yang dikembalikan melalui penyedia pabrik.

 static void Main(string[] args) { List<string> accNames = new List<string> { "B1-456", "B1-987", "B2-222" }; for (int i = 0; i < accNames.Count; i++) { AccountTypeFactory anAbstractFactory = AccountFactoryProvider.GetAccountTypeFactory(accNames[i]); if (anAbstractFactory == null) { Console.WriteLine("Invalid " + (accNames[i])); } else { ISavingAccount savingAccount = anAbstractFactory.SavingAccountFactory("Hello saving"); ICurrentAccount currentAccount = anAbstractFactory.CurrentAccountFactory("Hello Current"); } } Console.ReadLine(); }


Jika nama akun tidak mengandung literal “B1”, maka program akan mengeluarkan {{accountName}} yang tidak valid

Keluaran

Berikut ini adalah output dari potongan kode di atas.


 Hello saving B1-456 Hello Current B1-456 Hello saving B1-987 Hello Current B1-987

Pola Desain — Adaptor

Menurut Gang of Four, Pola Adaptor mengubah antarmuka suatu kelas menjadi antarmuka yang dibutuhkan klien.


Dengan kata lain, pola desain adaptor membantu antarmuka yang tidak kompatibel bekerja secara kolektif.

Kasus Penggunaan

Mari kita pertimbangkan contoh penggabungan dua organisasi; organisasi X mengambil alih Y, tetapi saat menggabungkan kode, antarmukanya tidak kompatibel. Asumsikan bahwa antarmuka yang menyediakan daftar transaksi organisasi Y tidak kompatibel dengan X.


Jadi, pola desain adaptor membantu memecahkan masalah ini dengan implementasi yang sangat mudah.

Tujuan pembelajaran

  • Bagaimana cara membuat kode menggunakan pola desain adaptor?

Memulai

Mari buat daftar transaksi dari organisasi Y yang dikonversi ke pola yang dibutuhkan aplikasi klien organisasi X. Kelas di atas dikenal sebagai "Adaptee".


 public class OrgYTransactions { public List<string> GetTransactionsList() { List<string> transactions = new List<string>(); transactions.Add("Debit 1"); transactions.Add("Debit 2"); transactions.Add("Debit 3"); return transactions; } }


Kedua, mari kita buat antarmuka target.


 public interface ITransactions{ List<string> GetTransactions(); }


Sekarang akhirnya, mari kita implementasikan kelas adaptor sebagai berikut.


 public class TransAdapter : OrgYTransactions, ITransactions { public List<string> GetTransactions() { return GetTransactionsList(); } }


Setelah semua implementasi di atas selesai, mari kita pahami cara menggunakan kelas adaptor dalam aplikasi konsol.


 class Program { static void Main(string[] args) { ITransactions adapter = new TransAdapter(); foreach (var item in adapter.GetTransactions()) { Console.WriteLine(item); } } }


Jika Anda perhatikan dengan seksama penggunaan di bawah ini, kami telah menggunakan antarmuka target ITransactions dan kelas adaptor TransAdapter tanpa mempertimbangkan tampilan antarmuka kelas pihak ketiga OrgYTransactions. Itulah kekuatan pola desain adaptor yang mengubah antarmuka kelas menjadi antarmuka yang dibutuhkan klien.

Pola Desain — Pembangun

Menurut Gang of Four, pola kreasi “Builder” memungkinkan seseorang untuk memisahkan dan menggunakan kembali metode tertentu untuk membangun sesuatu.


Kasus Penggunaan

Mari kita ambil contoh Mobil, dan pengguna ingin membangun dua model, yaitu SUV dan Sedan.


Pola desain pembangun berguna dalam kasus penggunaan di atas, dan mari kita lihat demonstrasinya langkah demi langkah.


Kelas Mobil memiliki properti berikut.

 public class Car{ public string Name { get; set; } public double TopSpeed { get; set; } public bool IsSUV { get; set; } }

Tujuan pembelajaran

  • Bagaimana cara membuat kode menggunakan pola desain pembangun?

Memulai

Pertama, mari terapkan pembangun kelas abstrak yang diperluas oleh berbagai model mobil seperti SUV atau sedan sesuai kasus penggunaan.


 public abstract class CarBuilder { protected readonly Car _car = new Car(); public abstract void SetName(); public abstract void SetSpeed(); public abstract void SetIsSUV(); public virtual Car GetCar() => _car; }


Kelas abstrak terdiri dari metode berikut

  • Metode abstrak untuk setiap properti kelas Mobil.
  • Metode virtual yang mengeluarkan instance kelas Mobil.


Sekarang, mari kita membuat pabrik yang memanfaatkan kelas CarBuilder untuk membuat berbagai model mobil dan mengembalikan contoh mobil yang dibuat.


 public class CarFactory { public Car Build(CarBuilder builder) { builder.SetName(); builder.SetSpeed(); builder.SetIsSUV(); return builder.GetCar(); } }


Terakhir, terapkan model mobil yang berbeda.

ModelSuv.cs

 public class ModelSuv : CarBuilder { public override void SetIsSUV() { _car.IsSUV = true; } public override void SetName() { _car.Name = "Maruti SUV"; } public override void SetSpeed() { _car.TopSpeed = 1000; } }

ModelSedan.cs

 public class ModelSedan : CarBuilder { public override void SetIsSUV() { _car.IsSUV = false; } public override void SetName() { _car.Name = "Maruti Sedan"; } public override void SetSpeed() { _car.TopSpeed = 2000; } }

Cara Membuat Pola Pembangun Pengguna Dari Metode Main()

Terakhir, mari kita gunakan pola desain untuk membangun model mobil yang berbeda dengan bantuan metode factory.Build(<model>).


 static void Main(string[] args) { var sedan = new ModelSedan(); var suv = new ModelSuv(); var factory = new CarFactory(); var builders = new List<CarBuilder> { suv, sedan }; foreach (var b in builders) { var c = factory.Build(b); Console.WriteLine($"The Car details" + $"\n--------------------------------------" + $"\nName: {c.Name}" + $"\nIs SUV: {c.IsSUV}" + $"\nTop Speed: {c.TopSpeed} mph\n"); } }

Penggunaan di atas menunjukkan betapa bagusnya kita dapat membangun berbagai model mobil menggunakan pola desain pembangun.


Pola kode sangat mudah dirawat & diperluas. Jika di masa mendatang kita perlu mengembangkan model baru, cukup model baru tersebut yang perlu memperluas kelas CarBuilder, dan selesai.

Keluaran

Cara Menggunakan Pola Rantai Tanggung Jawab

Menurut Gang of Four, hal ini mendefinisikan rantai tanggung jawab untuk memproses permintaan. Dengan kata lain, meneruskan permintaan dari satu objek ke objek lain hingga objek tersebut menerima tanggung jawabnya.


Kasus Penggunaan

Mari kita pertimbangkan contoh sistem klaim di perusahaan korporat mana pun. Berikut adalah daftar kisaran harga yang dapat disetujui dan oleh siapa.


 100–1000 Rs => Junior/Senior Engineers => Approved by Manager 1001–10000 Rs => Managers => Approved by Senior Manager


Jika jumlahnya di luar kisaran 10.000, diperlukan persetujuan luar biasa dari manajer senior.


Kasus penggunaan di atas dapat dengan mudah diimplementasikan menggunakan pola desain Rantai Tanggung Jawab. Jadi, kelas klaim memiliki properti berikut.


 public class Claim{ public int Id{get;set;} public double amount{get;set;} }

Memulai

Pertama, mari kita definisikan fungsi apa yang dapat dilakukan oleh pemberi persetujuan klaim dan tetapkan hierarki untuk karyawan di berbagai tingkatan. Terapkan kelas abstrak seperti yang ditunjukkan di bawah ini


 public abstract class ClaimApprover { protected ClaimApprover claimApprover; public void SetHierarchy(ClaimApprover claimApprover) { this.claimApprover = claimApprover; } public abstract void ApproveRequest(Claim claim); }


Sesuai kasus penggunaan, mari kita kendalikan pemohon klaim kelas "junior/senior". Perhatikan bahwa kelas/jabatan karyawan ini tidak dapat menyetujui klaim apa pun.


 public class Junior : ClaimApprover { public override void ApproveRequest(Claim claim) { System.Console.WriteLine("Cannot approve"); } }


Demikian pula, mari kita definisikan implementasi untuk peran Manajer dan Manajer Senior.


 public class Manager : ClaimApprover { public override void ApproveRequest(Claim claim) { if (claim.amount >= 100 && claim.amount <= 1000) { System.Console.WriteLine($"Claim reference {claim.Id} with amount {claim.amount} is approved by Manager"); } else if (claimApprover != null) { claimApprover.ApproveRequest(claim); } } }


Perhatikan bahwa berdasarkan rentang jumlah, jika dalam rentang Manajer, klaim dapat disetujui oleh Manajer; jika tidak, permintaan akan diteruskan ke Manajer Senior.


 public class SeniorManager : ClaimApprover { public override void ApproveRequest(Claim claim) { if (claim.amount > 1000 && claim.amount <= 10000) { System.Console.WriteLine($"Claim reference {claim.Id} with amount {claim.amount} is approved by Senior Manager"); } else { System.Console.WriteLine($"Exceptional approval for Claim reference {claim.Id} with amount {claim.amount} is approved by Senior Manager"); } } }


Demikian pula, jika rentang jumlahnya berada dalam rentang Manajer Senior, klaim dapat disetujui oleh Manajer; jika tidak, karena berada pada hierarki terakhir, persetujuan luar biasa dilakukan untuk jumlah di luar rentang tersebut.


 ClaimApprover junior = new Manager(); ClaimApprover sukhpinder = new Manager(); ClaimApprover singh = new SeniorManager(); junior.SetHierarchy(sukhpinder); sukhpinder.SetHierarchy(singh); Claim c1 = new Claim() { amount = 999, Id = 1001 }; Claim c2 = new Claim() { amount = 10001, Id = 1002 }; junior.ApproveRequest(c1); sukhpinder.ApproveRequest(c2);

Bagaimana Cara Menggunakan Pola Rantai Tanggung Jawab?

  1. Tetapkan pemberi persetujuan klaim: junior, meskipun tidak dapat menyetujui klaim apa pun.
  2. Tentukan pemberi persetujuan klaim: manajer “sukhpinder.”
  3. Tentukan pemberi persetujuan klaim: manajer senior “Singh.”
  4. Siapkan hubungan hierarki untuk junior, yaitu, pemberi persetujuan klaim adalah manajer.
  5. Siapkan hubungan hierarki untuk manajer, yaitu, pemberi persetujuan klaim adalah manajer senior.
  6. Buat dua rentang klaim yang berbeda.
  7. Junior mengirimkan permintaan klaim ke manajer.
  8. Manajer mengirimkan permintaan klaim kepada manajer senior.

Keluaran

 Claim reference 1001 with amount 999 is approved by Manager Exceptional approval for Claim reference 1002 with amount 10001 is approved by Senior Manager


Untuk keluaran baris 1, jumlahnya berada dalam kisaran, jadi manajer menyetujuinya.


Untuk keluaran lini 2, meskipun manajer senior menyetujuinya, jumlahnya berada di luar kisaran.

Pola Desain — Dekorator

Menurut Gang of Four, pola menambahkan tanggung jawab ekstra pada objek kelas secara dinamis.


Kasus Penggunaan

Mari kita pertimbangkan contoh pembelian mobil senilai sepuluh lakh; perusahaan menyediakan fitur tambahan berikut.

  • Atap matahari
  • Sistem Musik Mutakhir
  • dan masih banyak lagi


Dengan beberapa fitur tambahan, total harga mobil meningkat. Mari kita terapkan kasus penggunaan di atas menggunakan Pola Dekorator.

Tujuan pembelajaran

  • Bagaimana cara membuat kode menggunakan pola desain dekorator?

Memulai

Mari kita terapkan kasus penggunaan yang dijelaskan di atas. Pertama, definisikan kelas abstrak Car dan metode dasarnya.


 public abstract class Car{ public abstract int CarPrice(); public abstract string GetName(); }


Pertimbangkan sebuah mobil kecil yang berada di atas kelas abstrak Mobil.


 public class SmallCar : Car{ public override int CarPrice() => 10000; public override string GetName() => "Alto Lxi"; }


Sekarang, implementasikan kelas CarDecorator menggunakan komponen Car.


 public class CarDecorator : Car { protected Car _car; public CarDecorator(Car car) { _car = car; } public override int CarPrice() => _car.CarPrice(); public override string GetName() =>_car.GetName(); }


Sekarang, mari kita membuat kelas terpisah untuk setiap fitur tambahan yang tersedia untuk Mobil yang mewarisi kelas CarDecorator.


Sesuai dengan kasus penggunaan, fitur tambahannya adalah sunroof dan sistem musik canggih.

MukaMusik.cs

Ganti metode sebagai

  • Tambahkan biaya tambahan “sistem musik canggih” ke total harga mobil.

  • Perbarui nama mobil dengan nama fitur tambahan.

     public class AdvanceMusic : CarDecorator { public AdvanceMusic(Car car) : base(car) { } public override int CarPrice() => _car.CarPrice() + 3000; public override string GetName()=> "Alto Lxi with advance music system"; }

Atap.cs

Ganti metode sebagai

  • Tambahkan biaya tambahan “sunroof” ke total harga mobil.
  • Perbarui nama mobil dengan nama fitur tambahan.
 public class Sunroof : CarDecorator { public Sunroof(Car car) : base(car) { } public override int CarPrice() => _car.CarPrice() + 2000; public override string GetName() => "Alto Lxi with Sunroof"; }

Pola Dekorator dalam Aksi

Buat contoh SmallCar dan keluarkan nama dan harga mobil.


 Car car = new SmallCar(); Console.WriteLine($"Price of car {car.GetName()} : " + car.CarPrice());


Sekarang, mari kita tambahkan fitur tambahan seperti yang ditunjukkan di bawah ini


 var car1 = new Sunroof(car); var car2 = new AdvanceMusic(car);

Kode Lengkap

 static void Main(string[] args) { Car car = new SmallCar(); Console.WriteLine($"Price of car {car.GetName()} : " + car.CarPrice()); var car1 = new Sunroof(car); Console.WriteLine($"Price of car {car1.GetName()} : " + car1.CarPrice()); var car2 = new AdvanceMusic(car); Console.WriteLine($"Price of car {car2.GetName()} : " + car2.CarPrice()); }

Keluaran

Selamat..!! Anda telah berhasil menerapkan kasus penggunaan menggunakan pola dekorator.

Pola Desain — Metode Pabrik

Menurut Gang of Four, metode pabrik memungkinkan subkelas menentukan objek kelas mana yang harus dibuat.


Tujuan pembelajaran

  • Apa pola desain metode pabrik?
  • Bagaimana cara menulis kode menggunakan metode pabrik?

Memulai

Mari kita pertimbangkan contoh Bank mana pun dengan jenis akun Tabungan dan Giro. Sekarang, mari kita terapkan contoh di atas menggunakan pola desain pabrik


Pertama, buat kelas abstrak tipe akun.


 public abstract class AccoutType { public string Balance { get; set; } }


Terapkan kelas akun giro dan tabungan dengan mewarisi kelas abstrak AccountType seperti yang ditunjukkan di bawah ini.


 public class SavingsAccount : AccoutType { public SavingsAccount() { Balance = "10000 Rs"; } } public class CurrentAccount : AccoutType { public CurrentAccount() { Balance = "20000 Rs"; } }


Terakhir, mari kita terapkan antarmuka pabrik, yang akan menyediakan kontrak yang membantu membuat objek kelas. Antarmuka ini juga dikenal sebagai Creator.


 public interface IAccountFactory { AccoutType GetAccoutType(string accountName); }


Terakhir, tulis implementasi metode antarmuka kreator seperti yang ditunjukkan di bawah ini. Kelas yang mengimplementasikan kreator dikenal sebagai Concrete Creator.


 public class AccountFactory : IAccountFactory { public AccoutType GetAccoutType(string accountName) { if (accountName.Equals("SAVINGS", StringComparison.OrdinalIgnoreCase)) { return new SavingsAccount(); } else if (accountName.Equals("CURRENT", StringComparison.OrdinalIgnoreCase)) { return new CurrentAccount(); } else { throw new ArgumentException("Invalid account name"); } } }


Selesai. Anda telah berhasil menerapkan metode pabrik menggunakan contoh Bank.

Bagaimana Cara Menggunakan Metode Pabrik?

Subkelas akan menentukan objek kelas “AccountType” mana yang akan dibuat berdasarkan nama akun.


 class Program { static void Main(string[] args) { IAccountFactory accountFactory = new AccountFactory(); var savingAccount = accountFactory.GetAccoutType("SAVINGS"); Console.WriteLine("Saving account balance: " + savingAccount.Balance); var currentAccount = accountFactory.GetAccoutType("CURRENT"); Console.WriteLine("Current account balance: " + currentAccount.Balance); } }

Misalnya, jika nama akunnya adalah “TABUNGAN,” maka objek kelas “AkunTabungan” akan dibuat dan dikembalikan.


Demikian pula, jika nama akunnya adalah “CURRENT,” maka objek kelas “CurrentAccount” akan dibuat dan dikembalikan.

Keluaran

 Saving account balance: 10000 Rs Current account balance: 20000 Rs

Pola Desain — Iterator

Menurut Gang of Four, pola iterator menyediakan proses untuk mendapatkan objek agregator tanpa mengetahui implementasinya.


Kasus Penggunaan

Mari kita ambil contoh daftar koleksi mobil dan string[] array sepeda motor, kita perlu mendesain objek agregator sehingga seseorang dapat mengulang koleksi tersebut tanpa mengetahui apakah itu daftar atau array.


Pola desain iterator membantu memecahkan masalah ini di mana iterator standar akan melintasi berbagai jenis koleksi.

Memulai

Dengan mempertimbangkan kasus penggunaan di atas, mari kita tentukan antarmuka iterator khusus yang berfungsi sebagai lapisan abstrak pada iterator daftar dan array.


 public interface IVehicleIterator{ void First(); bool IsDone(); string Next(); string Current(); }


Sekarang, tulis iterator mobil dan sepeda motor yang mengimplementasikan antarmuka di atas sesuai dengan kasus penggunaan.

MobilIterator.cs

 public class CarIterator : IVehicleIterator { private List<string> _cars; private int _current; public CarIterator(List<string> cars) { _cars = cars; _current = 0; } public string Current() { return _cars.ElementAt(_current); } public void First() { _current = 0; } public bool IsDone() { return _current >= _cars.Count; } public string Next() { return _cars.ElementAt(_current++); } }


Iterator mobil diimplementasikan pada koleksi List<string> dan menyediakan implementasi metode antarmuka.

Iterator Sepeda Motor.cs

Iterator sepeda motor diimplementasikan melalui koleksi string[] dan menyediakan implementasi metode antarmuka.


 public class MotercycleIterator : IVehicleIterator { private string[] _motercylces; private int _current; public MotercycleIterator(string[] motercylces) { _motercylces = motercylces; _current = 0; } public string Current() { return _motercylces[_current]; } public void First() { _current = 0; } public bool IsDone() { return _current >= _motercylces.Length; } public string Next() { return _motercylces[_current++]; } }


Setelah semua iterator di atas didefinisikan, tentukan antarmuka objek agregator standar yang membuat iterator.


 public interface IVehicleAggregate{ IVehicleIterator CreateIterator(); }


Terakhir, tuliskan kelas-kelas yang mengimplementasikan antarmuka agregator di atas. Berdasarkan kasus penggunaan, kelas Mobil dan Sepeda Motor akan mengimplementasikan antarmuka agregator.

Mobil.cs

Metode antarmuka agregator mengembalikan iterator yang relevan seperti yang ditunjukkan di bawah ini.


 public class Car : IVehicleAggregate { private List<string> _cars; public Car() { _cars = new List<string> { "Car 1", "Car 2", "Car 3" }; } public IVehicleIterator CreateIterator() { return new CarIterator(_cars); } }

Sepeda motor.cs

Metode antarmuka agregator mengembalikan iterator yang relevan seperti yang ditunjukkan di bawah ini.


 public class Motercycle : IVehicleAggregate { private string[] _motercycles; public Motercycle() { _motercycles = new[] { "Bike 1", "Bike 2", "Bike 3" }; } public IVehicleIterator CreateIterator() { return new MotercycleIterator(_motercycles); } }

Pola Iterator dalam Aksi

Metode PrintVehicles memeriksa apakah !iterator.isDone kemudian mengeluarkan elemen koleksi. Apa pun koleksi yang kita hadapi, terapkan metode seperti First, IsDone, dan Next.


 static void Main(string[] args) { IVehicleAggregate car = new Vehicles.Car(); IVehicleAggregate motercycle = new Vehicles.Motercycle(); IVehicleIterator carIterator = car.CreateIterator(); IVehicleIterator motercycleIterator = motercycle.CreateIterator(); PrintVehicles(carIterator); PrintVehicles(motercycleIterator); } static void PrintVehicles(IVehicleIterator iterator) { iterator.First(); while (!iterator.IsDone()) { Console.WriteLine(iterator.Next()); } }

Keluaran

Kami tidak mengetahui jenis koleksi yang mendasarinya, tetapi masih diulang melalui Pola Desain Iterator. Jika Anda terus maju dan menjalankannya, output berikut akan ditampilkan.

Pola Desain — Mediator

Menurut Gang of Four, pola Mediator merangkum interaksi objek satu sama lain.


Pola desain mediator membantu kita merancang aplikasi yang saling terhubung secara longgar dengan merangkum interaksi objek.

Kasus Penggunaan

Mari kita pertimbangkan contoh ruang obrolan tempat peserta mendaftar, dan cara berkomunikasi secara efisien.


Perlu mengimplementasikan percakapan ruang obrolan berikut menggunakan Pola Desain Mediator.


 David to Scott: 'Hey' Scott to David: 'I am good how about you.' Jennifer to Ashley: 'Hey ashley... david is back in the group' Jennifer to David: 'Where have you been?' Ashley to David: 'How come you aren't active here anymore?'

Tujuan pembelajaran

  • Bagaimana cara membuat kode menggunakan pola desain mediator?

Memulai

Langkah utama adalah membuat daftar nama pengguna yang akan digunakan di dalam ruang obrolan. Enum publik untuk itu ditunjukkan di bawah ini.


 public enum Username{ Ashley, David, Jennifer, Scott }


Sekarang, pertama dan terutama, terapkan lapisan abstrak ruang obrolan.


 public abstract class AChatroom { public abstract void Register(User user); public abstract void Post(string fromUser, string toUser, string msg); }


Dan kelas yang mendefinisikan metode abstrak. Metode tersebut memvalidasi apakah pengguna tersebut ada dalam kamus. Misalnya, metode register memvalidasi apakah pengguna tersebut sudah ada atau belum. Jika tidak ada, maka pengguna tersebut hanya didaftarkan di ruang obrolan.


 public class Chatroom : AChatroom { private Dictionary<string, User> _users = new Dictionary<string, User>(); public override void Post(string fromUser, string toUser, string msg) { User participant = _users[toUser]; if (participant != null) { participant.DM(fromUser, msg); } } public override void Register(User user) { if (!_users.ContainsValue(user)) { _users[user.Name] = user; } user.Chatroom = this; } }


Terakhir, mari terapkan tindakan yang dapat dilakukan pengguna, seperti mengeposkan pesan kepada pengguna di ruang obrolan atau menerima DM dari pengguna lain.


 public class User { private Chatroom _chatroom; private string _name; public User(string name) => this._name = name; public string Name => _name; public Chatroom Chatroom { set { _chatroom = value; } get => _chatroom; } public void Post(string to, string message) => _chatroom.Post(_name, to, message); public virtual void DM(string from, string message) => Console.WriteLine("{0} to {1}: '{2}'", from, Name, message); }

Cara Menggunakan Pola Mediator Dari Metode Utama

 static void Main(string[] args) { Chatroom chatroom = new Chatroom(); User Jennifer = new UserPersona(Username.Jennifer.ToString()); User Ashley = new UserPersona(Username.Ashley.ToString()); User David = new UserPersona(Username.David.ToString()); User Scott = new UserPersona(Username.Scott.ToString()); chatroom.Register(Jennifer); chatroom.Register(Ashley); chatroom.Register(David); chatroom.Register(Scott); David.Post(Username.Scott.ToString(), "Hey"); Scott.Post(Username.David.ToString(), "I am good how about you."); Jennifer.Post(Username.Ashley.ToString(), "Hey ashley... david is back in the group"); Jennifer.Post(Username.David.ToString(), "Where have you been?"); Ashley.Post(Username.David.ToString(), "How come you aren't active here anymore?"); Console.ReadKey(); }


  1. Objek kelas ruang obrolan dibuat.
  2. Empat pengguna berbeda dibuat dengan nama yang unik.
  3. Daftarkan masing-masing dari mereka di ruang obrolan.
  4. Pengguna sekarang dapat mulai mengirim pesan satu sama lain.

Eksekusi program hanya menjelaskan metode Post dari kelas pengguna.


Output: Riwayat ruang obrolan dari eksekusi program di atas


 David to Scott: 'Hey' Scott to David: 'I am good how about you.' Jennifer to Ashley: 'Hey ashley... david is back in the group' Jennifer to David: 'Where have you been?' Ashley to David: 'How come you aren't active here anymore?'

Pola Desain — Pengamat

Menurut Gang of Four, pola pengamat mendefinisikan ketergantungan antara dua objek atau lebih. Jadi, ketika satu status objek berubah, maka semua dependennya akan diberitahu.


Dengan kata lain, perubahan pada satu objek memicu pemberitahuan pada objek lain.

Kasus Penggunaan

Mari kita ambil contoh influencer selebriti Instagram yang memiliki jumlah pengikut " x ". Jadi, saat selebriti tersebut mengunggah postingan, maka semua pengikutnya akan diberi tahu.


Mari kita terapkan kasus penggunaan tersebut di atas menggunakan Pola Desain Observer.

Tujuan pembelajaran

  • Bagaimana cara membuat kode menggunakan pola desain pengamat?

Memulai

Berdasarkan kasus penggunaan, yang pertama mengimplementasikan antarmuka yang berisi tindakan apa saja yang dapat dilakukan oleh seorang selebriti. Antarmuka ini dikenal sebagai “ Subjek .”


 public interface ICelebrityInstagram{ string FullName { get; } string Post { get; set; } void Notify(string post); void AddFollower(IFollower fan); void RemoveFollower(IFollower fan); }

Subjek Berisi Fungsi Anggota Berikut.

  • Beritahu: Untuk memberitahukan semua pengikut.

  • AddFollower: Tambahkan pengikut baru ke daftar selebriti.

  • RemoveFollower: Hapus pengikut dari daftar selebriti.


Sekarang, terapkan antarmuka pengamat “IFollower”, yang berisi fungsi anggota “Perbarui” untuk pemberitahuan.


 public interface IFollower{ void Update(ICelebrityInstagram celebrityInstagram); }


Akhirnya, sudah saatnya untuk menerapkan “Implementasi Konkret” untuk “ Subjek ” dan “ Pengamat ”.

ConcreteObserver Bernama “Follower.cs”

Ini menyediakan implementasi fungsi anggota Pembaruan, yang menampilkan nama selebriti & postingannya ke konsol.


 public class Follower : IFollower { public void Update(ICelebrityInstagram celebrityInstagram) { Console.WriteLine($"Follower notified. Post of {celebrityInstagram.FullName}: " + $"{celebrityInstagram.Post}"); } }

Subjek Beton Bernama “Sukhpinder.cs”

 public class Sukhpinder : ICelebrityInstagram { private readonly List<IFollower> _posts = new List<IFollower>(); private string _post; public string FullName => "Sukhpinder Singh"; public string Post { get { return _post; } set { Notify(value); } } public void AddFollower(IFollower follower) { _posts.Add(follower); } public void Notify(string post) { _post = post; foreach (var item in _posts) { item.Update(this); } } public void RemoveFollower(IFollower follower) { _posts.Remove(follower); } }

Bagaimana Cara Menggunakan Pola Pengamat?

Kasus penggunaan berikut menunjukkan bahwa setiap kali pernyataan di bawah ini dijalankan sukhpinder.Post = “Saya suka pola desain.”; Metode pembaruan dipicu untuk setiap pengikut, yaitu, setiap objek pengikut diberitahu tentang posting baru dari “Sukhpinder.”


 static void Main(string[] args) { var sukhpinder = new Sukhpinder(); var firstFan = new Follower(); var secondFan = new Follower(); sukhpinder.AddFollower(firstFan); sukhpinder.AddFollower(secondFan); sukhpinder.Post = "I love design patterns."; Console.Read(); }

Keluaran

Pola Properti Lanjutan C# 8.0

Artikel ini menjelaskan bagaimana pencocokan pola menyediakan cara yang efektif untuk memanfaatkan dan memproses data dalam bentuk yang bukan bagian dari sistem utama.


Ayo Mulai

Mari kita ambil contoh Kalkulator Tol dan lihat bagaimana pencocokan pola membantu menulis algoritma untuk itu.

Kelas Entitas yang Digunakan di Seluruh Artikel

 public class Car { public int PassengerCount { get; set; } } public class DeliveryTruck { public int Weight { get; set; } } public class Taxi { public int Fare { get; set; } } public class Bus { public int Capacity { get; set; } public int RidersCount { get; set; } }


Contoh 1: Hitung tarif tol sesuai dengan kondisi berikut:


  • Jika kendaraannya Mobil => 100 Rs
  • Jika kendaraannya adalah DeliveryTruck => 200 Rs
  • Jika kendaraannya Bus => 150 Rs
  • Jika kendaraannya adalah Taksi => 120 Rs

Program Pencocokan Pola Dengan Sintaks Switch Baru

Jika jenis kendaraan cocok dengan Mobil 100, maka akan dikembalikan dan seterusnya. Perhatikan bahwa null & {} adalah kasus default untuk jenis objek.

Selain itu, “_” dapat digunakan untuk memprogram skenario default. Lihat sintaks sakelar baru.


Ini adalah cara pengkodean yang jauh lebih bersih & efisien & juga merekomendasikan penggunaan nama variabel satu huruf di dalam sintaksis switch.


 public static int TollFare(Object vehicleType) => vehicleType switch { Car c => 100, DeliveryTruck d => 200, Bus b => 150, Taxi t => 120, null => 0, { } => 0 };

Uji Program Di Atas

Contoh pengujian dari sudut pandang aplikasi konsol. Kode di bawah ini menggambarkan cara memanggil fungsi pencocokan pola di atas dari metode utama.


 var car = new Car(); var taxi = new Taxi(); var bus = new Bus(); var truck = new DeliveryTruck(); Console.WriteLine($"The toll for a car is {TollFare(car)}"); Console.WriteLine($"The toll for a taxi is {TollFare(taxi)}"); Console.WriteLine($"The toll for a bus is {TollFare(bus)}"); Console.WriteLine($"The toll for a truck is {TollFare(truck)}");

Keluaran Konsol

 The toll for a car is 100 The toll for a taxi is 120 The toll for a bus is 150 The toll for a truck is 200


Contoh 2: Tambahkan harga hunian berdasarkan jenis kendaraan


  • Mobil dan taksi dengan penumpang “TIDAK” membayar tambahan 10 Rs.
  • Mobil dan taksi dengan dua penumpang mendapat diskon Rs 10.
  • Mobil dan taksi dengan tiga penumpang atau lebih mendapat diskon Rs 20.
  • Bus yang penumpangnya kurang dari 50% membayar tambahan 30 Rs.
  • Bus yang menampung lebih dari 90% penumpang mendapat diskon Rs 40.
  • Truk dengan berat lebih dari 5000 lbs dikenakan biaya tambahan sebesar 100 Rs.
  • Truk ringan di bawah 3000 lbs, diberi diskon 20 Rs.

Sakelar Pencocokan Pola

Lihat sintaks pencocokan pola dengan kelas properti tunggal & jamak. Tautan

Pencocokan Pola — Entitas Mobil

 Car { PassengerCount: 0 } => 100 + 10, Car { PassengerCount: 1 } => 100, Car { PassengerCount: 2 } => 100 - 10, Car c => 100 - 20,

Pencocokan Pola — Entitas Taksi

 Taxi {Fare:0 }=>100+10, Taxi { Fare: 1 } => 100, Taxi { Fare: 2 } => 100 - 10, Taxi t => 100 - 20,

Pencocokan Pola — Entitas Bus

 Bus b when ((double)b.RidersCount / (double)b.Capacity) < 0.50 => 150 + 30, Bus b when ((double)b.RidersCount / (double)b.Capacity) > 0.90 => 150 - 40, Bus b => 150,

Pencocokan Pola — Entitas Truk Pengiriman

 DeliveryTruck t when (t.Weight > 5000) => 200 + 100, DeliveryTruck t when (t.Weight < 3000) => 200 - 20, DeliveryTruck t => 200,

Menggabungkan Semua Entitas

Contoh di bawah ini menyoroti keuntungan dari pencocokan pola: cabang pola dikompilasi secara berurutan. Kompiler juga memperingatkan tentang kode yang tidak dapat diakses.


 public static int OccupancyTypeTollFare(Object vehicleType) => vehicleType switch { Car { PassengerCount: 0 } => 100 + 10, Car { PassengerCount: 1 } => 100, Car { PassengerCount: 2 } => 100 - 10, Car c => 100 - 20, Taxi { Fare: 0 } => 100 + 10, Taxi { Fare: 1 } => 100, Taxi { Fare: 2 } => 100 - 10, Taxi t => 100 - 20, Bus b when ((double)b.RidersCount / (double)b.Capacity) < 0.50 => 150 + 30, Bus b when ((double)b.RidersCount / (double)b.Capacity) > 0.90 => 150 - 40, Bus b => 150, DeliveryTruck t when (t.Weight > 5000) => 200 + 100, DeliveryTruck t when (t.Weight < 3000) => 200 - 20, DeliveryTruck t => 200, null => 0, { } => 0, };

Uji Program Di Atas

Contoh pengujian dari sudut pandang aplikasi konsol. Kode di bawah ini menggambarkan cara memanggil fungsi pencocokan pola di atas dari metode utama.


 var car1 = new Car{ PassengerCount=2}; var taxi1 = new Taxi { Fare = 0 }; var bus1 = new Bus { Capacity = 100, RidersCount = 30 }; var truck1 = new DeliveryTruck { Weight = 30000 }; Console.WriteLine($"The toll for a car is {OccupancyTypeTollFare(car1)}"); Console.WriteLine($"The toll for a taxi is {OccupancyTypeTollFare(taxi1)}"); Console.WriteLine($"The toll for a bus is {OccupancyTypeTollFare(bus1)}"); Console.WriteLine($"The toll for a truck is {OccupancyTypeTollFare(truck1)}");

Keluaran Konsol

 The toll for a car is 90 The toll for a taxi is 110 The toll for a bus is 180 The toll for a truck is 300


“Pencocokan pola membuat kode lebih mudah dibaca dan menawarkan alternatif untuk teknik berorientasi objek saat Anda tidak dapat menambahkan kode ke kelas Anda.”

Pola Desain — Singleton

Gang of Four — Pola desain Singleton memastikan bahwa kelas tertentu hanya memiliki satu instans/objek dan titik akses global.


Tujuan pembelajaran

  • Bagaimana cara membuat kode menggunakan pola desain singleton?

Memulai

Kelas singleton digunakan untuk menghilangkan pembuatan lebih dari satu objek dari kelas tertentu.


 public class SingletonExample { private string Name { get; set; } = "Hello from singleton"; private static SingletonExample _instance; public static SingletonExample Instance { get { if (_instance == null) { _instance = new SingletonExample(); } return _instance; } } public SingletonExample() { } public string GetName() => Name; }

Perincian

  1. Iterasi 1 _instance==null berarti hanya instance yang akan dibuat.
  2. Iterasi 2, seperti sekarang _intance !=null Jadi instance yang dibuat sebelumnya akan dikembalikan.

Uji Menggunakan Aplikasi Konsol

Mari panggil kelas singleton dua kali dan tetapkan instance yang dikembalikan ke dua variabel yang berbeda. Terakhir, periksa apakah kedua objek tersebut sama menggunakan fungsi Object.Equals.


 static void Main(string[] args) { var response = SingletonExample.Instance; Console.WriteLine(response); var response1 = SingletonExample.Instance; Console.WriteLine(response1); Console.WriteLine(Object.Equals(response1, response)); }
  • Jika mengembalikan nilai true, artinya satu contoh tunggal diproduksi setiap waktu.
  • Jika mengembalikan false, artinya kelas tidak mengikuti pola singleton.

Keluaran

Output konsol mengembalikan true; selamat. Anda telah berhasil menerapkan Pola Singleton.



Keamanan Benang

Kelas di atas dikenal sebagai kelas singleton, tetapi saat ini, kelas tersebut tidak aman untuk thread. Dalam lingkungan multi-thread, dua thread dapat menjalankan pernyataan if (_instance == null) secara bersamaan, dan pada akhirnya kita akan memiliki beberapa instance dari kelas singleton.


Salah satu cara untuk membuat thread lebih aman adalah dengan menggunakan mekanisme penguncian, dan cara lainnya adalah dengan membuat instance read-only untuk pendekatan yang lebih bersih dan efisien.

 public class ThreadSafeSingleton { private static readonly ThreadSafeSingleton _instance = new ThreadSafeSingleton(); public static ThreadSafeSingleton Instance { get { return _instance; } } public ThreadSafeSingleton() { } }

Contoh Github

https://github.com/ssukhpinder/DesignPatterns

Terima kasih telah membaca!

Sponsor membantu saya terus memelihara dan membangun proyek baru seperti ini.


🙏 Jika Anda menggunakan Pay, Noticed, atau proyek saya lainnya, kontribusi kecil akan SANGAT BERARTI. Dengan sendirinya, open source tidak akan menguntungkan. Semoga, dengan bantuan Anda, melanjutkan pekerjaan saya dapat berkelanjutan, dan saya tidak perlu mencari pekerjaan tetap 😛.

Pemrograman C#🚀

Terima kasih telah menjadi bagian dari komunitas C#!

Belikan aku kopi