Uygulamadan önce bir arayüz API'si yazmalı mıyım?


14

Son zamanlarda daha "organize" programlamaya giriyorum ve bir uygulamaya değil, bir arayüze programlamam gerektiğini öğreniyorum. Bunu göz önünde bulundurarak, mümkün olan yerlerde uygulamayı yazmadan önce arabirimlerdeki bir projeyi "taslak haline getirmek" daha iyi olur mu?

Ve eğer durum buysa, 3. taraf kitaplıkların (örneğin Lidgren) kullanılması durumunda, bunları arayüzlere de sarmalı ve IOC kapsayıcıları aracılığıyla çözmeliyim, yoksa bunları arayüzlere maruz bırakmak uygun mudur?


Kişisel deneyimime göre - önce mimariyi tasarlamak iyi - her sınıfın sorumluluğu. Yazmak zorunda değilsiniz, sadece düşünün veya bir kağıda çizin. O zaman kişisel tercih ile ilgili ama uygulamaya başladığınız her yöntem için önce doc yorumları yazmanızı tavsiye ederim. Doküman yazmak gerçekten kod yazmaya başlamadan önce işlevsellik hakkında düşünmenizi sağlar.
Sulthan

Evet ve bunları uygulamadan önce arabirimlere (veya bu konuyla ilgili soyut sınıflara) programlayın. Uygulamalara takılmadan (ve yatırılmadan) önce mesajın istemciden sunucuya ve "tam tersi" akışının elde edilmesine yardımcı olur. Konuyla ilgili çok iyi bir slayt gösterisi: İyi Bir API Nasıl Tasarlanır ve Neden Önemlidir
Marjan Venema

Yanıtlar:


8

Ne yazık ki, bunun genellikle kişisel tercihinize bağlı olduğunu göreceksiniz.

Şimdiye kadar tanımladığınız şey iyi görünüyor. Aslında, isterseniz (ve ben tavsiye ederim) aşağıdaki yaklaşımı kullanabilirsiniz:

  1. Uygulama iskeletinizi Arayüzler, soyut sınıflar (stubbed) ve sınıflar (stubbed) olarak yazın
  2. Testlerinizi bu arayüzlere ve saplamalara karşı yazın (şimdilik başarısız olacaklar)
  3. Uygulamalarınızı yazın (uygulamanızı bitirdiğinizde testleriniz geçmeye başlayacaktır)

Daha fazla "organize" kod yazmaya çalışıyorsunuz. TDD'yi takip etmek size bu konuda yardımcı olacaktır.

Bazı ekstra noktalar:

  • IoC kapları uygundur. Onları ve DI'yi olabildiğince kullanın.
  • Do 3. parti kütüphaneleri sarın. Bu, kodunuz (denetlediğiniz kod) ile 3. taraf kodu (denetlemediğiniz kod) arasındaki bağlantıyı gevşetir

1
Başlangıçta düşündüğüm buydu ama bana YAGNI prensibini ihlal edeceği söylendi. Bitirmediğim birçok projemde bulduğum sorun, yazdıklarımın blob kodunun miktarıyla hızla sürdürülemez hale gelmeleri, çünkü düzgün bir şekilde organize etmiyor veya saldırı planımı planlamıyorum.
Dan Pantry

hangi kısım YAGNI'yi ihlal eder?
MetaFight

3. taraf kütüphanelerin paketlenmesi.
Dan Pantry

2
Sanırım şu şekilde kayboluyor: 3. taraf kütüphanesinin değişme olasılığı nedir? Bunun% 0 şansı varsa, o zaman YAGNI. Ancak, nadiren durum budur. Ayrıca, 3. taraf kütüphanelerini sarma olabilir (örneğin, 3. parti kitaplığımızı alay edemedi ise) birim test etmek için diğer kod daha kolay hale
MetaFight

1
@DanPantry: Üçüncü taraf kitaplıkların sarılması bir YAGNI ihlali değil, "kendi kodunuzun üçüncü taraf kitaplık istilasına" karşı çok gerekli koruma. Bu sadece bir kütüphaneyi değiştirmekten ibaret değil, aynı zamanda MetaFight'ın kütüphanenin daha yeni sürümlerinde, aksi takdirde kendi kodunuzda değişiklik yapılmasını gerektiren değişikliklere karşı bir savunma söylediği gibi. Kütüphaneyi (ve özellikle belirli türlerini sınıflar, numaralar, yapılar vb.) Sararak kendi kodunuzu yalıtırsınız ve kütüphane değiştiğinde (herhangi bir nedenle) değiştirmek için tek bir noktanız olur.
Marjan Venema

13

Evet, bilinen uygulamalardan ziyade arabirimlere karşı kodlama yapmalısınız ve evet, arabirimleri kendi kodunuzdan çıkma yerine ilk olarak oluşturmalısınız.

Her iki tavsiyenin nedenleri büyük ölçüde aynıdır: bilgisayar programlama büyük ölçüde insan faktörleri ile ilgilidir. Birçoğu bunu şaşırtıcı buluyor, ancak düşünün: Aynı bilgi işlem problemini eşit derecede iyi çalışan çözmek için neredeyse sonsuz sayıda farklı yol var. Neredeyse hepsini yazmayanlar (ya da kısa bir süre sonra yazara) anlamamak tamamen imkansızdır.

İyi yazılım mühendisliğinin, kaynak kodun daha sonra üzerinde çalışılmasına izin verecek şekilde istenen etkiyi (makul verimlilikle doğru hesaplama) nasıl elde edeceği ile ilgilidir. Arayüzler ve API'lar bu disiplinin önemli bir parçasıdır: bir problemi aynı anda tek bir tanım düzeyinde düşünmenize izin verir. Bu, iş tutarlılığı kuralları ve aynı zamanda bağlantılı liste uygulamaları hakkında düşünmekten çok daha kolaydır ve bu nedenle endişelerin bu şekilde ayrılmasını zorla uygulamak , istemci programcının kodunuzu istediği gibi kullanmasına izin vermekten daha iyidir.

Bu, yazdıkları her şeyi anladıklarına ikna olan birçok kovboy programcıya inanmak zor, ortalama düşünürlerden çok daha iyi ve "daha az" programcılara sorun veren tüm karmaşıklığı kaldırabiliyor. Kişinin kendi bilişsel sınırlarının farkında olmamak son derece yaygın bir olgudur - bu yüzden kod organizasyonundaki en iyi uygulamalar bu kadar büyük önem taşır (ve çoğu zaman göz ardı edilir).

Tekrarlamak gerekirse, arayüzler ve API engelleri, yalnızca kendinizle işbirliği yaptığınızda bile büyük ölçüde iyidir . Dış kütüphanelere gelince, eğer onlarla iyi düşünülmüş bir API getiriyorlarsa, o kütüphaneyi başka bir kütüphane için değiştirmeyi beklemediğiniz sürece kullandığımda hiçbir sorun görmüyorum. Aksi takdirde, bir sargı veya yolsuzlukla mücadele katmanı çok iyi bir fikir olabilir.


SE'nin kaynak kodunun daha sonra çalışmasına izin verecek şekilde istenen etkiyi elde etme konusundaki görüşünü seviyorum. Keşke her zaman temiz kod için savaştığım son işimde bu kadar iyi ifade edebilseydim!
MetaFight

Sadece her yerde kullanacağım arayüzler olan API'lar için bir adlandırma kuralı var mı? Mesela, eğer bir komut paterni yapıyorsam, buna "komutalar" mı diyebilirim?
Snoop

@StevieV örneğin çeşitli vardır IBlahuyguladığı Blahveya Blahtarafından uygulanan BlahImpl. Her ikisinden de hoşlanmıyorum ve , veya Blahtarafından uygulanan kullanma eğilimindeyim . Ancak her zamanki gibi, mevcut kod tabanınıza ve beklentilerinize uymak, herhangi bir genel standarda göre daha önemlidir. OralBlahWrittenBlahASLBlah
Kilian Foth

4

Sadece arayüzlere körü körüne programlamak yerine, neden Test Odaklı Geliştirme / Tasarım'a (TDD) bakmıyorsunuz?

Birçok kişi TDD'yi bir test uygulaması olarak düşünür, ancak aslında testlerin kodunuzun testlerle nasıl kullanılacağını ortaya koymasına izin veren bir tasarım yaklaşımıdır (başlangıçta birim testleri ile, ancak entegrasyon testleri yoluyla da olabilir).

Arayüzlere programlama, araç setinizde önemli bir silahtır, ancak çoğu şey gibi, her zaman gerekli olmadığı için her zaman uygun çözüm / teknik / uygulama değildir. İhtiyacınız olan arabirimlere programlamalısınız.

TDD'yi kullanmak sizi bu tür arayüzlerin nerede önemli olduğunu ve açıkçası nerede önemli olmadığını keşfetmeye zorlayacaktır. Ve sonunda kod tabanınızda oldukça iyi bir dizi birim testiniz olmalı.

3. taraf kütüphaneleri kullanmaya gelince, bunları uygun durumlarda kendi soyutlamalarınıza sarmanızı şiddetle tavsiye ederim; ve API'nızın müşterilerinin onlar hakkında "bilmesini" istemeyin.

İyi şanslar!

[değiştir: megaflight'ın cevabını gördüm - tamamen katılıyorum]


2
TDD, resmi bir "arayüz" bildirimi olmasa da, implmenetasyondan ziyade arayüz açısından düşünmenizi sağladı.
DougM

1
Bu harika bir cevap. Yeni bir proje üzerinde çalışırken OP'nin asıl sorununa çözüm olduğunu düşündüğüm TDD'yi önermek için +1 ve "TDD'yi kullanmak sizi bu tür arayüzlerin nerede olduğunu keşfetmeye zorlayacaksa tekrar +1 önemli ve açıkçası önemli değil. "
Benjamin Hodgson

2

Bence aşırıya kaçmış. API'nızın kullanıcısının belirli bir şekilde bir şey uygulamak / kullanmak zorunda kalması gerekmiyorsa, onu dışarıda bırakırım. Arayüzler kontrattır, eğer ihtiyacım yoksa neden bana bir tane vereyim?

Bence insanlar arayüzleri aşırı kullanıyor. Çoğu durumda gerekli olmayan bir karmaşıklık katmanı ekliyorsunuz.


İnsanların, düşünmek altında -kullanır arayüzleri. Yeniden kullanılabilir parçalar oluşturmak istiyorsanız, arayüz sadece "olması güzel" bir ek değil, aynı zamanda dikkat edilmesi gereken en önemli şeydir. Elbette gerçek uygulama yanında.
JensG

1

Bir sözleşmeye karşı programlama neredeyse her zaman iyi bir fikirdir. Bu sözleşmenin bir arayüz olması gerekmez, bunun yerine bir sınıf tarafından yerine getirilebilir. Bence, birim test endişeleri ve alaycı çerçeveler nedeniyle arayüzler DI ile birlikte biraz aşırı kullanıldı.

Şahsen sadece bir sözleşmenin 1'den fazla uygulanmasına sahip olabileceğimde veya yapabileceğimde arayüzler getirmeyi tercih ederim. Arayüzler, veri erişimini soyutlamak istediğim depolar için harika, ancak nispeten esnek olmayan büyük olasılıkla standart iş mantığım için daha az.

Artık bir arayüze sahip olmamak, özellikle saflar için, birim testlerinde sorunlara neden olabilir. Ama programımın dışsal bağımlılıklarıyla değil, içsel bağımlılıklarıyla alay etmek istiyorum. Benim testleri kod yapısını yankı değil, kod doğrulaması gerçekleştirmek istiyorum.

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.