Yabancılarla Konuşma! – Law Of Demeter
Nesne yönelimli programlamanın kıyısından köşesinden bir ilişkiniz olduysa eğer encapsulation, abstraction, loosely coupling gibi terimleri duymuşsunuzdur. Bu terimler aslında kolay gibi gözüken ama gerçekleştirmesi, özellikle kodlar ve istekler büyüdükçe, o kadar da kolay olmayan şeylerden bahsederler.
Bugün bunların gerçekleştirilmesinde bize yardımcı olan, kimilerine göre bir pattern kimilerine göre bir pratik olan Law of Demeter’dan (LoD) bahsedeceğim. Özetle LoD başlıkta belirttiğim gibi “Yabancılarla Konuşma!” der. Bu pratiğe göre bir nesneye ait metod aşağıdaki dört şekilde metod çağırmaldır.
- Nesnenin kendisine ait metodlar.
- Metoda parametre ile gelen nesnelere ait metodlar.
- Metodun içerisinde oluşturulmuş bir nesneye ait metodlar.
- Nesnenin direk erişimi olan nesne ve özelliklere ait metodlar.
Bu maddeleri kısaca birer kod parçacığı ile gösterecek olursak.
- Nesnenin kendisine ait metodlar.
public class OrnekSinif { public void AcikIslemYap() { islemYap(); // Nesnenin kendi metodunu çağırıyor, LoD 1 } private void islemYap() { } }
- Metoda parametre ile gelen nesnelere ait metodlar.
public class OrnekSinif { public void AcikIslemYap(DigerSinif digerSinif) { digerSinif.BaskaIslemYap(); // Parametre ile gelen nesnenin metodunu çağırıyor, LoD 2 } }
- Metodun içerisinde oluşturulmuş bir nesneye ait metodlar.
public class OrnekSinif { public void AcikIslemYap() { DigerSinif digerSinif = new DigerSinif(); digerSinif.BaskaIslemYap(); // Metod içerisinde oluşturulmuş nesnenin metodunu çağırıyor, LoD 3 } }
- Nesnenin direk erişimi olan nesne ve özelliklere ait metodlar.
public class OrnekSinif { DigerSinif digerSinif = new DigerSinif(); public void AcikIslemYap() { digerSinif.BaskaIslemYap(); // Nesnenin direk erişimi olan nesnenin metodunu çağırıyor, LoD 4 } }
Eğer kodlar içerisinde aşağıdaki gibi zincirleme bir metod çağrımı görüyorsanız. Bazı istisnalar olsa da büyük bir ihtimalle LoD’a uymayan bir kod yazmış bulunuyorsunuz.
nesne.GetirDigerNesne().DigerNesneninMetodu()
Daha anlaşılır olması adına şöyle de yazabiliriz.
hesap.OkuMusteri().OkuIletisimAdresi().OkuIlce()
Tabii LoD’u sadece zincirleme metod çağrımına karşı olan bir pratik olarak düşünmek doğru olmaz. LoD temelde şuna dayanır:
Bir bilgiyi nesnenin dışarısından çekmek yerine nesnenin kendisinden almalısınız.
Yukarıdaki örnek üzerinden düşünecek olursak hesap nesnesi OkuMusteri’den dönen Musteri nesnesi üzerinden dönen IletisimAdresi üzerinden Ilce’ye ulaşıyor. Eğer hesap nesnesinde bir ilçe bilgisi gerekiyor ise dış dünyanın öncelikle müşterinin okunduğunun sonrasında IletisimAdresinin okunduğunun (belki de ileride değişecek, ResmiAdres okunacak) bilgisine ihtiyacı yok. Onlar sadece hesaptaki ilçe bilgisini istiyorlar. Bu durumda aşağıdaki gibi bir kullanım tercih edilebilir.
hesap.OkuIlce()
Yeni OkuIlce metodu kendi içerisinde IletisimAdresini ya da ResmiAdresi seçebilir. Bu değişiklik metod kullanıcılarını etkilemeyecektir.
Tabii, diğer pattern ve pratiklerde olduğu gibi LoD’un kullanımının tercih edileceği ya da vazgeçilmesinin gerekeceği durumlar olacaktır. Bunun kararının verilmesi için biraz acı ve biraz tecrübe gerekecektir. 🙂 Ancak geliştirme sırasında LoD’u göz önünde bulundurmak oldukça fayda sağlayacaktır.