The Open Closed Principle (OCP)
Modul haruslah terbuka untuk penambahan tetapi tertutup untuk dimodifkasi. Modul di sini dapat berarti banyak. Dalam lingkup ini adalah kelas.
Ini prinsip oo yg paling penting. jadi kita harus bikin kelas yg bisa di extends tanpa mengubah code yg ada sebelumnya. jadi tinggal bikin kelas baru dan plug and play. semua jalan normal. jadi yg diubah hanya apa yg dilakukan modul atau behaviournya bukan source codenya.
nah tekniknya gimana ??
coba lihat fungsi LogOn. Fungsi tersebut harus diubah setiap kali ada modem baru yg ditambahkan. setiap modem tergantung pada tipe enumerasinya.
struct Modem { // kita harus tambahkan tipe baru jika // akan menambahkan modem. tentu harus compile ulang enum Type {hayes, courrier, ernie) type; }; struct Hayes { Modem::Type type; // Hayes related stuff }; struct Courrier { Modem::Type type; // Courrier related stuff }; struct Ernie { Modem::Type type; // Ernie related stuff }; void LogOn(Modem& m, string& pno, string& user, string& pw) { // di sini kita harus cek tipe modemnya apa // dan kita kemudian menentukan fungsi mana yg // akan dipanggil sesuai dengan tipenya if (m.type == Modem::hayes) DialHayes((Hayes&)m, pno); else if (m.type == Modem::courrier) DialCourrier((Courrier&)m, pno); else if (m.type == Modem::ernie) DialErnie((Ernie&)m, pno) // ketika kita tambah modem yg baru maka // kita harus menambahkan else if yg lain // begitu seterusnya .... }
struktur di atas sulit sekali maintannya karena setiap tambah modem baru pasti kita harus mencari dimana if else akan ditambahkan…
cape deh … jadi kita harus akses source codenya dan ubah di tempat yg tepat dan compile ulang…
Nah kita ubah ke bentuk yg OCP jadi fungsi logonnya hanya tergantung pada interface modem saja. ketika kita mw tambah modem. kita tinggal nambahkan satu kelas saja dan ga usah ubah kelas2 yg lain.
Dynamic Polimorphisme
interface Modem { void Dial(string phoneNumber); void Send(string message); string Receive(); void HangUp(); }
nah skarang fungsi logonnya …
void LogOn(Modem m, string phoneNumber, string user, string pass) { m.Dial(phoneNumber); // dst ... }
jadi yg dimanfaatkan di sana adalah polymorphism.
skarang static polymorphism. yaitu dengan memanfaatkan generic.
public class LogOnManager<T> { void LogOn(T modem, string phoneNumber, string user, string pass) { modem.Dial(phoneNumber); // dst ... } }
jadi ketika perubahan ada kita nyaman melakukannya. Karena kalau kita ubah kode yg sudah berjalan akan besar kemungkinannya ada error atau break dll.