Embedding ile Composition: Go'da Kod Tekrarını Gerçekten Azaltıyor mu

Go'da embedding popüler bir kalıptır. Bir struct'ı başka bir struct'ın içine gömüp, onun metotlarını doğrudan kullanabilirsiniz. Teoride temiz, pratikde ise sık sık sorun yaratır.

Embedding, inheritance'ın Go versiyonumuş gibi görünür. Bir Logger struct'ını Database içine koyarsınız, Database otomatik olarak Logger'ın bütün metotlarını alır. Kod tekrarı yoktur, temiz görünür.

Ancak bu sadece görünüş. Embedding aslında kalıtım değil, delegasyon'dur, ama bu delegasyon sizin yerinize otomatik olarak yapılır. Fark çok önemlidir.

Bir Server struct'ı içine Logger ve Database embed ederseniz, Server aniden her ikisinin de bütün metotlarını ortaya çıkarır. Dışarıdan bakan biri Server'ın ne yaptığını anlamakta zorluk çeker. Bir Server neden Logger'ın SetLevel() metotunu doğrudan çağırabilsin?

Composition bu sorunu çözer:

1type Server struct {
2logger *Logger
3database *Database
4}
5
6func (s *Server) Log(msg string) {
7s.logger.Info(msg)
8}

Burada Server'ın sorumluluğu açıktır. Dışarıdan bakan biri tam olarak neler yaptığını görebilir.

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası

Azalır, ama fiyatı vardır. Embedding'de bir satır yazmadığınız metotları kullanırsınız. Composition'da her metot için bir wrapper yazmanız gerekebilir.

Ancak bu "tekrar" aslında tasarım kararıdır. Bir metotu açıkça expose etmiyorsanız, o metodu kullanılmasını istemiyor demektir. Embedding bunu göz ardı eder.

Ayrıca embedding'de ad çakışmaları sorun olur. İçine gömülen iki struct'ın aynı isimli metotu varsa, hangisini çağıracaksınız? Go bunu çözmek için karmaşık kurallar uygular, bu da kod tekrarını azaltmanın getirdiği karmaşıklıktır.

Embedding'i sadece ek özellik eklemek için kullanın. Bir BaseModel struct'ı varsa ve bütün modelleriniz onun ID, CreatedAt gibi alanlarını alması gerekiyorsa, embedding mantıklıdır.

Ancak davranış (metotlar) için composition tercih edin. Bir Database ve Logger'ı bir Service içine koyarken, hangisinin hangisini çağırdığını açıkça gösterin.

Go'da kod tekrarını azaltmanın yolu daha az yazmak değil, daha açık yazmaktır. Embedding bunu sağlamaz.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz