Apakah Dijkstra berniat untuk modularisasi kode, ketika ia menulis tentang pemisahan kekhawatiran?

9

Pertama, saya membaca kutipan makalah Edsger W. Dijkstra tahun 1974 "Tentang peran pemikiran ilmiah":

Biarkan saya mencoba menjelaskan kepada Anda, apa yang menurut selera saya adalah karakteristik untuk semua pemikiran cerdas. Yaitu, bahwa seseorang bersedia untuk mempelajari secara mendalam suatu aspek materi pelajaran seseorang secara terpisah demi konsistensinya sendiri, sepanjang waktu mengetahui bahwa ia hanya menempati diri sendiri dengan salah satu aspek saja. Kita tahu bahwa suatu program harus benar dan kita dapat mempelajarinya hanya dari sudut pandang itu; kita juga tahu bahwa itu harus efisien dan kita dapat mempelajari efisiensinya di lain hari, jadi untuk berbicara. Dalam suasana hati lain kita mungkin bertanya pada diri sendiri apakah, dan jika demikian: mengapa, program itu diinginkan. Tetapi tidak ada yang diperoleh - sebaliknya! - dengan menangani berbagai aspek ini secara bersamaan. Inilah yang kadang-kadang saya sebut "pemisahan kekhawatiran", yang, bahkan jika tidak sepenuhnya mungkin, adalah satu-satunya teknik yang tersedia untuk memesan pemikiran seseorang secara efektif, yang saya tahu. Inilah yang saya maksudkan dengan "memusatkan perhatian seseorang pada beberapa aspek": itu tidak berarti mengabaikan aspek-aspek lain, itu hanya berlaku adil terhadap kenyataan bahwa dari sudut pandang aspek ini, yang lain tidak relevan. Ia sedang berpikiran satu dan banyak jalur secara bersamaan.

Saya melihat pemisahan kekhawatiran modern berbicara tentang modularisasi kode Anda. Namun, membaca kutipan di atas, saya memahami ini sebagai memfokuskan pikiran Anda pada satu tugas tertentu pada satu waktu, sementara tidak fokus pada aspek lain. Bagi saya ini tidak berarti bahwa kode perlu dipisahkan menjadi potongan modular.

Maksudnya, katakan ada kode di depan Anda yang dalam satu file memiliki konsep view, repository, controller, event handling, factory, dll. Semuanya dalam satu file.

Untuk contoh singkat, inilah beberapa kode yang memiliki akses data, dan lihat (keluaran):

$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql)); 
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? '  selected="selected"' : '' ?>>Version <?=$row['ver']?></option>

Dengan menggunakan OO modern saya dapat menempatkan akses data dalam file sendiri menggunakan pola Repositori, kode View dapat masuk ke templat file sendiri, dan saya bisa menghubungkan mereka bersama untuk berkomunikasi melalui controller (atau Action atau Request Handler), dan saya bisa tambahkan pabrik untuk membuat dan memasang berbagai dependensi. Dan saya dapat memiliki file konfigurasi yang mendefinisikan pabrik-pabrik itu. Tentunya itu adalah langkah menjauh dari file tunggal segalanya.

Pertanyaan saya tentang pemisahan masalah adalah seperti ini: membaca kutipan Dijkstra, saya mendapat ide bahwa mungkin dia tidak bermaksud bahwa pemisahan kekhawatiran menjadi "pemisahan kode secara modular (ke dalam file atau fungsi / metode / dll mereka sendiri"), dan yang ia maksudkan adalah lebih memfokuskan pikiran seseorang pada aspek program, tanpa membebani diri Anda berfokus pada aspek penting lainnya yang belum dipertimbangkan saat ini, terlepas dari apakah mereka secara fisik dipisahkan dalam kode, atau tidak.

Lalu mengapa kita membebani diri kita sendiri dengan pemisahan kode modular fisik dan pola desain? Apakah tidak cukup hanya dengan memfokuskan diri pada suatu aspek, terlepas dari bagaimana kode Anda disusun?

Saya tidak berbicara tentang menulis kode spageti paling mengerikan dan kemudian hanya mempertimbangkan aspek itu, yang mungkin akan menjadi beban. Tetapi pada akhirnya, apa yang akan saya tuju adalah, mengapa melakukan pemisahan kode fisik, mengapa membagi kode menjadi file atau bongkahan terpisah (metode), ketika tidak perlu secara mental memfokuskan diri Anda pada suatu aspek?

Haruskah pemisahan kekhawatiran tetap menjadi latihan mental, bukan fisik?
Dengan kata lain, haruskah ada keterputusan antara aspek pemrograman mental (fokus pada) dan fisik (kode pada kertas)?

Dennis
sumber
5
Saya cukup yakin bahwa pada tahun 1974, ia hanya melihat pemrograman modular sebagai pemberian yang jelas, dan itulah sebabnya ia tidak secara eksplisit membahasnya di makalah itu. Makalah Parnas tentang bagaimana memodulasi adalah pada tahun 1972, dan pada saat itu apakah memodulasi tidak lagi menjadi pertanyaan. Bahkan, apa yang Anda gambarkan bahkan bukan pemrograman modular, itu adalah pemrograman terstruktur , yang Dijkstra sendiri sangat mendukung sudah pada tahun 1968 dalam makalah klasiknya "Go To Considered Harmful".
Jörg W Mittag
oke jadi mungkin saya bisa mengerti 'pemisahan kekhawatiran' lebih sebagai latihan fokus mental, dan modularisasi sebagai cara untuk merangkum aspek kode di atas kertas. Namun saya sekarang melihat pemisahan keprihatinan dan modularisasi lebih sebagai konsep terpisah.
Dennis
@ JörgWMittag, dapatkah Anda mendefinisikan perbedaan antara pemrograman terstruktur dan modular? Beberapa tautan di google menyarankan bahwa keduanya sama.
Dennis
Terstruktur = IF, WHILE, FORbukan GOTO. Modular = modul dengan API publik yang terdefinisi dengan ketat dipisahkan dari implementasi dan representasi internal yang tersembunyi. (Misalnya, Modula, Mesa, Modula-2, Modula-3, kemudian dialek Pascal ( UNIT).)
Jörg W Mittag

Jawaban:

2

Dijkstra membuat pernyataan eksplisit tentang cara berpikir. Modularisasi program (dan proses) - dan keinginannya - mungkin merupakan hasil dari pemikiran itu, tetapi poin kunci yang ia buat adalah bagaimana menilai suatu masalah. Program ini biasanya merupakan solusi untuk suatu masalah, dan dengan mengadvokasi "pemisahan keprihatinan", ia menawarkan saran yang bijak. Contoh terbaik dari ini mungkin "optimasi". Lelucon itu adalah: "Ketika berencana untuk mengoptimalkan suatu program, strategi pertama Anda seharusnya: Jangan." Dengan kata lain, Anda ingin fokus untuk membuat program yang benar. Membuatnya cepat dan mewah adalah masalah yang harus dipisahkan - tetapi juga tidak sepenuhnya dihapus juga.

MCL
sumber
14

Pemisahan masalah adalah cara berpikir abstrak yang terdiri dari mempertimbangkan secara terpisah hal-hal yang tidak harus terkait.

Modularisasi (memisahkan kelompok fungsi yang tidak terkait menjadi modul), enkapsulasi (menyembunyikan detail internal modul), dan abstraksi (memisahkan umum dari spesifik, dan ide dari implementasinya) adalah semua cara untuk menerapkan cara berpikir ini dalam domain desain perangkat lunak.

Christophe
sumber
9

Saya akan menyarankan bahwa, sementara makalah ini menarik sejarah, apa yang Dijkstra maksud dengan istilah "pemisahan keprihatinan" lebih dari 40 tahun yang lalu tidak terlalu relevan saat ini. Saat ini digunakan secara luas dalam referensi modulasi.

Ada banyak bukti bahwa modulasi sangat bermanfaat dan bahwa manfaat itu jauh lebih besar daripada "beban" yang ditimpakannya pada kita. Apapun yang Dijkstra maksudkan saat itu, tidak mengubah fakta bahwa potongan-potongan kecil kode, masing-masing berfokus pada satu hal, mengarah pada kode yang lebih mudah untuk ditulis, dibaca, dipahami, dipelihara, dan diuji.

David Arno
sumber
5
Saya pikir perlu dicatat bahwa banyak pemikiran modern tentang Separation of Concerns berasal dari makalah awal yang akhirnya melahirkan Pemrograman Berorientasi Aspek dari IBM. Saya pikir makalah awal (akhir 90-an-awal 2000-an) adalah pengaruh terbesar di sana. Sudah lama dan situs web semuanya berubah. Tidak yakin apakah saya dapat menemukannya lagi.
Berin Loritsch
2
Bagian yang sulit adalah mencoba mendefinisikan apa arti "satu hal". Tanpa itu, idenya tidak berguna dalam hal penulisan kode praktis, dan melakukan kesalahan memiliki efek langsung pada kesulitan menulis, membaca, memahami, memelihara, dan menguji kode.
jpmc26
1
Itu akan sangat membantu kami memahami posisi Anda jika Anda akan (a) menjelaskan apa yang Anda pikir Dijkstra maksud dengan "pemisahan keprihatinan" dan (b) menjelaskan MENGAPA Anda pikir apa yang dimaksudnya tidak lagi relevan.
John R. Strohm
2

Saya dapat memberi Anda sebuah contoh pribadi pemisahan kekhawatiran yang menurut saya sebanding dengan konsep Dijkstra. Ketika saya menganalisis materi pelajaran tertentu dalam perangkat lunak saya membangun tiga pandangan.

  1. Pertama saya perhatikan datanya. Data mewakili predikat logis dari masalah. Kelas dibangun untuk entitas abstrak di dunia nyata, dengan atributnya menjadi parameter abstraksi. Asosiasi antara kelas merupakan pemetaan fungsional antara instance kelas. Tidak ada kode yang terlibat dalam pemikiran pada saat ini dan tidak ada gagasan tentang pemrosesan. Hanya pandangan statis dari logika yang terlibat dalam materi pelajaran.
  2. Kedua, saya mempertimbangkan dinamika. Setiap kelas yang memiliki siklus hidup non-sepele dimodelkan sebagai mesin negara yang terbatas. Ini melibatkan pertimbangan pelaksanaan eksekusi dan sinkronisasi. Sekali lagi, tidak ada kode yang mengetahui bagaimana berbagai hal berinteraksi dan berurutan.
  3. Ketiga saya pertimbangkan pemrosesan. Di sini, pekerjaan algoritmik aktual yang harus dilakukan pada transisi negara atau dalam operasi sinkron lainnya.

Pada akhirnya, seseorang memperoleh pandangan segi tiga dari subjek yang kemudian dapat dirumuskan sebagai kode dalam pengelompokan apa pun yang nyaman untuk kode itu sendiri dan pemeliharaannya. Tiga aspek bukan hanya latihan mental. Saya menghasilkan deskripsi tertulis dari semua sisi. Mengapa? Karena jika subjeknya cukup besar, saya tidak bisa memegang satu aspek pun dalam memori jangka pendek. Jika subjeknya kecil, hampir semua pendekatan akan berhasil karena Anda dapat menyimpan semuanya di kepala Anda.

Motivasi untuk memisahkan masalah adalah untuk mengakomodasi keterbatasan memori jangka pendek manusia. Kita tidak bisa membawa semuanya dalam kepala kita sekaligus, meskipun programmer komputer cenderung lebih mampu daripada kebanyakan orang lain pada sejumlah konsep yang dapat mereka manipulasi dalam ingatan jangka pendek mereka. Agar efektif, memisahkan keprihatinan harus secara sistematismengecualikan satu atau lebih aspek masalah untuk fokus pada beberapa aspek tertentu lainnya. Tentu saja, mengecualikan satu aspek tidak membuatnya hilang dari pertimbangan. Harus ada sarana untuk menggabungkan semua aspek masalah untuk mencapai solusi. Pengalaman menunjukkan bahwa sering kali hasil akhir dari pemisahan dan rekombinasi menghasilkan solusi yang lebih dapat dipahami daripada lompatan raksasa tunggal di mana banyak aspek dapat disatukan. Ini khususnya terjadi ketika ukuran masalahnya besar atau rumit.

andy mangga
sumber
1

Pemisahan masalah adalah konsep logis yang akan menyebar ke model organisasi kode Anda, tidak peduli bagaimana Anda menerapkannya. Benar bahwa file kode hanyalah detail teknis, salah satu cara agar perangkat lunak Anda dapat dikelola. Satu file dengan editor yang baik yang memungkinkan untuk mengecilkan perluasan wilayah mungkin juga cocok untuk Anda (untuk sementara waktu). Atau database relasional yang menyimpan kelas dan metode dalam mode orangtua-anak dalam tabel terpisah bisa berfungsi sebagai media penyimpanan. Tetapi file teks sulit dikalahkan di dunia di mana kode sumber perlu

  • portabel
  • dapat diakses oleh banyak alat eksternal yang berbeda
  • dapat diakses oleh banyak programmer
  • versi dan sebanding
  • skala baik dengan sistem operasi yang sangat baik dalam penanganan file

Intinya adalah bahwa kita manusia tidak pandai berpikir atau berurusan dengan hal-hal yang berbeda sekaligus. Jadi kita memerlukan model yang memungkinkan untuk memikirkan dan mengerjakan satu hal pada satu waktu tanpa bahaya merusak bagian lain yang tidak kita pertimbangkan pada saat itu. Jadi kami membangun, meletakkan satu bata pada satu waktu, memastikan batu bata yang kami letakkan sebelumnya tidak akan mengganggu batu bata yang diletakkan nanti. Dan jika kita ingin mengganti batu bata nanti, segalanya tidak boleh runtuh. Itu adalah model yang bekerja untuk pikiran satu jalur kita.

Ini bukan bagaimana jamur atau ganggang tumbuh ... Bagaimana itu untuk fakta yang merendahkan?

Martin Maat
sumber
-1

Saya percaya jawaban spesifik untuk kutipan Dijkstra telah dialamatkan, karena Anda menyatakan "Menggunakan OO modern saya dapat menempatkan akses data dalam file sendiri" dan bertanya "Haruskah pemisahan kekhawatiran tetap menjadi latihan mental, bukan fisik?" izinkan saya menarik perhatian Anda ke tempat kepala sekolah modern OO mengarahkan kami.

Seseorang harus mengikuti prinsip SOLID dalam mengembangkan menggunakan OO. Berikut ini tautan yang bagus untuk mereka, tetapi, TLDR pada "pemisahan masalah" sebagian besar dalam S dalam SOLID: Prinsip Tanggung Jawab Tunggal atau SRP.

Ini, yang paling pasti, adalah latihan fisik, bukan latihan mental. Sebagai contoh spesifik Anda, MVC (atau saudara kandungnya MVVM dan MVP) mengarahkan seseorang untuk secara fisik memisahkan konser Model, View, dan Controller / Presenter / ViewModel ke dalam file terpisah. Saya telah melihat beberapa implementasi MVVM di mana ini diimplementasikan ke dalam majelis terpisah untuk lebih membatasi kecenderungan seseorang untuk "mencampuradukkan konsep".

Tapi. Ini melampaui sekadar "ini adalah tampilan dan ini adalah model", jika Anda mengikuti pandangan Paman Bob tentang ini.

Kita juga perlu mempertimbangkan sumber persyaratan untuk elemen OO tertentu. Jika Anda mencampur, katakanlah, apa yang diinginkan Pelanggan dengan apa yang diinginkan Personel Operasi, Anda juga melanggar SRP. Atau, seperti kata Paman Bob: Kelas harus memiliki satu dan hanya satu alasan untuk berubah.

Saya sangat menyarankan agar Anda meneliti ini lebih lanjut menggunakan tautan yang disediakan atau melakukan pencarian web untuk "prinsip yang kuat".

Reginald Blue
sumber
Tidak. Prinsip-prinsip SOLID sejauh ini terputus dari kenyataan sebenarnya menulis kode (= filosofis) sehingga prinsip-prinsip itu hanya dapat dipahami dengan cara yang sangat berguna sekali Anda sudah tahu bagaimana menulis kode yang baik, pada titik mana mereka mubazir paling baik. Menggunakannya sebagai prinsip panduan tanpa memiliki pengalaman dan kemampuan menghasilkan kode yang sangat buruk.
jpmc26