Kompozisyon, delegation ve nesne koleksiyonları

Gerçek uygulamalar tek bir sınıftan oluşmaz. Bir sipariş müşteriye ve ürünlere, bir kütüphane kitaplara ve üyelere, bir takım oyunculara sahiptir. Bu hafta nesneler arasındaki has-a ilişkisini, kompozisyonu ve bir nesnenin başka nesnelere işi devretmesini (delegation) kullanacağız.

Bu hafta neleri yapabilmelisiniz?

  • has-a ilişkisinin anlamını açıklayabilmeli,
  • bir sınıfın başka sınıftan nesneyi nitelik olarak tutmasını tasarlayabilmeli,
  • nesne koleksiyonlarını liste veya sözlükte yönetebilmeli,
  • delegation ile sorumluluğu doğru nesneye aktarabilmeli,
  • kimlik/tekrar kontrolünü nesne koleksiyonlarında uygulayabilmeli,
  • kompozisyonun kalıtıma alternatif olabileceğini sezgisel olarak açıklayabilmelisiniz.

Bir nesne başka nesneyi tutabilir

Order, bir Customer nesnesine sahiptir. Bu bir has-a ilişkisidir: Order has a Customer.

Bir siparişin müşteri, sipariş satırı ve ürün nesneleri arasındaki ilişkilerle kurulması.
NoteBu derste “kompozisyon”u hangi anlamda kullanıyoruz?

Başlangıç düzeyinde kompozisyon sözcüğünü, bir nesnenin başka nesneleri içererek veya kullanarak davranış oluşturması biçimindeki geniş has-a yaklaşımı için kullanacağız. UML’deki aggregation–composition ayrımı, özellikle parçanın yaşam döngüsünün bütüne bağlı olup olmadığı gibi daha ayrıntılı modelleme kuralları bu geçiş sürümünün kapsamı dışındadır.

Nesne koleksiyonu

Sipariş birden çok ürüne sahip olabilir:

items, sayı listesi değil Product nesneleri listesidir.

Delegation: işi sahibine bırakmak

Delegation, bir nesnenin başka bir nesnenin sorumluluğunda olan davranışı kendisi yeniden yazmak yerine o nesneye çağrı yapmasıdır. Örneğin fiyatlandırma kuralının ürüne ait olduğunu varsayalım:

OrderLine, ürünün fiyatlandırma kuralını kopyalamaz; Product.price_for() davranışına delegasyon yapar. Bu örnekte delegasyonun gerekçesi, miktara bağlı fiyatlandırma kuralının ürün sorumluluğu olarak seçilmiş olmasıdır.

ImportantDelegation mekanik bir kural değildir

Eğer ara toplam yalnızca unit_price * quantity hesabından ibaretse bu davranışın OrderLine içinde kalması da makul olabilir. Amaç “her çağrıyı başka nesneye devretmek” değil, davranışı kuralın gerçek sahibine yerleştirmektir.

Sorumluluk yanlış yerdeyse ne olur?

Şöyle bir Library sınıfı düşünün:

class Library:
    def borrow_book(self, member, book):
        book.is_borrowed = True
        member.borrowed_count += 1
        # onlarca kural...

Kütüphane her nesnenin iç durumunu doğrudan yönetmeye başlarsa sınıf hızla “her şeyi yapan” merkeze dönüşür.

Daha iyi tasarımda Book.borrow() ve Member.add_borrowed_book() gibi davranışlar kendi nesnelerine ait olabilir; Library ise işlemi koordine eder.

Kütüphane işleminin üye ve kitap nesneleriyle birlikte yürütülmesi; uygun durumda kitap ve üye durumlarının güncellenmesi.

Çokluk ilişkisi

Bir sınıfın:

  • tek bir nesneye sahip olması: order.customer
  • çok sayıda nesneye sahip olması: order.lines

farklı ilişkilerdir.

Bir-çok ilişkide liste veya sözlük seçimi kullanım biçimine göre yapılmalıdır. Üye numarasından doğrudan üye bulmak istiyorsak sözlük uygun olabilir:

Burada tekrar kontrolü Library’nin koleksiyonu yönetme sorumluluğundadır.

Alıştırma — İlişkiyi belirle

Aşağıdaki çiftlerde ilişkinin has-a olup olmadığını ve hangi tarafın diğerini tutmasının makul olduğunu tartışın:

  1. CarEngine
  2. OrderCustomer
  3. PlaylistSong
  4. StudentCourse

Son örnekte ilişkinin iki yönlü modellenmesi gerekip gerekmediğini de düşünün. Her ilişkiyi iki tarafta da saklamak zorunlu değildir; iki yönlü durum senkronizasyon maliyeti yaratır.

Alıştırma — Nesne koleksiyonunu tamamla

Oyuncu adını kimlik yerine kullanmak güvenilir olmayabilir; iki farklı oyuncunun aynı adı olabilir. Bu nedenle tekrar kontrolünü player_id üzerinden yapıyoruz:

self.players.append(player)

Alıştırma — Kim değişti?

Aşağıdaki örnekte Cart, dışarıdaki product ile aynı Product nesnesini tutar. Stok değişimini doğrudan niteliğe yazmak yerine nesnenin davranışı üzerinden yapıyoruz:

Bu örnek 6. haftadaki referans modelinin nesneler arası ilişkide nasıl devam ettiğini, 8. haftadaki kontrollü durum değişimiyle birlikte gösterir.

Küçük üretim görevi — Kütüphane modeli

En az üç sınıflı küçük model oluşturun:

  • Book
  • Member
  • Library

Şu kuralları uygulayın:

  • kitap ISBN ile tanımlansın,
  • aynı ISBN iki kez eklenemesin,
  • üye numarası benzersiz olsun,
  • Library kitap ve üyeleri koleksiyonlarda tutsun,
  • ödünç alma davranışının hangi sınıfa/sınıflara ait olduğuna gerekçeyle karar verin.

Tam bir kütüphane otomasyonu yazmaya çalışmayın. Amaç ilişki ve sorumluluk tasarımıdır.

Kompozisyon neden önemli?

Bir davranışı yeniden kullanmak için ilk refleks “bir üst sınıf oluşturayım” olmamalıdır. Çoğu zaman bir nesnenin başka nesneyi kullanması daha esnek bir ilişkidir. Gelecek hafta kalıtımı öğreneceğiz; ancak kompozisyonu birinci sınıf tasarım seçeneği olarak hatırlayacağız.

Kendinizi kontrol edin

  1. has-a ilişkisi neyi ifade eder?
  2. Bu derste kompozisyon terimini hangi geniş anlamda kullanıyoruz?
  3. Nesne koleksiyonunda liste ile sözlük seçimi neye bağlıdır?
  4. Delegation nedir ve hangi durumda anlamlıdır?
  5. Neden her ilişkiyi iki yönlü tutmak gereksiz olabilir?
  6. Bir nesnenin görünen adı ile alan kimliğini neden aynı şey kabul etmemeliyiz?
  7. Kompozisyon, kalıtımdan hangi açıdan daha gevşek bir bağ kurabilir?

Bu haftadan akılda kalması gerekenler

  • Gerçek sistemler nesnelerin işbirliğiyle kurulur.
  • Bu derste kompozisyonu, nesneleri içererek/kullanarak davranış oluşturma anlamında geniş has-a yaklaşımıyla kullanıyoruz.
  • Delegation, davranışı mekanik olarak taşımak değil, işi uygun sorumluluğa devretmektir.
  • Bir-çok ilişkilerde koleksiyon seçimi ve benzersizlik anahtarı kullanım ihtiyacına göre belirlenir.
  • Kalıtım tek yeniden kullanım mekanizması değildir.
Back to top