Programming to Interface
Baru saja selesai skimming buku Interface Oriented Design. Buku ini menuntas habis mengenai cara kita membuat sistem dengan interface.
Introduction
Di awal buku ini ada contoh mengenai Pizza Ordering. Skenarionya adalah kira2 sebagai berikut.
Kejadiannya ini karena malam2 lapar trus pengen pesan pizza favourite.
Nelepon deh..
Pizza guy : Yapz
Aku : Aku mw pesan pizza jumbo
Pizza : Toppings?
Aku : Pepperoni dan Mushrooms
PIzza : Alamat?
Aku : 1 Oak street
Pizza : 30 menit lagi akan diantar.
Nah.. kita coba bangun interface untuk PizzaOrdering tersebut. Hampir di setiap pemesanan pizza akan mendapati model percakapan seperti itu. Pemesanan pizza memiliki interface yg sama tetapi hanya implementasinya saja yg berbeda. Misalkan kita menelpon pizza yg lain maka yg kita hadapi kemungkinan besar adalah percakapan di atas.
public interface PizzaOrdering { void SetSize(Size size); void SetToppings(Toppings toppings); void SetAddress(Address address); DateTime GetTimeDelivered(); }
Nah.. sekarang kita udh punya interfacenya.. Trus bagaimana kita mendapatkan implementasi dari interface tersebut ? Kita tentu saja butuh Finder. Kita cari di buku telepon atau buku informasi mengenai toko pizza. Dari situ kita akan dapat memilih mana toko pizza yg akan kita hubungi. And then dial the number… Cara kita meng-order pizza tersebut sama tetapi perlakuan toko terhadap proses tersebut kemungkinan besar berbeda. Interfacenya sama tetapi implementasinya berbeda.
Untuk implementasinya kita mungkin akan menggunakan Dependency Injection container (seperti StructureMap, Spring .NET, Castle Windsor etc) untuk menentukan implementasi yg mana sesuai dengan kebutuhan kita.
Programming life
Contoh yg mungkin bisa diterapkan dalam kehidupan sehari2 programmer adalah interface untuk data acess. Kemungkinan kita akan memiliki CRUD interface data acess seperti berikut:
public interface IDao<Entity> { void Save(Entity entity); Entity Get(Guid id); }
kita bisa saja mengimplementasikannya dengan ADO .NET, FIleSystem, Memory, NHibernate dan data access technology lainnya..
so maybe we’ll have
public class AdoDotNetDao<T> : IDao<T> { ..... }
dst.
Interface is Contract
Interface tersebut merupakan kontrak. Jadi apa2 saja yg didefinisikan di interface hal tersebut harus dipenuhi oleh implementasinya. Hal ini diperkenalkan oleh Bertrand Mayer dengan Design by Contract.
Implementasi dari Interface juga tidak boleh membahayakan/merusak state atau intervensi ke program lain. Interface juga tidak boleh mengambil alih sepenuhnya resource seperti database, time, memory, threads. Koneksi2 haruslah dilepas secepatnya setelah operasi tersebut selesai.
Jika implementasi dari inteface tidak dapat memenuhi kontraknya maka secepatnya harus memberitahu pengguna/client. Hal ini dapat dilakukan dengan cara melemparkan exception atau return code. Contohnya adalah interface yg membutuhkan koneksi ke database, disaat database sedang down. Maka interface tersebut sebaiknya memberitahukan bahwa operasi tidak dapat dilakukan.
Berdasarkan dari Design by Contract, interface contract tersebut harus dicek statenya.
Precondition (kondisi sebelum method di interface di invoke)
Postcondition (kondisi setelah method di interface dilaksanakan)
Class Invariants (kondisi yg harus dipenuhi oleh setiap object)
Jika salah satu dilanggar maka interface tersebut gagal melakukan fungsinya. Ada beberapa cara untuk mengecek kontrak yaitu dengan Proxy, AOP dan ada fitur terbaru dari .NET 4.0 yaitu Code Contract.
Follow the protocol
Sama seperti cara menggunakan barang. Katakanlah DVD player. Ketika kita akan menonton movie. Kita harus mengikuti langkah2 penggunaan barang tersebut. Hubungkan DVD player dengan TV. Colokkan ke listrik. Hidupkan DVD dan TV, Open DVD, Insert Disc, etc.. Pada task2 tersebut ada hal2 yg harus dilakukan secara urut. Salah satunya adalah Open DVD dan Insert Disc. KIta gak bakalan bisa insert Disc klo blum kita eject holdernya. Jadi sebelum menggunakan interface kita harus mengetahui protocol standar untuk menggunakan interface tersebut
Dibuku itu juga dijelaskan lagi jenis2 interface.
Data Interface vs Service Interface
dari namanya udh ketauan klo data interface itu berhubungan erat sama data/attribute dan satu lagi berhubungan dengan behaviour. Data interface ini mirip dengan DTO. Jadi isinya mostly getter and setter. Sedangakan Service Interface ini isinya kebanyakan Command/Behaviour. Jika kita membawa lebih dalam lagi kita bisa memisahkan antara command dan behavoiur dan ujung2nya nanti ke arah CQRS. 😀
Pull vs Push Interface
Kalo yg pull model itu lebih kepada kita ask ke interface dan nanti interfacenya jawab. Klo model push ini merupakan penerapan dari observer pattern. Methodnya akan dipanggil sebagai proses notifikasi bahwa sesuatu telah terjadi.
Stateless vs Stateful interface
Statless berarti tidak menyimpan state. Jadi setiap kita memanggil method tersebut kita dipastikan akan mendapatkan hal yg sama dengan kondisi yg sama. Kalau stateful method state sebelum pemanggilan akan mempengaruhi result dari invocation tersebut.
Kelebihan dari statless adalah operasi yg kita lakukan sedikit tetapi parameter yg dilewatkan banyak.
Stateful interface bakalan lebih chatty (banyak roundtrip yg akan terjadi jika dilakukan secara remote).
Stateful interface juga jika diimplementasikan di Service Layer bisa lebih scalable. Karena kita bisa membuat cluster dari service tersebut tanpa memperdulikan state yg dimaintain sebelumnya. Selalu memliki fresh start.
1. dengan interface kita bisa mengurangi dependency client dan component itu sendiri.
2. mudah ganti2 implementasi tanpa harus merubah client, bisa juga dilakukan on saat run time
>mengurangi dependency client dan component itu sendiri
mengurangi coupling dan juga lebih testable. jadi gak perlu tunggu concrete classnya selesai dulu. bisa kelas consumer interface itu langsung bisa di kerjain. bisa pake mocking framework utk ngetestnya. Mocking framework ini ada banyak… NMOck, RhinoMock
>mudah ganti2 implementasi tanpa harus merubah client, bisa juga dilakukan on saat run time
komposisi dengan interface bisa diconfigure pada saat runtime. penerapannya banyak pada design pattern