Perbedaan antara SPI dan API?

Jawaban:

395
  • API adalah deskripsi kelas / antarmuka / metode / ... yang Anda panggil dan gunakan untuk mencapai tujuan, dan
  • SPI adalah deskripsi kelas / antarmuka / metode / ... yang Anda perluas dan terapkan untuk mencapai tujuan.

Dengan kata lain, API memberi tahu Anda apa yang dilakukan kelas / metode tertentu untuk Anda, dan SPI memberi tahu Anda apa yang harus Anda lakukan untuk menyesuaikan diri.

Biasanya API dan SPI terpisah. Misalnya, dalam JDBC yang Driverkelas merupakan bagian dari SPI: Jika Anda hanya ingin menggunakan JDBC, Anda tidak perlu menggunakannya secara langsung, tapi semua orang yang menerapkan driver JDBC harus menerapkan kelas itu.

Namun, terkadang mereka tumpang tindih. The Connectionantarmuka adalah baik SPI dan API: Anda menggunakannya secara rutin ketika Anda menggunakan driver JDBC dan perlu dilaksanakan oleh pengembang driver JDBC.

Joachim Sauer
sumber
Kedengarannya benar. hanya saja garis-garis antara SPI & API bisa sedikit abu-abu karena kebanyakan API memiliki kelas / antarmuka abstrak untuk penggunanya diimplementasikan untuk menyelesaikan sesuatu juga ...
kctang
1
@oss: sebagian besar API? Saya tahu apa maksud Anda, tetapi saya tidak melihat banyak hal.
Joachim Sauer
2
API lebih relevan untuk pengembang sedangkan SPI untuk vendor.
Azfar Niaz
7
@AzfarNiaz: yah, karena vendor mempekerjakan pengembang untuk membangun produk mereka, keduanya relevan untuk pengembang ;-)
Joachim Sauer
Di Jawa, apakah anotasi merupakan bagian dari SPI? Misalnya, jika saya harus menambahkan @SomeAnnotationke kelas saya untuk mengambilnya dengan beberapa kerangka kerja, akankah kelas anotasi ini SomeAnnotation.classdianggap sebagai bagian dari SPI, meskipun saya tidak secara teknis memperluas atau mengimplementasikannya?
Adam Burley
59

Dari Java Efektif, Edisi ke-2 :

Kerangka kerja penyedia layanan adalah suatu sistem di mana banyak penyedia layanan mengimplementasikan suatu layanan, dan sistem membuat implementasi tersedia untuk kliennya, memisahkan mereka dari implementasi.

Ada tiga komponen penting dari kerangka penyedia layanan: antarmuka layanan, yang diimplementasikan oleh penyedia; API pendaftaran penyedia, yang digunakan sistem untuk mendaftarkan implementasi, memberi klien akses ke sana; dan API akses layanan, yang digunakan klien untuk mendapatkan mesin virtual layanan. API akses layanan biasanya memungkinkan tetapi tidak mengharuskan klien untuk menentukan beberapa kriteria untuk memilih penyedia. Dengan tidak adanya spesifikasi seperti itu, API mengembalikan contoh implementasi default. API akses layanan adalah "pabrik statis fleksibel" yang membentuk dasar kerangka penyedia layanan.

Komponen keempat opsional dari kerangka penyedia layanan adalah antarmuka penyedia layanan, yang diterapkan penyedia untuk membuat instance implementasi layanan mereka. Dengan tidak adanya antarmuka penyedia layanan, implementasi didaftarkan oleh nama kelas dan instantiated reflektif (Butir 53). Dalam kasus JDBC, Connection memainkan bagian dari antarmuka layanan, DriverManager.registerDriver adalah API pendaftaran penyedia, DriverManager.getConnection adalah API akses layanan, dan Driver adalah antarmuka penyedia layanan.

Ada banyak varian pola kerangka penyedia layanan. Sebagai contoh, API akses layanan dapat mengembalikan antarmuka layanan yang lebih kaya daripada yang dibutuhkan oleh penyedia, menggunakan pola Adaptor [Gamma95, hal. 139]. Berikut ini adalah implementasi sederhana dengan antarmuka penyedia layanan dan penyedia default:

// 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();
    }
}
Roma
sumber
3
terima kasih atas uraian yang sangat bagus tentang kerangka penyedia layanan. ini akan berguna untuk diketahui. Namun, itu tidak jelas menggambarkan "perbedaan" antara api & spi jadi saya tidak akan memberi tanda centang di sini ... ;-)
kctang
23

Perbedaan antara API dan SPI muncul ketika API juga menyediakan beberapa implementasi konkret. Dalam hal ini, penyedia layanan harus mengimplementasikan beberapa API (disebut SPI)

Contohnya adalah JNDI:

JNDI menyediakan antarmuka & beberapa kelas untuk pencarian konteks. Cara default untuk mencari konteks disediakan di IntialContext. Kelas ini secara internal akan menggunakan antarmuka SPI (menggunakan NamingManager) untuk implementasi khusus penyedia.

Lihat Arsitektur JNDI di bawah ini untuk pemahaman yang lebih baik.

Masukkan deskripsi gambar di sini

Sandeep Jindal
sumber
22

API adalah singkatan dari Application Programming Interface, di mana API adalah sarana untuk mengakses layanan / fungsi yang disediakan oleh beberapa jenis perangkat lunak atau platform.

SPI adalah singkatan dari Service Provider Interface, di mana SPI adalah cara untuk menyuntikkan, memperluas atau mengubah perilaku untuk perangkat lunak atau platform.

API biasanya menargetkan klien untuk mengakses layanan dan memiliki properti berikut:

-> API adalah cara terprogram mengakses layanan untuk mencapai perilaku atau keluaran tertentu

-> Dari sudut pandang evolusi API, penambahan tidak ada masalah sama sekali untuk klien

-> Tetapi API yang pernah digunakan oleh klien tidak dapat (dan seharusnya tidak) diubah / dihapus kecuali ada komunikasi yang sesuai, karena merupakan degradasi lengkap dari harapan klien

SPI pada bagian lain ditargetkan untuk penyedia dan memiliki sifat-sifat berikut:

-> SPI adalah cara untuk memperluas / mengubah perilaku perangkat lunak atau platform (dapat diprogram vs. terprogram)

-> Evolusi SPI berbeda dari evolusi API, dalam penghapusan SPI tidak ada masalah

-> Penambahan antarmuka SPI akan menyebabkan masalah dan dapat merusak implementasi yang ada

Untuk penjelasan lebih lanjut klik di sini: Antarmuka Penyedia Layanan

Venkata Aditya Pavan
sumber
12

FAQ NetBeans: Apa itu SPI? Apa bedanya dengan API?

API adalah istilah umum - akronim untuk Antarmuka Pemrograman Aplikasi - artinya sesuatu (di Jawa, biasanya beberapa kelas Java) yang dipaparkan oleh perangkat lunak, yang memungkinkan perangkat lunak lain berkomunikasi dengannya.

SPI adalah singkatan dari Service Provider Interface. Ini adalah himpunan bagian dari semua hal yang bisa menjadi API khusus untuk situasi di mana perpustakaan menyediakan kelas yang dipanggil oleh aplikasi (atau perpustakaan API), dan yang biasanya mengubah hal-hal yang dapat dilakukan aplikasi.

Contoh klasik adalah JavaMail. API-nya memiliki dua sisi:

  • Sisi API - yang Anda panggil jika Anda sedang menulis klien email atau ingin membaca kotak surat
  • Sisi SPI jika Anda menyediakan penangan protokol kawat untuk memungkinkan JavaMail berbicara dengan server jenis baru, seperti berita atau server IMAP

Pengguna API jarang perlu melihat atau berbicara dengan kelas SPI, dan sebaliknya.

Di NetBeans, ketika Anda melihat istilah SPI, biasanya berbicara tentang kelas yang dapat disuntikkan modul saat runtime yang memungkinkan NetBeans untuk melakukan hal-hal baru. Misalnya, ada SPI umum untuk menerapkan sistem kontrol versi. Modul yang berbeda menyediakan implementasi SPI untuk CVS, Subversion, Mercurial, dan sistem kontrol revisi lainnya. Namun, kode yang berhubungan dengan file (sisi API) tidak perlu peduli jika ada sistem kontrol versi, atau apa itu.

Ondra Žižka
sumber
5

Ada satu aspek yang tampaknya tidak terlalu disorot tetapi sangat penting untuk memahami alasan di balik keberadaan perpecahan API / SPI.

Perpecahan API / SPI hanya diperlukan saat platform diharapkan untuk berkembang. Jika Anda menulis API dan "tahu" itu tidak akan memerlukan perbaikan di masa mendatang, tidak ada alasan nyata untuk memecah kode Anda menjadi dua bagian (selain membuat desain objek bersih).

Tapi ini hampir tidak pernah terjadi dan orang perlu memiliki kebebasan untuk mengembangkan API bersama dengan persyaratan di masa depan - dengan cara yang kompatibel.

Perhatikan bahwa semua hal di atas mengasumsikan Anda sedang membangun platform yang digunakan dan / atau diperluas orang lain dan bukan API Anda sendiri di mana Anda memiliki semua kode klien di bawah kendali dan dengan demikian dapat memperbaiki sesuai kebutuhan Anda.

Mari kita tunjukkan pada salah satu objek Java yang terkenal Collectiondan Collections.


API: Collections adalah seperangkat metode statis utilitas. Seringkali kelas yang mewakili objek API didefinisikan sebagai finalmemastikan (pada waktu kompilasi) bahwa tidak ada klien yang dapat "mengimplementasikan" objek itu dan mereka dapat bergantung pada "memanggil" metode statisnya, misalnya

Collections.emptySet();

Karena semua klien "menelepon" tetapi tidak "menerapkan" , penulis JDK bebas untuk menambahkan metode baru ke Collectionsobjek di versi JDK yang akan datang. Mereka dapat yakin itu tidak dapat menghancurkan klien mana pun, bahkan jika mungkin ada jutaan penggunaan.


SPI: Collection adalah antarmuka yang menyiratkan bahwa siapa pun dapat mengimplementasikan versinya sendiri. Dengan demikian, penulis JDK tidak dapat menambahkan metode baru ke dalamnya karena akan menghancurkan semua klien yang menulis sendiriCollection implementasi (*).

Biasanya ketika metode tambahan diperlukan untuk ditambahkan, antarmuka baru, misalnya Collection2yang meluas yang sebelumnya perlu dibuat. Klien SPI kemudian dapat memutuskan apakah akan bermigrasi ke versi baru SPI dan mengimplementasikan metode tambahan itu atau apakah akan tetap menggunakan yang lebih lama.


Anda mungkin sudah mengerti intinya. Jika Anda menggabungkan kedua bagian menjadi satu kelas, API Anda diblokir dari penambahan apa pun. Itu juga alasan mengapa API dan Kerangka Java yang bagus tidak terbukaabstract class karena mereka akan memblokir evolusi masa depan mereka sehubungan dengan kompatibilitas ke belakang.

Jika ada sesuatu yang masih belum jelas, saya sarankan untuk memeriksa halaman ini yang menjelaskan hal di atas secara lebih rinci.


(*) Catatan ini benar hanya sampai Java 1.8 yang memperkenalkan konsep defaultmetode yang didefinisikan dalam antarmuka.

Martin Janíček
sumber
4

Saya kira slot SPI ke dalam sistem yang lebih besar dengan mengimplementasikan fitur-fitur tertentu dari API, dan kemudian mendaftarkan dirinya sebagai tersedia melalui mekanisme pencarian layanan. API digunakan oleh kode aplikasi pengguna akhir secara langsung, tetapi dapat mengintegrasikan komponen SPI. Perbedaan antara enkapsulasi dan penggunaan langsung.

Chris Dennett
sumber
terima kasih atas tanggapan chris. Adakah contoh perpustakaan Java (yaitu Servlet, JDBC, dll) yang ada? ... seperti bagaimana membuat mereka API / SPI. bisa sulit untuk memvisualisasikan perbedaan hanya dengan deskripsi saja.
kctang
1
API adalah JDBC, SPI untuk JDBC adalah antarmuka konektor basis data yang dapat digunakan pengembang SPI untuk membuat konektor basis data baru yang dapat dipilih pengembang untuk digunakan.
Chris Dennett
4

Antarmuka penyedia layanan adalah antarmuka layanan yang harus diterapkan oleh semua penyedia. Jika tidak ada implementasi penyedia yang ada bekerja untuk Anda, Anda perlu menulis penyedia layanan Anda sendiri (mengimplementasikan antarmuka layanan) dan mendaftar di suatu tempat (lihat posting berguna oleh Roman).

Jika Anda menggunakan kembali implementasi penyedia antarmuka layanan yang ada, pada dasarnya Anda menggunakan API penyedia tertentu itu, yang mencakup semua metode antarmuka layanan plus beberapa metode publik sendiri. Jika Anda menggunakan metode API penyedia di luar SPI, Anda menggunakan fitur khusus penyedia.

tapasvi
sumber
2

Di dunia Java, berbagai teknologi dimaksudkan untuk menjadi modular dan "pluggable" ke dalam server aplikasi. Kemudian ada perbedaan di antara keduanya

  • server aplikasi
    • [SPI]
  • teknologi pluggable
    • [API]
  • aplikasi pengguna akhir

Dua contoh teknologi tersebut adalah JTA (manajer transaksi) dan JCA (adaptor untuk JMS atau database). Tapi ada yang lain.

Pelaksana teknologi pluggable tersebut kemudian harus mengimplementasikan SPI agar dapat dicolokkan ke dalam aplikasi. server dan menyediakan API untuk digunakan oleh aplikasi pengguna akhir. Contoh dari JCA adalah antarmuka ManagedConnection yang merupakan bagian dari SPI, dan Koneksi yang merupakan bagian dari API pengguna akhir.

ewernli
sumber