Seperti yang saya pahami, desain top-down adalah dengan menyempurnakan konsep abstrak tingkat tinggi menjadi bagian-bagian yang lebih kecil dan dapat dipahami, sampai blok bangunan terkecil didefinisikan. Di sisi lain, bottom up mendefinisikan bagian tingkat rendah, kemudian secara bertahap membangun blok tingkat yang lebih tinggi sampai seluruh sistem terbentuk.
Dalam praktiknya, dikatakan terbaik untuk menggabungkan dua metode: dimulai dengan spesifikasi tingkat tinggi untuk sepenuhnya menentukan pengetahuan domain, hubungan dan batasannya. Setelah masalah dipahami dengan baik, blok bangunan terkecil dibuat untuk membangun sistem.
Proses dari:
- Membuat spesifikasi kebutuhan
- Buat spec desain (dengan diagram)
- Melaksanakan
- Kirim
- Ulangi (dalam pengembangan berulang, daripada melakukan seluruh potongan di setiap fase, kami melakukan sedikit setiap kali berulang-ulang, dan mendapatkan pertemuan harian untuk beradaptasi dengan kebutuhan dinamis pelanggan)
terlihat sangat normal bagi saya (dengan spesifikasi sebagai rencana). Ini memiliki kekurangannya tetapi itulah sebabnya kami mendapatkan pengembangan berulang: alih-alih menghabiskan waktu pada satu fase, kata, analisis kebutuhan untuk mempelajari setiap hal yang mungkin dalam pengetahuan domain yang mengalami perubahan (mungkin setiap hari), kami melakukan sedikit analisis, sedikit desain lalu mengimplementasikannya.
Cara lain adalah bahwa setiap iterasi adalah mode air terjun mini, di mana analisis dilakukan dalam beberapa hari (atau seminggu). Hal yang sama berlaku untuk desain. Sisa waktu dihabiskan untuk implementasi. Apakah ada sesuatu yang salah dengan pendekatan top-down yang dikombinasikan dengan pengembangan berulang?
Dalam esainya Programming Bottom Up , Paul Graham tampaknya mendorong pembangunan dari bawah sepenuhnya, atau memprogramnya dari bawah ke atas, tetapi bukan tahap analisis / desain kebutuhan:
Pemrogram Lisp berpengalaman membagi program mereka secara berbeda. Seperti halnya desain top-down, mereka mengikuti prinsip yang bisa disebut desain bottom-up - mengubah bahasa agar sesuai dengan masalah.
Sejauh yang saya dapat, maksudnya adalah bahwa Lisper masih melakukan desain top-down, tetapi program bottom-up, apakah itu benar? Poin lain yang dia tulis:
Patut ditekankan bahwa desain bottom-up tidak berarti hanya menulis program yang sama dalam urutan yang berbeda. Ketika Anda bekerja dari bawah ke atas, Anda biasanya berakhir dengan program yang berbeda. Alih-alih program monolitik tunggal, Anda akan mendapatkan bahasa yang lebih besar dengan operator yang lebih abstrak, dan program yang lebih kecil ditulis di dalamnya. Alih-alih ambang pintu, Anda akan mendapatkan lengkungan.
Apakah ini berarti bahwa selama periode penulisan program di Lisp, Anda berakhir dengan alat generik?
Jawaban:
Top-down adalah cara yang bagus untuk menggambarkan hal-hal yang Anda ketahui, atau membangun kembali hal-hal yang sudah Anda bangun.
Masalah top-down terbesar adalah bahwa seringkali tidak ada "top". Anda akan berubah pikiran tentang apa yang harus dilakukan sistem saat mengembangkan sistem dan saat menjelajahi domain. Bagaimana bisa titik awal Anda sesuatu yang tidak Anda ketahui (yaitu apa yang Anda ingin sistem lakukan)?
Top down "lokal" adalah hal yang baik ... beberapa pemikiran di depan pengkodean jelas baik. Tetapi berpikir dan merencanakan terlalu banyak bukanlah, karena apa yang Anda bayangkan bukanlah skenario nyata (kecuali Anda sudah pernah ke sana sebelumnya, yaitu jika Anda tidak membangun, tetapi membangun kembali). Global top-down ketika membangun hal-hal baru tidak masuk akal.
Bottom-up harus (secara global) pendekatan kecuali Anda tahu 100% dari masalah, Anda hanya perlu solusi yang dikenal untuk dikodekan dan Anda tidak peduli mencari kemungkinan solusi alternatif.
Pendekatan Lisp adalah bottom-up yang disuling. Anda tidak hanya membangun dari bawah ke atas tetapi Anda juga dapat membentuk batu bata seperti yang Anda inginkan. Tidak ada yang tetap, kebebasan adalah total. Tentu saja kebebasan mengambil tanggung jawab dan Anda dapat membuat hal-hal mengerikan dengan menyalahgunakan kekuatan ini.
Tetapi kode mengerikan dapat ditulis dalam bahasa apa pun. Bahkan dalam bahasa-bahasa yang dibentuk sebagai sangkar pikiran, dirancang dengan harapan bahwa dengan bahasa-bahasa itu bahkan monyet bisa menjalankan dan menjalankan program yang baik (sebuah ide yang sangat keliru pada banyak tingkatan sehingga menyakitkan bahkan hanya memikirkannya).
Contoh Anda adalah tentang server web. Sekarang pada 2012 ini adalah masalah yang terdefinisi dengan baik, Anda memiliki spesifikasi yang harus diikuti. Server web hanyalah masalah implementasi. Terutama jika Anda bertujuan untuk menulis server web secara substansial identik dengan gajillion server web lain yang ada di luar sana maka tidak ada yang benar-benar tidak jelas, kecuali beberapa hal kecil. Bahkan komentar Anda tentang RSA masih berbicara tentang masalah yang jelas, dengan spesifikasi formal.
Dengan masalah yang didefinisikan dengan baik, dengan spesifikasi formal dan solusi yang sudah dikenal maka pengkodean hanya menghubungkan di titik-titik. Top down tidak masalah untuk itu. Ini adalah surga manajer proyek.
Namun dalam banyak kasus tidak ada pendekatan terkenal yang terbukti digunakan untuk menghubungkan titik-titik. Sebenarnya sangat sering sulit untuk mengatakan apa saja titiknya.
Misalkan misalnya Anda diminta untuk menginstruksikan mesin pemotong otomatis untuk menyelaraskan bagian-bagian yang akan dipotong ke bahan cetak yang tidak sepenuhnya sesuai dengan logo berulang teori. Anda diberi bagian dan gambar dari bahan yang diambil oleh mesin.
Apa itu aturan pelurusan? Kamu putuskan. Apa itu pola, bagaimana cara mewakilinya? Kamu putuskan. Bagaimana cara menyelaraskan bagian-bagian? Kamu putuskan. Bisakah bagian "ditekuk"? Tergantung, ada yang tidak dan ada yang ya, tapi tentu saja tidak terlalu banyak. Apa yang harus dilakukan jika bahan terlalu cacat untuk memotong sehingga dapat diterima? Kamu putuskan. Apakah semua bahan gulungan identik? Tentu saja tidak, tetapi Anda tidak dapat mengganggu pengguna untuk mengadaptasi aturan penyelarasan untuk setiap gulungan ... yang tidak praktis. Gambar apa yang dilihat kamera? Materi, apa pun artinya ... itu bisa warna, bisa hitam di atas hitam di mana hanya refleks cahaya membuat polanya jelas. Apa artinya mengenali suatu pola? Kamu putuskan.
Sekarang coba desain struktur umum solusi untuk masalah ini dan berikan penawaran, dalam bentuk uang dan waktu. Taruhan saya adalah bahwa bahkan arsitektur sistem Anda ... (ya, arsitekturnya) akan salah. Estimasi biaya dan waktu adalah angka acak.
Kami menerapkannya dan sekarang ini adalah sistem yang berfungsi, tetapi kami berubah pikiran tentang bentuk sistem itu berkali-kali. Kami menambahkan seluruh sub-sistem yang sekarang bahkan tidak dapat dijangkau dari menu. Kami mengganti peran master / slave dalam protokol lebih dari sekali. Mungkin sekarang kita memiliki pengetahuan yang cukup untuk mencoba membangun kembali dengan lebih baik.
Perusahaan lain tentu saja memecahkan masalah yang sama ... tetapi kecuali Anda berada di salah satu perusahaan ini, kemungkinan besar proyek rinci top-down Anda akan menjadi lelucon. Kita bisa mendesainnya dari atas ke bawah. Anda tidak bisa karena Anda belum pernah melakukannya sebelumnya.
Anda mungkin dapat memecahkan masalah yang sama juga. Namun bekerja dari bawah ke atas. Dimulai dengan apa yang Anda ketahui, pelajari apa yang tidak Anda ketahui dan tambahkan.
Sistem perangkat lunak baru yang rumit ditanam, tidak dirancang. Kadang-kadang seseorang mulai mendesain sistem perangkat lunak kompleks baru yang tidak ditentukan dengan spesifik dari awal (catat bahwa dengan proyek perangkat lunak besar yang kompleks hanya ada tiga kemungkinan: a] spesifikasinya kabur, b] spesifikasinya salah dan kontradiktif sendiri atau c] keduanya ... dan paling sering [c] adalah masalahnya).
Ini adalah proyek khas perusahaan besar dengan ribuan dan ribuan jam dilemparkan ke slide powerpoint dan diagram UML saja. Mereka selalu gagal total setelah membakar sejumlah sumber daya yang memalukan ... atau dalam beberapa kasus yang luar biasa mereka akhirnya memberikan perangkat lunak yang terlalu mahal yang hanya menerapkan sebagian kecil dari spesifikasi awal. Dan perangkat lunak itu selalu dibenci oleh pengguna ... bukan jenis perangkat lunak yang akan Anda beli, tetapi jenis perangkat lunak yang Anda gunakan karena Anda terpaksa melakukannya.
Apakah ini berarti saya pikir Anda harus berpikir hanya untuk kode? Tentu saja tidak. Tapi menurut saya konstruksi harus dimulai dari bawah (batu bata, kode beton) dan harus naik ... dan fokus dan perhatian Anda terhadap detail harus dalam arti "memudar" karena Anda semakin jauh dari apa yang Anda miliki. Top-down sering disajikan seolah-olah Anda harus meletakkan tingkat detail yang sama untuk seluruh sistem sekaligus: tetap membelah setiap node sampai semuanya jelas ... dalam modul realitas, subsistem "tumbuh" dari subrutin. Jika Anda tidak memiliki pengalaman sebelumnya dalam masalah khusus, desain top-down Anda dari suatu subsistem, modul atau pustaka akan mengerikan. Anda dapat mendesain perpustakaan yang baik setelah Anda tahu fungsi apa yang harus dimasukkan, bukan sebaliknya.
Banyak ide Lisp semakin populer (fungsi kelas satu, penutupan, pengetikan dinamis sebagai default, pengumpulan sampah, metaprogramming, pengembangan interaktif) tetapi Lisp masih hari ini (di antara bahasa yang saya tahu) cukup unik dalam cara mudah membentuk kode untuk apa yang Anda butuhkan.
Parameter kata kunci misalnya sudah ada, tetapi jika tidak ada, mereka dapat ditambahkan. Saya melakukannya (termasuk verifikasi kata kunci pada waktu kompilasi) untuk kompiler Lisp mainan yang saya coba dan tidak memerlukan banyak kode.
Dengan C ++ sebagai gantinya yang paling banyak Anda dapatkan adalah sekelompok pakar C ++ yang memberi tahu Anda bahwa parameter kata kunci tidak terlalu berguna, atau implementasi templat setengah didukung yang sangat kompleks, rusak, setengah didukung yang memang tidak terlalu berguna. Apakah kelas C ++ objek kelas satu? Tidak dan tidak ada yang bisa Anda lakukan tentang itu. Bisakah Anda melakukan introspeksi saat runtime atau pada waktu kompilasi? Tidak dan tidak ada yang bisa Anda lakukan tentang itu.
Fleksibilitas bahasa Lisp inilah yang membuatnya bagus untuk bangunan dari bawah ke atas. Anda tidak hanya dapat membangun subrutin, tetapi juga sintaks dan semantik bahasa. Dan dalam arti tertentu, Lisp itu sendiri adalah dari bawah ke atas.
sumber
Saya tidak yakin bagaimana jawaban ini akan berlaku untuk Lisp, tetapi saya baru saja selesai membaca Prinsip, Pola, dan Praktek Agile , dan penulisnya, Paman Bob , sangat menganjurkan pendekatan top-down untuk C # (juga berlaku untuk C ++) yang saya gunakan sepenuhnya setuju.
Namun, tidak seperti beberapa jawaban lain yang menarik kesimpulan bahwa pendekatan top-down berarti bahwa dalam interaksi pertama Anda hanya mengirimkan dokumen dan desain keseluruhan, buku ini menunjuk ke metode lain: TDD dikombinasikan dengan desain evolusioner.
Idenya adalah Anda mulai dari atas dan menentukan tingkat abstraksi tertinggi Anda (atau tertinggi lokal) dan segera setelah ditetapkan, Anda membuatnya berfungsi dengan baik sehingga fitur # 1 segera berfungsi. Kemudian ketika Anda menambahkan lebih banyak fitur Anda memperbaiki kode Anda dan mengembangkan desain sesuai kebutuhan sambil selalu tetap menyadari prinsip-prinsip SOLID. Dengan cara ini Anda tidak akan berakhir dengan lapisan abstraksi terlalu banyak dan Anda tidak akan berakhir dengan desain tingkat rendah yang tidak sesuai dengan arsitektur keseluruhan. Jika Anda tidak yakin apa artinya ini, buku yang saya sebutkan di atas memiliki bab penuh dengan contoh di mana pengembang mengambil konsep dan mulai dengan diagram UML dan kelas tingkat rendah, hanya untuk menyadari setengah dari kelas-kelas itu tidak diperlukan begitu pengkodean benar-benar dimulai. Pada dasarnya dengan pendekatan ini, kode tingkat rendah secara alami ditekan ke bawah karena rincian tingkat lebih tinggi didefinisikan dalam proyek.
Dan terakhir, jika Anda berlatih SOLID, Anda seharusnya tidak mengalami situasi di mana Anda memiliki abstraksi tingkat tinggi yang ditetapkan dan kemudian masuk ke detail dan tiba-tiba menemukan bahwa tidak ada OOD atau abstraksi. Itu bukan benar-benar kesalahan desain top-down, tetapi rekayasa malas.
Jika Anda tertarik untuk membaca lebih lanjut tentang XP dan desain evolusioner, inilah bacaan yang bagus dari Martin Fowler, penulis hebat lainnya: "Is Design Dead?"
sumber
Bagi saya, pernyataan paling penting yang dibuat oleh Paul Graham dalam artikelnya adalah ini:
Atau, seperti yang dikenal dalam lingkaran C ++: Desain Perpustakaan adalah Desain Bahasa (Bjarne Stroustrup)
Ide utama desain top down adalah: pertama Anda merencanakan, lalu Anda membuat kode. Beanow benar ketika ia menulis , bahwa ada masalah ketika kode yang dapat dieksekusi datang terlambat dalam proses. Dalam desain bottom-up Anda selalu memiliki kode, dan kode itu yang dapat diuji.
Juga, kode Anda tidak rata. Maksud saya, itu cenderung memiliki lebih banyak tingkat abstraksi yang lebih kecil. Dalam desain top down orang sering berakhir dengan abstrasi besar ke tingkat sewenang-wenang dan di bawahnya tidak ada abstraksi sama sekali. Kode yang dirancang dari bawah ke atas OTOH sering mengandung kontrol tingkat rendah dan struktur data yang lebih rendah karena cenderung diabstraksi.
sumber
Idealnya, menulis sebuah program dalam bahasa apa pun, bukan hanya Lisp, memungkinkan Anda menulis seluruh rangkaian alat generik yang dapat mempercepat Anda di program berikutnya atau peningkatan kecepatan ke program Anda saat ini.
Dalam praktiknya, melacak alat-alat ini bisa sulit. Dokumentasi buruk dan tidak terorganisir dan orang-orang yang tahu tentang mereka pergi. Dalam praktiknya, menggunakan kembali kode seringkali lebih banyak masalah daripada nilainya. Tetapi jika kode didokumentasikan dan diorganisir dengan baik, dan programmer tetap bertahan (atau menyimpan persediaan kode berguna mereka sendiri) sejumlah besar pekerjaan dapat diselamatkan dengan mengambil kode dari gudang daripada membangunnya kembali.
Semua desain harus dari atas ke bawah atau Anda tidak akan tahu apa yang Anda lakukan. Apakah Anda membangun gudang atau mobil? Anda tidak dapat menemukan yang dengan desain bottom-up. Tetapi jika Anda akan membangun roda depan kiri, Anda mungkin berpikir bahwa Anda mungkin membutuhkan lebih banyak roda nanti, baik untuk proyek ini dan untuk orang lain. Dan jika Anda membangun roda yang dapat digunakan kembali Anda akan memiliki empat untuk harga satu. (Dan 18 untuk trailer traktor yang akan Anda bangun berikutnya, semuanya gratis.)
Perhatikan bahwa tidak seperti mobil nyata dan roda nyata, jika Anda telah membangun satu "roda" perangkat lunak, Anda telah membangun jumlah yang tak terbatas.
Lebih lanjut tentang desain top-down: sementara Anda harus mulai dengan ini, saya merasa berkewajiban untuk menunjukkan bahwa jika Anda tidak dapat membuat roda, Anda perlu mencari tahu sebelum Anda melakukan banyak pekerjaan pada mobil Anda. Jadi, Anda harus bekerja dari bawah ke atas hampir sejajar dengan bekerja dari atas ke bawah. Juga, mengetahui Anda dapat membuat roda mungkin menyarankan banyak proyek yang tidak akan Anda pikirkan sebelumnya, seperti traktor-trailer. Saya pikir pendekatan top-down harus mendominasi, tetapi dengan sentuhan yang sangat ringan.
Jadi, untuk melanjutkan memparafrasekan Paul Graham, idealnya ketika Anda menulis sebuah program Anda berakhir dengan banyak bagian yang dapat digunakan kembali yang dapat menghemat banyak waktu baik pada program asli dan pada orang lain. Untuk menjauhkan diri saya sedikit dari Paul Graham, ini bekerja dalam bahasa apa pun (meskipun beberapa mendorong proses lebih dari yang lain).
Musuh dari proses yang hampir ajaib ini adalah programmer dengan pandangan jangka pendek. Ini mungkin hasil dari cacat kepribadian, tetapi lebih sering dari beralih pekerjaan dan tanggung jawab terlalu cepat, baik di dalam maupun di antara perusahaan yang mempekerjakan.
sumber
Menggunakan pendekatan top-down dengan pengembangan berulang tidak memberikan kode kerja dalam iterasi pertama. Ini memberikan dokumen desain dan dimana pelanggan akan mengalami kesulitan dengan memberikan umpan balik. Respons seperti, "Ya, saya kira (ini terlalu abstrak untuk saya)" tidak akan membantu Anda dalam menentukan spesifikasi sistem yang diinginkan oleh pelanggan.
Alih-alih, Anda hanya membuat ikhtisar umum tentang apa yang diminta. (Persyaratan) untuk digunakan sebagai pedoman umum untuk apa yang mendefinisikan produk jadi dan apa yang pantas diprioritaskan untuk diterapkan. Dari sana Anda membuat produk yang berfungsi untuk setiap iterasi yang benar-benar dapat dipermainkan pelanggan untuk melihat apakah ini yang ada dalam pikiran mereka. Jika tidak, maka itu tidak akan menjadi masalah karena belum ada menghabiskan ratusan jam untuk merancang sistem yang bekerja berbeda dari apa yang diminta pelanggan sekarang.
Saya tidak akan berbicara untuk orang lain. Saya juga tidak membaca esainya. Jawaban yang saya berikan kepada Anda berasal dari pendidikan dan pengalaman saya.
Menggunakan pendekatan ini berarti bahwa Anda akan berakhir dengan blok bangunan yang lebih abstrak. Hanya karena Anda harus membangun subsistem mandiri yang dapat disajikan langsung, Anda tidak dapat membuat desain top-down yang sangat terkait dan harus diimplementasikan sekaligus. Ini meningkatkan re-usability, rawatan tetapi yang paling utama memungkinkan respons yang lebih fleksibel terhadap perubahan.
sumber