a61a2a9ade1061355c0c12e191cf1f97.ppt
- Количество слайдов: 36
Prinsip-Prinsip Desain OO Dana S. K.
Penyebab-penyebab Desain yang Jelek 2
Indikator Rotting Desain Ada empat indikator utama yang akan memberitahu kita bahwa desain (software) kita dikategorikan rotting design (rancangan busuk). Indikator ini tidak orthogonal, tetapi saling terkait dalam cara yang jelas. Keempat indikator ini antara lain – rigidity - kekakuan, – fragility - kerapuhan, – immobility, statis, tidak reuse, dan – viscosity – mengubah s/w dg cara mudah (lupa tujuan awal).
Software Rigidity • Rigidity adalah kecenderungan software sulit untuk diubah, bahkan dalam cara yang mudah • Simtom : setiap perubahan menyebabkan perubahan yang berurutan dalam modul-modul lain yang berhubungan • Dampak : ketika software seperti ini, project manager tidak memperbolehkan developer memperbaiki masalah yang tidak kritis. Keengganan ini berasal dari fakta bahwa mereka tidak tahu kepastian kapan developer menyelesaikan pekerjaan mereka 4
Software Fragility • Fragility adalah kecenderungan software bermasalah pada beberapa bagian kode jika diubah. Bahkan masalah terjadi pada kode-kode yang tidak mempunyai hubungan konseptual dengan bagian kode yang diubah. • Simtom : setiap perbaikan malahan membuat kerusakan yang makin parah, mendatangkan lebih banyak masalah daripada yang diselesaikan (oleh perubahan). • Dampak : setiap saat project manager menyetujui perbaikan, karena takut software akan bermasalah di kemudian hari 5
Software Immobility • Immobility adalah ketidakmampuan untuk reuse software dari proyek lain atau bagain-bagian lain dalam proyek yang sama • Simptom: seorang developer membutuhkan reuse modul. Tapi modul tersebut mempunyai banyak ketergantungan. Setelah berusaha, developer menyimpulkan usaha dan resiko yang dibutuhkan untuk reuse terlalu besar. • Dampak : Software lebih mudah ditulis ulang daripada me-reuse 6
Software Viscosity • Viscosity adalah kecenderungan software/lingkungan pengembangan untuk mengubah software dengan cara mudah daripada mempertahankan tujuan desain awal. • Simtom : Mudah untuk melakukan kesalahan tapi sukar untuk melakukan hal yang benar. • Dampak : Software maintainability menurun karena mengubah dengan cara yang mudah, shortcut, perbaikan sementara dll. 7
Contoh Rigidity dan Immobility Copy Read Keyboard Write Disk Write Printer enum Output. Device {printer, disk}; void Copy(Output. Device dev){ int c; while((c = Read. Keyboard())!= EOF) if(dev == printer) Write. Printer(c); else Write. Disk(c); } void Copy(){ int c; while ((c = Read. Keyboard()) != EOF) Write. Printer(c); } Lecture 3
Penyebab “Bad Design” • Pertimbangan yang jelas: ketiadaan latihan mendisain / ketrampilan disain, perubahan teknologi, batasan sumber daya / waktu, kompleksitas daerah dll. • Pertimbangan yang kurang jelas: – Perangkat lunak menjadi usang dengan proses yang lambat. Bahkan disain yang rapi dan baik dapat merosot di waktu mendatang – Ketergantungan suatu Modul tidak tepat sehingga ketergantungan tidak dapat diatur. – Requirements sering berubah sedemikian hingga desain awal atau perancang sistem tidak dapat mengantisipasinya
OO Design Principles · The Open/Closed Principle (OCP) · The Liskov Substitution Principle (LSP) · The Dependency Inversion Principle (DIP) · The Interface Segregation Principle (ISP) · The Reuse/Release Equivalency Principle (REP) · The Common Closure Principle (CCP) · The Common Reuse Principle (CRP) · The Acyclic Dependencies Principle (ADP) · The Stable Abstractions Principle (SAP) 10
Atribut Utama OCP Software entities should be open for extension, but closed for modification B. Meyer, 1988 / quoted by R. Martin, 1996 • Terbuka untuk perluasan – Tingkah laku modul dapat diperluas • Tertutup untuk modifikasi – Source code dari modul tidak boleh diganti • Modul-modul harus ditulis sehingga dapat diperluas tanpa harus dimodifikasi
Contoh • Bagaimana membuat mobil berjalan secara efektif dengan sebuah mesin turbo? • Hanya dengan mengganti mobilnya • …Seperti design yang telah diberikan
…. Tetapi harus dijaga supaya tertutup • Sebuah class tidak harus bergantung pada sebuah class yang konkret • Tetapi harus bergantung pada sebuah class abstrak • …. . menggunakan abstract concept atau polymorphisme
Strategic Closure No significant program can be 100% closed R. Martin, “The Open-Closed Principle, ” 1996 • Closure tidak komplit tapi strategic • Gunakan abstraksi untuk memperoleh closure yang eksplisit – Menyediakan method-method class yang dapat secara dinamis dipanggil • Untuk mengenali general policy decisions • Gambar kotak sebelum lingkaran – Desain menggunakan abstract ancestor classes • Gunakan pendekatan “data-driven” untuk mencapai closure – Tempatkan volatile policy decisions dalam lokasi yang terpisah • Sebuah file atau objek yang terpisah – Meminimasi perubahan lokasi di masa datang
OCP Heuristics Make all object-data private No Global Variables! • Perubahan pada data public selalu memiliki resiko untuk “open” modul – Mungkin akan memunyai sebuah efek yang memerlukan perubahan pada lokasi-lokasi yang tak terduga. – Error dapat menjadi sukar untuk ditemukan diperbaiki secara tuntas. – Perbaikan-perbaikan dapat menyebabkan error-error di lain tempat • Non-private members dapat dimodifikasi – Kasus 1: “Saya janji bahwa ini tidak berubah” – Dapat mengubah status dari class – Kasus 2: waktu class – Dapat menyebabkan waktu yang tidak konsisten
OCP Heuristics (2) RTTI is Ugly and Dangerous! • RTTI adalah sesuatu yang buruk dan berbahaya – RTTI = Run-Time Type Information – Jika sebuah modul mencoba untuk cast( lihat definisi cast secara OOP ) secara dinamis sebuah base class pointer ke beberapa kelas turunannya, kapanpun anda memperluas hierarki pewarisan, anda dapat mengganti modul – Dapat dikenali dengan struktur tipe switch atau if-else-if • Tidak semua situasi tersebut melanggar OCP seterusnya – Ketika digunakan hanya sebagai sebuah “filter”
Contoh Open/Closed Principle (OCP) 17
Contoh Open/Closed Principle (OCP) 18
Summary Open/Closed Principle (OCP) • Jika kita membuat shape yang baru, misalnya segitiga, kita harus memodifikasi fungsi ‘draw. Shape()' • Dalam aplikasi yang kompleks, statemen switch/case di atas diulang-ulang untuk setiap operasi yang dapat dilakukan pada sebuah shape • Yang lebih buruk adalah setiap model dapat berisi statemen switch/case yang berisi ketergantungan pada setiap kemuingkinan shape yang dapat digambar sehingga jika salah satu shape dimodifikasi, semua modul membutuhkan rekompilasi dan kemungkinan modifikasi • Bagaimanapun, ketika kebanyak modul dalam aplikasi sesuai dengan open/closed principle, maka ketika fitur baru ditambahkan ke aplikasi dengan menambahkan kode baru daripada mengubah kode yang ada. Jadi kode yang ada menjadi tidak bermasalah. 19
Dependency Inversion Principle I. High-level modules should not depend on low-level modules. Both should depend on abstractions. II. Abstractions should not depend on details. Details should depend on abstractions R. Martin, 1996 § Super Class dalam hirarki inheritance seharusnya tidak tahu subclass-nya § Modul-modul dengan implementasi detail tidak menjadi tempat bergantung modul-modul lainnya tapi seharusnya modul-modul yang lain bergantung pada abstraksi-abstraksi § OCP adalah tujuan, DIP adalah mekanisme § LSP adalah jaminan untuk DIP
Procedural vs. OO Architecture Procedural Architecture Object-Oriented Architecture Lecture 3
Contoh Penerapan DIP class Reader { public: virtual int read()=0; }; Copy Reader Writer Keyboard Reader Printer Writer Lecture 3 class Writer { public: virtual void write(int)=0; }; Disk Writer void Copy(Reader& r, Writer& w){ int c; while((c = r. read()) != EOF) w. write(c); }
Heuristik DIP Design to an interface, not an implementation! • Gunakan inheritance untuk mencegah binding langsung ke class-class Interface (abstract class) Client Implementation (concrete class)
Design to an Interface[1] • Abstract classes/interfaces: – Kecenderungan untuk berubah lebih sedikit( dibanding class konkrit ) – Abstraction adalah “hinge point” yang lebih mudah untuk dimodifikasi ( dibanding class konkrit ) – Tidak harus memodifikasi class/interface untuk menghadirkan abstraksi( OCP )
Design to an Interface[2] • Exceptions – Beberapa kelas jarang berubah • Oleh karena itu kecil keuntungan penyisipan abstraction layer • Contoh: String class – Jika seperti itu dapat menggunakan class concrete secara langsung • Seperti pada Java atau C++
DIP Related Heuristic (2) Avoid Transitive Dependencies • Menghindari struktur higher-level layers tergantung pada lower-level abstractions: – Contoh di bawah, Policy layer akhirnya tergantung pada Utility layer. Policy Layer depends on Mechanism Layer depends on Utility Layer
Solution to Transitive Dependencies • Penggunaan pewarisan dan abstract ancestor classes untuk mengurangi transitive dependencies: Policy Layer depends on Policy Service Interface Mechanism Layer depends on Mechan. Service Interface Utility Layer
DIP - Related Heuristic When in doubt, add a level of indirection Jika tidak bisa temukan suatu solusi memuaskan untuk kelas sedang dirancang, maka dilakukan mendelegasikan responbility pada satu atau lebih kelas: Problem Holder Problem Solver
When in doubt, add a level of indirection • Umumnya lebih mudah untuk memindahkan atau memby-pass level indirection daripada menambahnya kemudian Blue class’s indirect message calls to red class fail to meet some criteria (e. g. real-time constraints, etc. ) So, Blue class re-implements some or all of green class’s responsibilities for efficiency and calls red object directly X
DIP Summary • Pengunaan DIP untuk menghindari • Concrete class • Asosiasikan atau agregation concrete class • Ketergantungan pada komponen concrete • Encapsulate invariants (generic algorithms) • Absract interface tidak dirubah • Concrete class menerapkan interface • Concrete class mudah untuk melepaskan dan menggantikan/ replace
The Liskov Substitution Principle (LSP) “What is wanted here is something like the following substitution property: If for each object o 1 of type S there is an object o 2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o 1 is substituted for o 2 then S is a subtype of T. ” (Barbara Liskov, 1988) 31
The Liskov Substitution Principle (LCP) • Client dari base class seharusnya berfungsi dengan baik jika turunan class tersebut di-pass ke client • Dengan kata lain, jika beberapa fungsi mengambil argumen dengan tipe Policy, maka dimungkinkan memanggil sebuah instance Personal Auto Policy yang secara langsung/tidak langsung diturunkan dari Policy. 32
Contoh The Liskov Substitution Principle (LCP) 33
Diskusi The Liskov Substitution Principle (LCP) • Apakah bujur sangkar adalah segu empat? Secara matematis ya, secara behavior, Bujur Sangkar bukan Segi Empat dan behavior adalah aspek software • Hanya jika tipe turunan dapat menggantikan tipe base class-nya. Tipe base class seharusnya tidak membutuhkan informasi tentang object turunannya • Pelanggaran terhadap LSP dipastikan melanggar OCP 34
Jaminan Dukungan terhadap LSP • Object turunan tidak harus mengharapkan user untuk mematuhi pre-kondisi yang lebih kuat untuk base class( tidak boleh lebih kuat ) • Object turunan harus memenuhi semua post kondisi yang dipenuhi base class-nya ( tidak boleh lebih lemah ) • Base class harus menyediakan fungsi virtual termasuk virtual destructor
Bibliography Robert Martin, www. objectmentor. com/publications
a61a2a9ade1061355c0c12e191cf1f97.ppt