Yazdığım her sınıf bir arayüze uymalı mıdır?


10

Typescript'te bir oyun yazıyorum ve bir nesnenin uygulanması yerine bir arabirime dayalı kod yazdığınız " arabirim tabanlı programlama " fikrine uymaya çalışacağım olmaya karar verdim .

Çok sayıda arayüz ve bunları uygulayan sınıflar yazdım, sonra bir adım geri attım ve sınıfların uygulamayı asla değiştirmem gerekmeyecek kadar basit olduğunu fark ettim, çünkü sınıf yapar ( Phaser.Spritetank gibi davranmak için kısıtlı bir şekilde hareket etmek).

Sonra birkaç yıl önce YAGNI fikrini okuduğumu hatırlıyorum , temelde kodunuzu asla kullanamayacağınız şeyleri içerecek şekilde aşırı mühendislik yapmamalısınız.

En iyi uygulamaları izleyerek, her sınıf bir arabirim uygulamalı mı, yoksa gelecekte potansiyel olarak değiştirilmesini beklediğiniz sınıflarla mı sınırlandırmalısınız?


Gerçek bir sınıfı parametre olarak kullandığınızda, bir arabirime, bu sınıfın arabirimine de kod yazdığınızı unutmayın. Kimse sizi belirli bir sınıfı kullanmaya zorlamaz, onu miras alabilir ve tamamen yeni bir işlevsellik sağlayabilirsiniz, ancak bu doğru görünmüyor. İnsanların fikirlerini kafalarına daha kolay sarmaları için arayüzler mevcuttur. Bu üzücü olduğunda, hayır, her şey için gerçekten arayüze ihtiyacınız yok.
Andy

Yanıtlar:


6

Arayüzlere sahip olmanın nedeni, polimorfizmi basitleştirmesidir. Yani gerçek uygulamalarını bilmek yerine örnekleri sözleşme ile gönderebilirsiniz. Örneğin, bir yönteme "Okuyucu" gönderebilirsiniz, böylece böyle bir çağrılan yöntem "read ()" yöntemini kullanabilir. Bir arabirim "Okuyucu" bildirerek, belirttiği yöntemleri uygulayarak herhangi bir nesneyi bu sözleşmeye uygun hale getirebilirsiniz. Bu şekilde, sözleşmenin altında yatan nesneler tamamen farklı olsa bile, herhangi bir arayan belirli yöntemlerin var olacağını varsayabilir.

Bu, polimorfizmi bir temel sınıftan ayırır ve bir sözleşme ima ederek sınıf zinciri sınırları arasında da bunu mümkün kılar.

Şimdi ... Bu sadece aynı şekilde hareket etmek için birden fazla kalıtım zincirine ihtiyacınız varsa veya diğer kullanıcılara iletmek isteyeceğiniz ortak davranışa sahip birçok temel sınıfınız varsa yararlıdır.

Yalnızca BİR devralma zinciriniz (baseclass-> alt sınıf) veya yalnızca tabanınız varsa veya ilgili nesneleri başka birine PASS'a geçirmenize veya genel olarak kullanmanıza gerek yoksa, o zaman bu durumda olduğu gibi arayüz uygulamaları eklemezsiniz. Faydasız.


Arayüzlerin soyutlamaları modellemesi gerektiğini de ekleyeceğim, bu yüzden sadece bir sınıfın tüm kamu üyelerini kaldırarak bunları yaratmayın. Sınıfın neyi temsil ettiğini düşünün ve bunları yalnızca bu türden herhangi bir nesnenin sahip olması gereken arayüze yerleştirin. Ayrıca , tek bir sınıf için birden fazla arabirim (örneğin Movesve Shootstank örneğiniz için) oluşturabilirsiniz.
TMN

7

Arayüzlere gerçekten ihtiyacınız olup olmadığından emin değilseniz, muhtemelen ihtiyacınız yoktur. Bu YAGNI prensibinin çekirdeğidir. Ne zaman sen uygulanmasını takas gerekiyor, o zaman bir arabirim tanıtmak.


6

Her sınıf için bir arayüz oluşturmak biraz fazladır. Tamamen nesneye yönelik bir bakış açısından, her sınıfın zaten bir arayüzü vardır . Bir arabirim, bir sınıfın halka açık yöntemlerinden ve veri üyelerinden başka bir şey değildir.

"Arabirim" terimini " interfaceanahtar kelime kullanılarak tanımlanan bir Java sınıfı " veya "yalnızca genel, saf sanal işlevlere sahip bir C ++ sınıfı" anlamına gelir . Bunlar kullanışlı soyutlamalardır, çünkü bir sınıfın arabirimini uygulanmasından ayırırlar.

Bunu göz önünde bulundurarak, uygun olduğunda arayüzleri kullanın.

  • Bir arayüz için birden fazla uygulama olacak mı? Eğer öyleyse, bu durum ortak, halka açık yöntemleri bir arayüze çıkarmak için bir aday olabilir .

  • Potansiyel bir arayüzün uygulamalarını modülümün iç işleyişini bilmemesi gereken diğer modüllere dağıtacak mıyım? Burada bir arayüz yararlı olabilir, çünkü modüller arasındaki temas noktasının boyutunu azaltır.

Yukarıdaki gelincik kelimelere dikkat edin: "aday" olabilir, "yararlı olabilir". Belirli bir durum için "evet" veya "hayır" diyen sert ve hızlı bir kural yoktur.

Bununla birlikte, her şey için bir arayüze sahip olmak büyük olasılıkla aşırıdır. Bu modeli görürseniz, çok uzağa gidersiniz:

interface I {
  int getA()
  int getB()
  ...
  int getY()
  int getZ()
}

class C : I {
  int getA() { ... }
  int getB() { ... }
  ...
  int getY() { ... }
  int getZ() { ... }
}

Arayüzlerin bir başka nedeni, test sisteminizin dilinize ve test çerçevenize bağlı olabilmesi için gerekli olup olmamasıdır. Umarım bunu yapmanıza gerek yoktur elbette.
Darien

@Darien: Bir test sisteminin arabirimler gerektirebilmesinin nedeni, testin aslında farklı (alay edilmiş) bir uygulama kullanmasıdır;
Bart van Ingen Schenau

Burada harika şeyler var. Sadece bunu düşünmek: Arayüz, bir sınıfın halka açık yöntemlerinden ve veri üyelerinden başka bir şey değildir . Bu bir arabirim uygulaması için doğru olsa da , kesinlikle verilmesine rağmen asla uygulanmayan bir arabirim için kesinlikle geçerli değildir - bu bir kod kokusu olacaktır.
Robbie Dee

Örneğin Java için doğrudur interface, Java'daki her şeyin interfaceaynı zamanda halka açık arayüzü (OO konsepti) olduğu da olur.

Herkes! Yanıtın 2. ve 3. cümlelerini yazın. Lamine edin. Onu cüzdanına koy. Sık başvuru.
radarbob

5

Yeni geliştiricilerin arayüzleri sadece "en iyi uygulama" olduğu söylendiğinden eklediğiniz bir rahatsızlık olarak düşünmesi çok cazip gelebilir. Eğer varsa vardır körü körüne bunu, bu smacks kargo kült programlama .

Bir dizi sınıfı bir araya getirmek yerine, daha büyük gelişmeler için arayüzleri göz önünde bulundurmanız gereken çok iyi nedenler vardır.

Alaycı çerçeveler

Çeşitli katmanlar için nesnelerde işlem yapmak zorunda kalmadan çok katmanlı bir uygulamayı test etmek istiyorsanız, şüphesiz katmanları alay etmek için alaycı çerçeveler kullanmak isteyeceksiniz. Arayüzler burada yaygın olarak kullanılmaktadır.

Bağımlılık enjeksiyonu

Ekledikleri şişkinlik nedeniyle bir şekilde iyilikten düşmüş olsalar da, fikir sağlamdır - bir arayüze dayalı betonlarda kolayca takas etme yeteneği. İlke, fabrika deseni gibi birçok tasarım deseninde de bulunabilir.


Bu yaklaşımlar D' de SOLID ilkelerinden özetlenmiştir . Bunun sürtünmesi - soyutlamaları kullanın, betonları değil.

Tasarım kalıplarının kendisi gibi, ne zaman kullanılacağı da bir yargılama çağrısıdır. Paket servisi olan nokta, arayüzlerin sadece sınıflarınıza yapışmakla kalmayıp aynı zamanda hissetmeniz gerektiği için nasıl yararlı olduğunu anlamaktır. Burada DIP ve YAGNI'nın çeşitli değerleri hakkında iyi bir tartışma var .


Bağımlılık enjeksiyonu ve IoC kaplarının tamamen farklı iki şey olduğuna dikkat edin (biri bir tasarım ilkesidir ve diğeri bu ilkeyi çeşitli çerçeveler kullanarak somut bir şekilde uygulamaya koymanın bir yoludur). DI'yi bir IoC kabı kullanmadan kullanabilirsiniz.
sara

@kai " DI'yi bir IoC kabı kullanmadan kullanabilirsiniz" . Bence daha olgun gelişim mağazaları yapabilir (ve yapabilir). Görünüşte basit bir kavramın kodunu kirletmeye gerek yoktur. Joel de benzer bir görüşe sahip.
Robbie Dee

YAGNI çok zor. Felsefe ne olursa olsun, çoğu durumda, gerçekte, YAGNI köşeleri kesmek için bir bahane olarak kullanılır. Bağlantıdan kaçının daha ciddiye alınmalıdır. Birçok scrum toplantısında görmek sinir bozucu, bir geliştirici kendini başka biri işini bitirmediği için bloke ediyor. Başka bir geliştiriciyi engellemek nasıl zaman kazanıyor? Benim önerim, birleşmeyi önlemek için bir arayüz kullanmak. Tabii ki, Model sınıfları için bir arayüz kullanmak zorunda değildir.
Ripal Barot
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.