Menu
Coddy logo textTech

Mixin ve Arayüz Karşılaştırması

Coddy'nin Dart Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 55 / 110.

Mixin'lerin kalıtımla nasıl karşılaştırıldığını gördün. Şimdi, her ikisi de birden fazla türle çalışmana olanak tanıdığı için mixin'leri arayüzlerle karşılaştıralım. Temel fark, sağladıkları şeydir: arayüzler bir sözleşme tanımlarken mixin'ler uygulama sağlar.

Bir arayüzü uyguladığınızda belirli metotları sağlama sözü verirsiniz, ancak tüm kodu kendiniz yazarsınız. Bir mixin kullandığınızda ise gerçek kodu ücretsiz olarak elde edersiniz.

// Arayüz yaklaşımı - her şeyi uygulamanız gerekir
abstract class Printable {
  void printInfo();
}

class Report implements Printable {
  @override
  void printInfo() {
    print('Printing report...');  // Bunu siz yazarsınız
  }
}

// Mixin yaklaşımı - uygulama dahildir
mixin Printable {
  void printInfo() {
    print('Printing...');  // Sizin için zaten yazıldı
  }
}

class Report with Printable {}  // printInfo() işlevini otomatik olarak alır

Öyleyse her birini ne zaman kullanmalısınız? Farklı sınıfların aynı yöntem imzalarına ancak farklı uygulamalara ihtiyaç duyduğu durumlarda bir arayüz kullanın. Sınıfların tamamen aynı davranışı paylaşması gerektiğinde ise bir mixin kullanın.

ÖzellikArayüzMixin
SağladığıYalnızca sözleşmeSözleşme + kod
UygulamaSen yazarsınDahil
Anahtar kelimeimplementswith
Şunlar için en iyisiFarklı davranışlar, aynı APIPaylaşılan davranış

Hatta her iki yaklaşımı birleştirebilirsin: bir sınıfın neler yapabileceğini tanımlamak için arayüzleri, uygun olduğunda ortak uygulamalar sağlamak için mixin'leri kullanabilirsin. Dart'ta her ikisini birleştirirken her zaman with ifadesini implements ifadesinden önce yaz:

class MyClass with SomeMixin implements SomeInterface {
  // with, implements'tan önce gelir
}
challenge icon

Görev

Kolay

Arayüzlerin ve mixin'lerin ne zaman kullanılacağını gösteren bir bildirim sistemi oluşturalım. Farklı uygulamalar gerektiren bildirimler için bir arayüz, tüm bildirim türlerinde aynı olması gereken ortak günlük kaydı davranışı için ise bir mixin oluşturacaksın.

Kodunu üç dosyada düzenleyeceksin:

  • notifiable.dart: Arayüz görevi gören soyut bir Notifiable sınıfı tanımla. İki soyut yöntem bildirmelidir: send(String message) ve bir getChannel() döndüren String. Farklı bildirim türleri, kendi kanallarına göre bu yöntemleri farklı şekilde uygulayacaktır.
  • logging.dart: Tüm bildirimlerin sahip olması gereken ortak davranışı sağlayan bir Logging mixin'i oluştur. logSent(String channel, String message) yazdıran [LOG] Sent via [channel]: [message] yöntemini ve logTimestamp() yazdıran [LOG] Timestamp recorded yöntemini ekle. Bu davranış tüm bildirim türleri için aynı olduğundan mixin kullanımı için idealdir.
  • main.dart: Her iki dosyayı içe aktar ve arayüzü mixin ile birleştiren iki bildirim sınıfı oluştur:
    • EmailNotification mixin'ini kullanan ve Logging arayüzünü uygulayan bir Notifiable sınıfı. getChannel() yöntemi 'Email' döndürmeli ve send() yöntemi Sending email: [message] yazdırmalı, ardından kanal ve mesajla birlikte logSent() yöntemini, sonra da logTimestamp() yöntemini çağırmalıdır.
    • SMSNotification mixin'ini kullanan ve Logging arayüzünü uygulayan bir Notifiable sınıfı. getChannel() yöntemi 'SMS' döndürmeli ve send() yöntemi Sending SMS: [message] yazdırmalı, ardından kanal ve mesajla birlikte logSent() yöntemini, sonra da logTimestamp() yöntemini çağırmalıdır.
    Ardından bir EmailNotification oluştur ve send('Hello World') çağrısını yap, boş bir satır yazdır, bir SMSNotification oluştur ve send('Quick update') çağrısını yap

Arayüzün her sınıfı kendi send() ve getChannel() uygulamalarını (farklı davranış) yazmaya zorladığına, mixin'in ise her ikisi için aynı şekilde çalışan günlük kaydı yöntemlerini (ortak davranış) sağladığına dikkat et.

Beklenen çıktı:

Sending email: Hello World
[LOG] Sent via Email: Hello World
[LOG] Timestamp recorded

Sending SMS: Quick update
[LOG] Sent via SMS: Quick update
[LOG] Timestamp recorded

Kendin dene

import 'notifiable.dart';
import 'logging.dart';

// TODO: Şu özelliklere sahip EmailNotification sınıfını oluşturun:
//       - Logging mixin'ini kullanır (with)
//       - Notifiable arayüzünü uygular (implements)
//       - getChannel() 'Email' değerini döndürür
//       - send() 'Sending email: [message]' yazdırır, ardından logSent() ve logTimestamp() fonksiyonlarını çağırır

// TODO: Şu özelliklere sahip SMSNotification sınıfını oluşturun:
//       - Logging mixin'ini kullanır (with)
//       - Notifiable arayüzünü uygular (implements)
//       - getChannel() 'SMS' değerini döndürür
//       - send() 'Sending SMS: [message]' yazdırır, ardından logSent() ve logTimestamp() fonksiyonlarını çağırır

void main() {
  // TODO: Bir EmailNotification oluşturun ve send('Hello World') fonksiyonunu çağırın
  
  // TODO: Boş bir satır yazdırın
  
  // TODO: Bir SMSNotification oluşturun ve send('Quick update') fonksiyonunu çağırın
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Dart derleyicisi