Komposisi daripada Pewarisan
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C# di Coddy. Pelajaran 41 dari 70.
Pewarisan menciptakan keterikatan erat antara class. Saat Car mewarisi dari Vehicle, perubahan apa pun pada Vehicle dapat merusak Car. Komposisi menawarkan alternatif yang lebih fleksibel: alih-alih mewarisi perilaku, sebuah class berisi object yang menyediakan perilaku tersebut.
Bayangkan karakter game yang dapat bergerak dan menyerang. Dengan pewarisan, kamu mungkin membuat hierarki yang rumit. Dengan komposisi, kamu cukup memberikan komponen yang dibutuhkan karakter tersebut:
public class MovementBehavior
{
public void Move() => Console.WriteLine("Moving...");
}
public class AttackBehavior
{
public void Attack() => Console.WriteLine("Attacking!");
}
public class Character
{
private MovementBehavior movement = new MovementBehavior();
private AttackBehavior attack = new AttackBehavior();
public void Move() => movement.Move();
public void Attack() => attack.Attack();
}Perbedaan utamanya terletak pada hubungannya. Inheritance menggambarkan hubungan "is-a" (seekor Dog adalah Animal), sedangkan composition menggambarkan hubungan "has-a" (sebuah Character memiliki perilaku gerakan). Composition memungkinkan kamu mengganti perilaku saat program berjalan, menggabungkan kemampuan dengan bebas, dan menghindari masalah fragile base class.
Gunakan pewarisan jika memang ada hubungan hierarkis. Pilih komposisi jika kamu membutuhkan fleksibilitas, jika perilaku mungkin dibagikan di antara class yang tidak berkaitan, atau jika kamu ingin mengubah perilaku secara dinamis.
Tantangan
MudahMari kita buat sistem notifikasi yang menunjukkan keunggulan komposisi dibandingkan pewarisan. Daripada membuat hierarki class notifikasi yang rumit, kamu akan menyusun NotificationSender dengan memberinya komponen perilaku yang dapat ditukar.
Kamu akan menyusun kodemu dalam tiga file:
Behaviors.cs: Buat dua class perilaku dalam namespaceNotificationsuntuk menangani aspek pengiriman notifikasi yang berbeda:FormattingBehavior- memiliki methodFormat(string message)yang mengembalikan pesan dengan[ALERT]di awal dan[END]di akhirDeliveryBehavior- memiliki methodDeliver(string channel, string message)yang mengembalikan string dalam formatSending via {channel}: {message}
NotificationSender.cs: Buat classNotificationSenderdalam namespaceNotificationsyang menggunakan komposisi untuk menggabungkan perilaku. Pengirimmu harus:- Memuat instance
FormattingBehaviordanDeliveryBehaviorsebagai field privat - Memiliki property
Channel(string) yang menyimpan nama saluran pengiriman - Memiliki constructor yang menerima nama saluran
- Memiliki method
Send(string message)yang terlebih dahulu memformat pesan menggunakan perilaku pemformatan, lalu mengirimkannya menggunakan perilaku pengiriman, dan mengembalikan hasil akhir
- Memuat instance
Program.cs: Di file utama, buatNotificationSenderdengan saluran dari input, lalu kirim pesan dari input. Cetak hasilnya untuk menunjukkan cara kerja perilaku yang digabungkan.
Kamu akan menerima dua input:
- Nama saluran pengiriman (misalnya,
Email,SMS) - Pesan yang akan dikirim
Cetak hasil pemanggilan Send() pada pengirim notifikasimu.
Misalnya, jika inputnya adalah Email dan Server is down, outputnya akan seperti ini:
Sending via Email: [ALERT] Server is down [END]Perhatikan bahwa NotificationSender tidak mewarisi apa pun, class ini hanya "memiliki" perilaku pemformatan dan pengiriman. Pendekatan komposisi ini berarti kamu dapat dengan mudah mengganti salah satu perilaku tanpa mengubah class pengirim, atau menggunakan kembali perilaku ini di class yang sama sekali berbeda!
Coba sendiri
using System;
using Notifications;
class Program
{
public static void Main(string[] args)
{
// Baca input
string channel = Console.ReadLine();
string message = Console.ReadLine();
// TODO: Buat NotificationSender dengan channel
// TODO: Kirim message dan cetak hasilnya
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalNamespace & DirektifPengantar class & objectKata Kunci 'this'Method dan ParameterField vs PropertyKonstruktorInisialisasi objectRingkasan: Kalkulator Sederhana4Pewarisan
Sintaks Dasar Pewarisan (:)Kata Kunci 'base'Kata Kunci Virtual & OverrideClass SealedBase Class 'object'Rangkuman: Hierarki Karyawan7Fitur Lanjutan
Overloading OperatorIndexer (this[])Penimpaan ToString()Extension methodRingkasan: Custom list2Property & Anggota Statis
Property yang Diimplementasikan OtomatisProperty Hanya Baca dan Hanya TulisField dan method StatisClass StatisAnggota Berbentuk Ekspresi5Polimorfisme & Antarmuka
Polimorfisme saat kompilasi vs runtimeAntarmuka vs kelas abstrakBeberapa antarmukaAntarmuka eksplisitUpcasting & DowncastingRingkasan, Kalkulator Bentuk8Konsep OOP Lanjutan
Komposisi daripada PewarisanGenerics (class dan method)Delegate dan EventAtribut dan ReflectionIDisposable dan Pernyataan usingDasar-Dasar Dependency Injection11Pola Desain Bagian 2
Pola PerintahPola AdapterPola DecoratorPola Template MethodPola StatePola CompositeLatihan sendiri: Compiler C# online