Menu
CoddyTech

Yineleyici Kalıbı

Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 76 / 87.

Yineleyici Deseni, bir koleksiyonun temel yapısını açığa çıkarmadan öğelerine sıralı olarak erişmenin bir yolunu sunan davranışsal bir tasarım desenidir. Bir dizi, bağlı liste veya ağaçla çalışıyor olmanız fark etmeksizin, yineleyici öğeler arasında gezinmek için tek tip bir yol sunar.

Desen, dolaşım mantığını koleksiyonun kendisinden ayırır. İki ana bileşenden oluşur: öğeler arasında dolaşmaya yönelik yöntemleri tanımlayan bir Iterator arayüzü ve koleksiyonu için yineleyiciler oluşturan bir Iterable (veya Aggregate):

interface Iterator<T> {
    boolean hasNext();
    T next();
}

interface Container<T> {
    Iterator<T> createIterator();
}

class BookShelf implements Container<String> {
    private String[] books;
    private int count = 0;
    
    public BookShelf(int size) {
        books = new String[size];
    }
    
    public void addBook(String book) {
        books[count++] = book;
    }
    
    public Iterator<String> createIterator() {
        return new BookIterator();
    }
    
    private class BookIterator implements Iterator<String> {
        private int index = 0;
        
        public boolean hasNext() {
            return index < count;
        }
        
        public String next() {
            return books[index++];
        }
    }
}

Yineleyici, kendi dolaşım durumunu koruyarak birden fazla yineleyicinin aynı koleksiyonda birbirinden bağımsız olarak gezinmesini sağlar. İstemciler, koleksiyonun verilerini nasıl sakladığını bilmeden yineleyiciyi kullanır:

BookShelf shelf = new BookShelf(3);
shelf.addBook("Design Patterns");
shelf.addBook("Clean Code");

Iterator<String> iterator = shelf.createIterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Java'nın yerleşik Iterable ve Iterator arayüzleri bu kalıbı aynen izler; bu nedenle Iterable uygulayan herhangi bir sınıfla gelişmiş for döngülerini kullanabilirsin. Yineleyici Kalıbı, birden fazla dolaşma yöntemi sunman veya karmaşık iç yapıları istemci kodundan gizlemen gerektiğinde önemlidir.

challenge icon

Görev

Kolay

Iterator Deseni'ni kullanarak bir çalma listesi sistemi oluşturalım! Şarkıları depolayan ve şarkıların dahili olarak nasıl saklandığını açığa çıkarmadan bunların arasında sırayla gezinmek için özel bir yineleyici sağlayan bir müzik çalma listesi oluşturacaksın. Kullanıcıların koleksiyonunda temiz ve tutarlı bir arayüz üzerinden gezinmesini sağlayan Iterator Deseni için bu mükemmel bir kullanım örneğidir.

Kodunu dört dosyaya ayıracaksın:

  • Iterator.java: İki yöntemi olan genel Iterator<T> arayüzünü tanımla: Daha fazla öğe olup olmadığını belirten bir boolean döndüren hasNext() ve T türündeki bir sonraki öğeyi döndüren next().
  • Playlist.java: Şarkılarını tutan koleksiyon sınıfını oluştur. Playlist sınıfın, sabit kapasiteli (kurucuya geçirilen) bir String dizisinde şarkıları saklamalı ve kaç şarkı eklendiğini takip etmelidir. Çalma listesine şarkı eklemek için bir addSong(String song) yöntemi ekle.

    Playlist sınıfında bir Iterator<String> döndüren createIterator() yöntemi bulunmalıdır. Bunu, Iterator arayüzünü uygulayan ve PlaylistIterator adlı özel bir iç sınıf oluşturarak gerçekleştir. Bu iç yineleyici kendi indeks konumunu tutar ve şarkı dizisinde gezinerek her şarkıyı sırayla döndürür.

  • Song.java: Bir şarkı başlığını saran basit bir Song sınıfı oluştur. Başlığı (String) alan bir kurucusu, bir getTitle() yöntemi ve Playing: [title] döndüren bir toString() yöntemi olmalıdır.
  • Main.java: Yineleyici sistemini bir araya getir! Tek bir girdi alacaksın: virgülle ayrılmış şarkı başlıkları listesi (örneğin: Bohemian Rhapsody,Stairway to Heaven,Hotel California).

    10 şarkı kapasiteli bir Playlist oluştur. Girdiyi ayrıştır ve her şarkı başlığını çalma listesine ekle. Ardından çalma listesinden bir yineleyici al ve tüm şarkılarda gezinmek için bu yineleyiciyi kullan; her şarkıyı bir Song nesnesine sarılmış olarak yazdır (bu nesne Playing: [title] şeklinde görüntülenir).

    Tüm şarkılarda yineleme yaptıktan sonra yeni bir satıra Playlist complete! yazdır.

Tek bir girdi alacaksın: virgülle ayrılmış şarkı başlıklarından oluşan bir dize.

Örneğin, girdi Yesterday,Imagine,Let It Be olduğunda çıktın şöyle olur:

Playing: Yesterday
Playing: Imagine
Playing: Let It Be
Playlist complete!

Main sınıfının, temel dizi yapısı hakkında hiçbir şey bilmeden çalma listesinde gezinmek için yineleyicinin hasNext() ve next() yöntemlerini nasıl kullandığına dikkat et. Yineleyici tüm gezinme mantığını kapsülleyerek koleksiyonun dahili gösterimini istemci kodundan gizli tutar!

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: 10 şarkı kapasiteli bir Playlist oluştur
        
        // TODO: Girdiyi (virgülle ayrılmış) ayrıştır ve her şarkı başlığını çalma listesine ekle
        
        // TODO: createIterator() kullanarak çalma listesinden bir iterator al
        
        // TODO: Tüm şarkıları dolaşmak için iterator kullan
        // Her şarkıyı bir Song nesnesine dönüştür ve yazdır
        
        // TODO: Tüm şarkıları dolaştıktan sonra "Playlist complete!" yazdır
    }
}
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 Java derleyicisi