API tasarımı: somut ve soyut yaklaşım - en iyi uygulamalar?


25

Sistemler arasındaki API'leri tartışırken (işletme düzeyinde) ekibimizde genellikle iki farklı bakış açısı vardır: bazı insanlar daha çok şey söyler - diyelim - genel soyut yaklaşım, bazıları ise doğrudan "somut" bir yaklaşım.

Örnek: basit bir "kişi arama" API'sinin tasarımı. somut versiyon olurdu

 searchPerson(String name, boolean soundEx,
              String firstName, boolean soundEx,
              String dateOfBirth)

Somut versiyonun lehine olan insanlar şöyle der:

  • API kendi kendini belgeliyor
  • anlamak kolaydır
  • doğrulaması kolaydır (derleyici veya web servisi olarak: şema doğrulama)
  • ÖPMEK

Ekibimizdeki diğer insan grubu “Bu sadece bir arama kriteri listesi” derdi.

searchPerson(List<SearchCriteria> criteria)

ile

SearchCritera {
  String parameter,
  String value,
  Map<String, String> options
}

bazı numaralandırma tipinde "parametresi" olabilir.

Adaylar diyor ki:

  • API (bildirgesini) değiştirmeden uygulama değişebilir, örneğin daha fazla kriter veya daha fazla seçenek eklemek. Dağıtım zamanında böyle bir değişikliği senkronize etmeden bile.
  • somut değişkende bile dokümantasyon gereklidir
  • şema doğrulama geçersiz kılınır, çoğu zaman daha fazla doğrulamanız gerekir, şema tüm durumları yerine getiremez
  • zaten başka bir sistemle benzer bir API’miz var - yeniden

Karşı argüman

  • geçerli parametreler ve geçerli parametre kombinasyonları hakkında çok sayıda dokümantasyon
  • Daha fazla iletişim çabası çünkü diğer takımlar için anlaşılması daha zor

En iyi uygulamalar var mı? Edebiyat?


3
Tekrarlanan "Dize ilk / ad, boolean soundex" nin açıkça ihlalidir kuru ve bu tasarım adı soundex ile birlikte gitmesi bekleniyor gerçeğini ele başarısız olduğunu göstermektedir. Bunun gibi basit tasarım hatalarıyla karşılaştığımızda, daha karmaşık analizlere devam etmek zor geliyor
gnat

"Somut" un karşıtı "genel" değil, "soyut" dır. Bir kütüphane veya API için soyutlama çok önemlidir ve bu tartışma gerçekten temel bir soru sormakta başarısız oluyor, bunun yerine açıkçası oldukça önemsiz bir stil sorusu üzerine fikre karar veriyor. Seçenek B'nin karşıt argümanları olan FWIW, bir FUD yükü gibi ses çıkarır, API tasarımı yarı temizse ve SOLID ilkelerine uyuyorsa, herhangi bir ek belgeye veya iletişime gerek duymamanız gerekir.
Aaron,

@Aarona bunu gösterdiğiniz için teşekkür eder ("soyut"). Bir çeviri sorunu olabilir, Almancada "generisch" sesler hala bana uygun. Sizin için "gerçekten temel soru" nedir?
erik

4
@Aaronaught: Soru soyut değil. Doğru düzeltme, "genel" in zıtının "somut" değil "spesifik" olduğudur.
Jan Hudec

Bunun bir başka oyu, genel ve özele karşı değil, genel ve özele yönelik. Yukarıdaki "somut" örnek aslında adı, firstName ve dateOfBirth'e özgüdür, diğer örnek ise herhangi bir parametreye özgüdür. Hiçbiri özellikle soyut değildir. Başlığı düzenlerdim ama bir savaş düzenlemeye başlamak istemiyorum :-)
matt freake 12:13

Yanıtlar:


18

Bu, kaç alandan bahsettiğinize ve bunların nasıl kullanıldığına bağlıdır. Yalnızca birkaç alana sahip yüksek yapılandırılmış sorgular için beton tercih edilir, ancak sorgulama çok serbest bir formda olma eğilimindeyse, somut yaklaşım hızlı bir şekilde üç veya dört alandan sonra hantallaşır.

Öte yandan, genel bir API'yi saf tutmak çok zordur. Birçok yerde basit bir ad araması yaparsanız, sonunda birileri aynı beş kod satırını tekrarlamaktan yorulur ve bir fonksiyona sarılırlar. Böyle bir API, her zaman en çok kullanılan sorgular için somut sarmalayıcılarla birlikte genel bir sorgunun melezine dönüşür. Ve bunda yanlış bir şey görmüyorum. Her iki dünyanın da en iyisini verir.


7

İyi API tasarımı bir sanattır. İyi API, zaman geçtikten sonra bile takdir edilir. Bence soyut-somut çizgide genel bir önyargı olmamalı. Bazı parametreler haftanın günleri kadar somut olabilir, bazıları genişletilebilirlik için tasarlanmayı gerektirir (ve bunları somutlaştırmak, örneğin, işlev adlarının bir parçası), ancak bir başkası daha da ileri gidebilir ve zarif olması için API bir geri aramalar sağlamak için ihtiyaç duyduğu veya hatta etki alanına özgü bir dil karmaşıklığı mücadele etmek için yardımcı olacaktır.

Ay'ın altında nadiren yeni şeyler oluyor. Önceki tekniğe, özellikle belirlenmiş standartlara ve formatlara bir göz atın (örneğin, yayınlardan sonra birçok şey modellenebilir, olay açıklamaları ical / vcal olarak hazırlandı). Sıklıkla ve her yerde bulunan varlıkların somut ve öngörülen uzantıların sözlükler olduğu API'nizi kolayca katkı yapın. Belirli durumlarla başa çıkabilmek için iyi bilinen bazı modeller de vardır. Örneğin, HTTP isteğinin (ve benzeri) ele alınması, İstek ve Yanıt nesneleriyle birlikte API'de modellenebilir.

API tasarlamadan önce, dahil edilmeyecek olanlar dahil olmak üzere yönler üzerinde beyin fırtınası yapın, ancak bunun farkında olmalısınız. Bunlara örnek olarak dil, yazı yönü, kodlama, yerel ayar, saat dilimi bilgisi ve benzeri verilebilir. Katların görünebileceği yerlere dikkat edin: listeyi kullanın, onlar için tek bir değer değil. Örneğin, görüntülü sohbet sistemi için API istiyorsanız, yalnızca iki değil (şu anda özellikleriniz böyle olsa da) N katılımcısı varsayarsanız API'niz çok daha faydalı olacaktır.

Bazen soyut olmak, karmaşıklığı önemli ölçüde azaltmaya yardımcı olur: Yalnızca 3 + 4, 2 + 2 ve 7 + 6 eklemek için bir hesap makinesi tasarlasanız bile, X + Y (X ve Y'de teknik olarak uygulanabilir sınırlar) uygulamak çok daha kolay olabilir Y ve ADD_3_4 (), ADD_2_2 () yerine API'nize ADD (X, Y) ekleyin ...

Sonuçta, bir yol ya da diğerini seçmek sadece teknik bir detaydır. Belgeleriniz sık kullanım durumlarını somut bir şekilde tanımlamalıdır.

Veri yapısı tarafında ne yaparsanız yapın, bir API sürümü için bir alan sağlayın.

Özetlemek gerekirse, API yazılımınızla ilgilenirken karmaşıklığı en aza indirmelidir. API'yi takdir etmek için, maruz kalan karmaşıklık seviyesi yeterli olmalıdır. API'nin formuna karar vermek, problem bölgesinin kararlılığına büyük ölçüde bağlıdır. Bu nedenle, yazılımın ve API'sinin hangi yönde büyüyeceği konusunda bir tahmin yapılmalıdır, çünkü bu bilgi karmaşıklığın denklemini etkileyebilir. Ayrıca, API tasarımı insanların anlayabilmesi için var. Bulunduğunuz yazılım teknolojisi alanında herhangi bir iyi gelenek varsa, anlamanıza yardımcı olacağı için onlardan fazla sapmamaya çalışın. Kime yazdığına dikkat et. Daha ileri seviyedeki kullanıcılar genelliği ve esnekliği takdir ederken, daha az deneyime sahip olanlar beton ile daha rahat olabilir. Ancak, oradaki API kullanıcılarının çoğuna dikkat edin,

Literatür tarafında, Öncü Programcılara “Güzel Kod” u önerebilirim. Andy Oram, Greg Wilson'dan, güzelliğin gizli iyiliği algılamakla (ve bir amaç için uygunluk) olduğunu düşündüğümden, Andy Wilson'dan bahsedebilirim.


1

Kişisel tercihim soyut olmakla birlikte şirketimin politikaları beni somutlaştırıyor. Bu benim için tartışmanın sonu :)

Her iki yaklaşım için de artıları ve eksileri listeleyen iyi bir iş çıkardınız ve kazmaya devam ederseniz her iki tarafın lehine çok sayıda argüman bulacaksınız. API'nizin mimarisi doğru bir şekilde geliştirildiği sürece - bugün nasıl kullanılacağını ve gelecekte nasıl gelişip büyüyebileceğini düşündüğünüz anlamına gelir - o zaman her iki durumda da iyi olmalısınız.

İşte karşıt bakış açıları olan iki yer imi:

Soyut Sınıfları Sevme

Arabirimleri Sevme

Kendinize sorun: "API iş gereksinimlerimi yerine getiriyor mu? Başarı için iyi tanımlanmış kriterlerim var mı? Ölçeklenebilir mi?". Bunlar izlenecek gerçekten basit en iyi uygulamalar gibi görünüyor, ancak dürüst olmak gerekirse, somut ve jenerik olmaktan çok daha önemli.


1

Soyut bir API'nin mutlaka doğrulaması daha zor olduğunu söyleyemem. Kriterler parametreleri yeterince basitse ve birbirleri arasında çok az bağımlılık varsa, parametreleri ayrı mı yoksa bir dizide mi geçirmeniz pek fark etmez. Hala hepsini doğrulaman gerekiyor. Ancak bu, kriter parametrelerinin ve nesnelerin kendilerinin tasarımına bağlıdır.

API yeterince karmaşıksa, somut yöntemlere sahip olmak bir seçenek değildir. Bir noktada muhtemelen ya çok parametreli metotlarla veya gerekli tüm kullanım durumlarını kapsamayacak çok basit metotlarla karşılaşacaksınız. Tüketici bir API tasarlama konusundaki kişisel deneyimime bakıldığında, API düzeyinde daha genel yöntemlere sahip olmak ve uygulama düzeyinde belirli gerekli paketleyicileri uygulamak daha iyidir.


1

Değişim argümanı YAGNI ile reddedilmelidir. Temel olarak, genel API'yi farklı bir şekilde kullanan en az 3 farklı kullanım durumunuz olmadıkça, olasılıklar oldukça düşüktür, bunu bir sonraki kullanım durumu ortaya çıktığında (ve ne zaman kullanmanız gerektiğinde değişmek zorunda kalmayacak şekilde tasarlarsınız). durumlarda, tabii ki jenerik arayüze, süreye ihtiyacınız var). Bu yüzden girişimde bulunmayın ve değişime hazır olun.

Her iki durumda da değişikliğin dağıtım için senkronize edilmesi gerekmez. Arabirimi daha sonra genelleştirdiğinizde, geriye dönük uyumluluk için her zaman daha belirgin bir arabirim sağlayabilirsiniz. Ancak uygulamada, herhangi bir dağıtımın o kadar çok değişikliği olacaktır ki, onu yine de senkronize edersiniz, bu nedenle ara durumları test etmeniz gerekmez. Bunu da tartışma olarak görmezdim.

Belgeleme gelince, her iki çözüm de kullanımı kolay ve açık olabilir. Ancak önemli bir argüman olarak duruyor. Arayüzü, gerçek durumlarda kullanmanız kolay olacak şekilde uygulayın. Bazen spesifik daha iyi olabilir, bazen genel olabilir.


1

Soyut arayüz yaklaşımını tercih ederim. Bu tür bir (arama) hizmeti için bir sorgu koymak yaygın bir sorundur ve büyük olasılıkla tekrar ortaya çıkar. Ayrıca, daha genel bir arayüzü tekrar kullanmak için uygun olan daha fazla servis adayı bulabileceksiniz. Bu hizmetler için tutarlı bir ortak arabirim sağlayabilmek için, arabirim tanımında şu anda tanımlanmış sorgu parametrelerini numaralandırmam.

Daha önce belirtildiği gibi - Arabirimi değiştirmeden uygulamayı değiştirme veya genişletme fırsatını seviyorum. Başka bir arama kriteri eklemek, hizmet tanımına yansıtılmamalıdır.

Her ne kadar iyi tanımlanmış, özlü ve açık arayüzleri tasarlamak soru olmasa da, ek olarak her zaman bazı belgeler sağlamanız gerekecektir. Geçerli arama kriterleri için tanım kapsamı eklemek böyle bir yük değildir.


1

Gördüğüm en iyi özeti Rusty'nin ölçeği, şimdi Rusty'nin API Tasarım bildirgesi . Bunu şiddetle şiddetle tavsiye edebilirim. Tamlık uğruna, ölçeğin özetini ilk bağlantıdan alıntıyım (en iyisi, aşağıda daha kötüsü):

İyi API'ler

  • Yanlış anlaşılması imkansız.
  • Derleyici / linker yanlış anlamanıza izin vermez.
  • Yanlış yaparsanız, derleyici uyarır.
  • Açık kullanım (muhtemelen) doğru olanıdır.
  • İsim size nasıl kullanılacağını anlatıyor.
  • Doğru yapın yoksa çalışma zamanında daima kırılır.
  • Ortak kongre izleyin ve doğru olsun.
  • Belgeleri okuyun ve doğru anlayın.
  • Uygulamayı okuyun ve doğru anlayın.
  • Doğru posta listesi iş parçacığını okuyun ve doğru olsun.

Kötü API'ler

  • Posta listesi başlığını okuduğunuzda yanlış anlayacaksınız.
  • Uygulamayı okuyun ve yanlış anlayacaksınız.
  • Belgeleri okuyun ve yanlış anlayın.
  • Yaygın konvansiyonu izleyin ve yanlış anlayın.
  • Doğru yapın ve bazen çalışma zamanında kırılır.
  • İsim, nasıl kullanılamayacağınızı gösterir.
  • Açık kullanım yanlış.
  • Doğru yaparsanız, derleyici uyarır.
  • Derleyici / linker doğru anlamanıza izin vermez.
  • Doğru olmak imkansız.

Buradaki ve buradaki her iki ayrıntı sayfası , her bir noktanın derinlemesine tartışmasıyla birlikte gelir. API tasarımcıları için mutlaka okunması gereken bir şey. Teşekkürler Rusty, eğer bunu okuduysan.


0

Layman'ın sözleriyle:

  • Soyut yaklaşım, çevresinde somut yöntemlerin oluşturulmasına izin verme avantajına sahiptir.
  • Diğer yol, doğru değil.

UDP, kendi güvenilir akışlarınızı oluşturmanıza izin verme avantajına sahiptir. Peki neden neredeyse herkes TCP kullanıyor?
svick

Kullanım durumlarının çoğunluğu da dikkate alınmıştır. Bazı davalara o kadar sık ​​ihtiyaç duyulabilir ki, bu davaları özel kılmak mümkün olabilir.
Roman Susi

0

Eğer uzatırsanız SearchCriteriafikre biraz, böyle oluşturarak size esneklik verebilir AND, ORvb kriterleri. Böyle bir işlevselliğe ihtiyacınız varsa, bu daha iyi bir yaklaşım olacaktır.

Aksi takdirde, kullanılabilirlik için tasarlayın. API'yi, kullanan kişiler için kolaylaştırın. Sık ihtiyaç duyulan bazı temel fonksiyonlarınız varsa (ismini bir kişiyi aramak gibi), doğrudan sağlayın. Gelişmiş kullanıcıların gelişmiş aramalara ihtiyacı varsa, yine de kullanabilirler SearchCriteria.


0

API'nin arkasındaki kod ne yapıyor? Esnek bir şey ise, esnek bir API iyidir. API'nin arkasındaki kod çok spesifikse, üzerine esnek bir yüz koymak, yalnızca API kullanıcılarının, API'nin iddia ettiği her şeyde hüsrana uğrayacağı ve sinirleneceği anlamına gelir;

Kişisel arama örneğiniz için üç alanın da doldurulması zorunlu mu? Öyleyse, ölçütler listesi kötüdür, çünkü sadece düz çalışmayan çok sayıda kullanıma izin verir. O zaman kullanıcının gerekli olmayan girişleri belirtmesini gerektirmiyorsa kötüdür. Adrese göre arama V2'de eklenecek mi? Esnek arayüz, esnek olmayandan daha kolay eklenmesini sağlar.

Her sistemin ultra esnek olması gerekmez, her şeyi yapmaya çalışın, Mimar Astronotu. Esnek bir yay okları vurur. Esnek bir kılıç, kauçuk bir tavuk kadar faydalıdır.

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.