SPI ve API arasındaki fark nedir?


Yanıtlar:


395
  • API, bir hedefe ulaşmak için çağırdığınız ve kullandığınız sınıfların / arayüzlerin / yöntemlerin / ... açıklamasıdır ve
  • SPI, bir hedefe ulaşmak için genişlettiğiniz ve uyguladığınız sınıfların / arayüzlerin / yöntemlerin / ... tanımlarıdır .

Farklı bir ifadeyle, API size belirli bir sınıfın / yöntemin sizin için ne yaptığını ve SPI size uymak için ne yapmanız gerektiğini söyler.

Genellikle API ve SPI ayrıdır. Örneğin, JDBC içinde sınıf SPI parçasıdır: basitçe JDBC kullanmak istiyorsanız, doğrudan kullanmak gerekmez, ancak bir JDBC sürücüsünü uygulayan herkes sınıfını uygulamalıdır.Driver

Ancak bazen çakışırlar. Arayüz olan hem SPI ve API: Bir JDBC sürücüsünü kullanmak ve JDBC sürücüsünün geliştirici tarafından uygulanması gerekmektedir zaman rutin kullanabilirsiniz.Connection


kulağa doğru geliyor. SPI & API arasındaki çizgiler biraz gri olabilir, çünkü çoğu API, kullanıcının da işleri halletmesi için uygulayacağı soyut sınıflara / arayüzlere sahiptir ...
kctang

1
@koss: en çok API? Ne demek istediğini biliyorum, ama bunları çok fazla görmüyorum.
Joachim Sauer

2
API, geliştiriciler için daha alakalı, SPI ise satıcılar için geçerlidir.
Azfar Niaz

7
@AzfarNiaz: Peki, satıcılar ürünlerini geliştirmek için geliştiriciler istihdam ettikleri için her ikisi de geliştiricilerle ilgilidir ;-)
Joachim Sauer

Java'da ek açıklamalar bir SPI'nın parçası mı? Örneğin, bir @SomeAnnotationçerçeveyle alınmasını sağlamak için sınıfıma eklemem gerekirse , bu açıklama sınıfı SomeAnnotation.classteknik olarak genişletmeme veya uygulamadığım halde SPI'nin bir parçası olarak kabul edilir mi?
Adam Burley

59

Gönderen Etkili Java, 2. Baskı :

Hizmet sağlayıcı çerçevesi, birden çok hizmet sağlayıcısının bir hizmet uyguladığı bir sistemdir ve sistem, uygulamaları müşterilerinin kullanımına sunar ve bunları uygulamalardan ayırır.

Bir servis sağlayıcı çerçevesinin üç temel bileşeni vardır: sağlayıcıların uyguladığı bir servis arayüzü; sistemin uygulamaları kaydetmek için kullandığı ve istemcilere bunlara erişim sağlayan bir sağlayıcı kayıt API'sı; ve istemcilerin hizmetin bir örneğini almak için kullandıkları bir hizmet erişim API'sı. Hizmet erişim API'sı genellikle istemcinin bir sağlayıcı seçmek için bazı ölçütler belirtmesine izin verir ancak bunu gerektirmez. Böyle bir belirtimin olmaması durumunda, API varsayılan uygulamanın bir örneğini döndürür. Hizmet erişim API'sı, hizmet sağlayıcı çerçevesinin temelini oluşturan “esnek statik fabrika” dır.

Hizmet sağlayıcı çerçevesinin isteğe bağlı dördüncü bileşeni, hizmet sağlayıcıların hizmet uygulamalarının örneklerini oluşturmak için uyguladıkları bir hizmet sağlayıcı arabirimidir. Bir servis sağlayıcı arayüzü olmadığında, uygulamalar sınıf adına göre kaydedilir ve yansıtıcı bir şekilde somutlaştırılır (Madde 53). JDBC durumunda, Bağlantı hizmet arabiriminin bir bölümünü oynatır, DriverManager.registerDriver sağlayıcı kayıt API'sı, DriverManager.getConnection hizmet erişim API'sı ve Sürücü servis sağlayıcı arabirimidir.

Servis sağlayıcı çerçeve modelinin sayısız çeşidi vardır. Örneğin, servis erişim API'sı, Adaptör kalıbını kullanarak, sağlayıcıdan gerekenden daha zengin bir servis arayüzü döndürebilir [Gamma95, s. 139]. Bir servis sağlayıcı arayüzü ve bir varsayılan sağlayıcı ile basit bir uygulama:

// Service provider framework sketch

// Service interface
public interface Service {
    ... // Service-specific methods go here
}

// Service provider interface
public interface Provider {
    Service newService();
}

// Noninstantiable class for service registration and access
public class Services {
    private Services() { }  // Prevents instantiation (Item 4)

    // Maps service names to services
    private static final Map<String, Provider> providers =
        new ConcurrentHashMap<String, Provider>();
    public static final String DEFAULT_PROVIDER_NAME = "<def>";

    // Provider registration API
    public static void registerDefaultProvider(Provider p) {
        registerProvider(DEFAULT_PROVIDER_NAME, p);
    }
    public static void registerProvider(String name, Provider p){
        providers.put(name, p);
    }

    // Service access API
    public static Service newInstance() {
        return newInstance(DEFAULT_PROVIDER_NAME);
    }
    public static Service newInstance(String name) {
        Provider p = providers.get(name);
        if (p == null)
            throw new IllegalArgumentException(
                "No provider registered with name: " + name);
        return p.newService();
    }
}

3
servis sağlayıcı çerçevesindeki çok güzel açıklama için teşekkürler. bunu bilmek faydalı olacaktır. Ancak, açıkça api & spi arasındaki "fark" açıklamıyor bu yüzden burada bir kene koymak olmaz ... ;-)
kctang

23

API ve SPI arasındaki fark, bir API ek olarak bazı somut uygulamalar sağladığında ortaya çıkar. Bu durumda, servis sağlayıcı birkaç API (SPI adı verilir) uygulamak zorundadır

Bir örnek JNDI:

JNDI, arayüz araması için arabirimler ve bazı sınıflar sağlar. Bir bağlamı aramanın varsayılan yolu IntialContext'de sağlanır. Bu sınıf dahili olarak sağlayıcıya özel uygulamalar için SPI arabirimlerini (NamingManager kullanarak) kullanır.

Daha iyi anlamak için aşağıdaki JNDI Mimarisine bakın.

Resim açıklamasını buraya girin


22

API , Uygulama Programlama Arayüzü anlamına gelir; burada API, bir tür yazılım veya platform tarafından sağlanan bir hizmete / işleve erişmek için bir araçtır.

SPI , SPI'nın yazılım veya platform için davranışı enjekte etmenin, genişletmenin veya değiştirmenin bir yolu olduğu Servis Sağlayıcı Arayüzü anlamına gelir.

API normalde istemcilerin bir hizmete erişmesi için hedeftir ve aşağıdaki özelliklere sahiptir:

-> API, belirli bir davranış veya çıktıyı elde etmek için bir hizmete erişmenin programlı bir yoludur

-> API evrimi açısından, ekleme işlemi müşteriler için hiç sorun değil

-> Ancak API'ler müşteriler tarafından bir kez kullanıldığında, uygun bir iletişim olmadığı sürece değiştirilemez / silinemez, çünkü müşteri beklentisinin tamamen bozulması

Öte yandan SPI sağlayıcılar için hedeflenmiştir ve aşağıdaki özelliklere sahiptir:

-> SPI, bir yazılımın veya platformun davranışını genişletmenin / değiştirmenin bir yoludur (programlanabilir ve programatik)

-> SPI evrimi API evriminden farklı, SPI kaldırılmasında bir sorun yok

-> SPI arabirimlerinin eklenmesi sorunlara neden olur ve mevcut uygulamaları bozabilir

Daha fazla açıklama için buraya tıklayın: Servis Sağlayıcı Arayüzü


12

NetBeans SSS: SPI nedir? Bir API'dan farkı nedir?

API genel bir terimdir - Uygulama Programlama Arayüzü'nün kısaltması - diğer yazılımların onunla iletişim kurmasına izin veren bir yazılım parçası (Java'da, genellikle bazı Java sınıflarında) ortaya çıkar.

SPI, Servis Sağlayıcı Arayüzü anlamına gelir. Bu, bir kütüphanenin uygulama (veya API kütüphanesi) tarafından çağrılan ve genellikle uygulamanın yapabildiği şeyleri değiştiren sınıflar sağladığı durumlara özel API olabilecek tüm şeylerin bir alt kümesidir.

Klasik örnek JavaMail'dir. API'sının iki tarafı vardır:

  • Bir API istemcisi yazıyorsanız veya bir posta kutusunu okumak istiyorsanız aradığınız API tarafı
  • JavaMail'in haber veya IMAP sunucusu gibi yeni bir sunucuyla konuşmasına izin vermek için bir tel protokol işleyicisi sağlıyorsanız SPI tarafı

API kullanıcılarının nadiren SPI sınıflarını görmesi veya konuşması gerekir, bunun tersi de geçerlidir.

NetBeans'te, SPI terimini gördüğünüzde, genellikle bir modülün çalışma zamanında enjekte edebileceği ve NetBeans'in yeni şeyler yapmasına izin veren sınıflardan bahsedilir. Örneğin, sürüm kontrol sistemlerinin uygulanması için genel bir SPI vardır. Farklı modüller CVS, Subversion, Mercurial ve diğer revizyon kontrol sistemleri için bu SPI'nın uygulamalarını sağlar. Bununla birlikte, dosyalarla (API tarafı) ilgilenen kodun, bir sürüm kontrol sistemi olup olmadığını veya ne olduğunu dikkate alması gerekmez.


5

Çok vurgulanmış gibi görünmeyen, ancak API / SPI bölünmesinin varlığının ardındaki mantığı anlamak için çok önemli olan bir yönü vardır.

API / SPI bölünmesi yalnızca platformun gelişmesi bekleniyorsa gereklidir. Bir API yazar ve " bilirseniz " daha sonra herhangi bir iyileştirme gerektirmeyeceğini , kodunuzu iki bölüme ayırmak için gerçek bir neden yoktur (temiz nesne tasarımı yapmanın yanı sıra).

Ancak bu neredeyse hiç böyle değildir ve insanların geriye dönük olarak uyumlu bir şekilde API'ları gelecekteki gereksinimlerle birlikte geliştirme özgürlüğüne sahip olmaları gerekir.

Yukarıdakilerin hepsinin, tüm istemci kodlarının kontrol altında olduğu ve böylece ihtiyacınız olduğunda yeniden düzenleme yapabileceğiniz kendi API'nızı değil, diğer kişilerin kullandığı ve / veya genişlettiği bir platform oluşturduğunuzu varsayalım.

Bunu iyi bilinen Java nesnelerinden birinde gösterelim Collectionve Collections.


API: Collections bir dizi yardımcı statik yöntemdir. Genellikle API nesnesini temsil eden sınıflar final, hiçbir istemcinin yapamayacağı şekilde (derleme zamanında) tanımlanır bu nesneyi "uygulayamadığını " ve (statik yöntemlerini "çağırmaya" bağlı olabileceğini

Collections.emptySet();

Tüm istemciler "çağırıyor" ama "uygulamıyor" olduğundan , JDK yazarları yeni yöntemler eklemek için ücretsiz olarakCollections JDK geleceği sürümünde nesne. Muhtemelen milyonlarca kullanım olsa bile herhangi bir müşteriyi kıramayacağından emin olabilirler.


SPI: Collection Herkesin kendi sürümünü uygulayabileceğini ima eden bir arayüzdür. Böylece, JDK yazarları kendi Collectionuygulamalarını yazan tüm istemcileri (*) kıracağı için yeni yöntemler ekleyemezler .

Genellikle ek yöntemin eklenmesi gerektiğinde yeni arayüz, ör. Collection2 , öncekini genişleten oluşturulması gerekir. SPI istemcisi daha sonra SPI'nin yeni sürümüne geçip eklenmeyeceğine veya ek yönteminin uygulanıp uygulanmayacağına veya eskisine bağlı kalıp kalmayacağına karar verebilir.


Bu noktayı zaten görmüş olabilirsiniz. Her iki parçayı tek bir sınıfta birleştirirseniz, API'nız herhangi bir eklemeden engellenir. İyi Java API'lerinin ve Frameworks abstract classuygulamasının, geriye dönük uyumluluk açısından gelecekteki evrimini engelleyecekleri için ortaya çıkmamasının nedeni de budur .

Hala net olmayan bir şey varsa , yukarıdakileri daha ayrıntılı olarak açıklayan bu sayfayı kontrol etmenizi öneririz .


(*) Bunun yalnızca defaultbir arabirimde tanımlanan yöntemler kavramını tanıtan Java 1.8'e kadar geçerli olduğunu unutmayın .


4

Bir API'nın belirli özelliklerini uygulayarak ve daha sonra kendisini hizmet arama mekanizmaları aracılığıyla kullanılabilir olarak kaydederek bir SPI yuvasını daha büyük bir sisteme sanırım. Bir API, son kullanıcı uygulama kodu tarafından doğrudan kullanılır, ancak SPI bileşenlerini entegre edebilir. Kapsülleme ile doğrudan kullanım arasındaki farktır.


cevap için teşekkürler chris. mevcut Java (örn. Servlet, JDBC, vb.) kitaplıklarının herhangi bir örneği ... onları API / SPI yapma biçimi gibi. sadece açıklama ile farkı görselleştirmek zor olabilir.
kctang

1
Bir API JDBC'dir, JDBC için bir SPI, SPI geliştiricilerinin geliştiricinin kullanım için seçebilecekleri yeni veritabanı bağlayıcıları oluşturmak için kullanabileceği veritabanı bağlayıcı arabirimidir.
Chris Dennett

4

Servis sağlayıcı arayüzü, tüm sağlayıcıların uygulaması gereken servis arayüzüdür. Mevcut sağlayıcı uygulamalarının hiçbiri sizin için işe yaramıyorsa, kendi servis sağlayıcınızı yazmanız (servis arayüzünü uygulamanız) ve bir yere kaydolmanız gerekir (Roman tarafından gönderilen faydalı yazıya bakın).

Hizmet arabiriminin mevcut sağlayıcı uygulamasını yeniden kullanıyorsanız, temel olarak söz konusu sağlayıcının API'sini kullanırsınız; bu hizmet arabiriminin tüm yöntemlerini ve kendi başına birkaç genel yöntemi içerir. SPI dışında sağlayıcı API'sı yöntemleri kullanıyorsanız, sağlayıcıya özgü özellikleri kullanıyorsunuzdur.


2

Java dünyasında, farklı teknolojilerin modüler olması ve bir uygulama sunucusuna "takılması" amaçlanmaktadır. O zaman arasında bir fark var

  • uygulama sunucusu
    • [SPI]
  • takılabilir teknoloji
    • [API]
  • son kullanıcı uygulaması

Bu tür teknolojilere iki örnek JTA (işlem yöneticisi) ve JCA'dır (JMS veya veritabanı için adaptör). Ama başkaları da var.

Böyle bir takılabilir teknolojinin uygulayıcısı daha sonra uygulamada takılabilir olması için SPI'yi uygulamalıdır. sunucusuna gidin ve son kullanıcı uygulaması tarafından kullanılacak bir API sağlayın. JCA'dan bir örnek, SPI'nin bir parçası olan ManagedConnection arabirimi ve son kullanıcı API'sının bir parçası olan Bağlantı'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.