"Di mana kaki tumbuh dari" atau apa yang mendahului pemrograman?

Halo semuanya! Suatu hari, sebagai bagian dari platform pendidikan OTUS, sebuah kursus baru diluncurkan: "Pola Desain dan Arsitektur" . Sehubungan dengan permulaan, kami mengadakan pelajaran terbuka tradisional . Ini mempelajari fitur aplikasi monolitik, arsitektur multi-level dan serverless. Kami memeriksa secara terperinci sistem yang digerakkan oleh peristiwa, sistem yang berorientasi layanan, dan arsitektur layanan mikro.



Guru itu adalah Matvey Kalinin , seorang spesialis dengan lebih dari 20 tahun pengalaman pemrograman dan penulis kursus "Arsitektur dan Pola Desain".

Sedikit latar belakang


Awalnya, program benar-benar menyelesaikan tugas yang ditetapkan untuk mereka sendiri dan cukup terisolasi. Namun seiring berjalannya waktu, program tumbuh, dan orang-orang mulai memahami bahwa kompleksitas fungsional yang muncul mulai memengaruhi kecepatan peningkatan, keandalan, dan resistensi terhadap berbagai jenis komplikasi.

Memang, ketika kita memiliki satu atau dua program yang sama dan tidak berubah, menulis program ini dan memastikan interaksinya tidak sulit. Tetapi ketika ada semakin banyak dari mereka, masalah tidak dapat dihindari, dan tidak masalah apa jenis paket perangkat lunak yang terlibat.

Saat ini, sebagian besar aplikasi didistribusikan. Mereka terdiri dari beberapa modul dan saling berhubungan oleh pesan sistem. Artinya, konglomerat yang agak besar dari program yang saling berinteraksi diperoleh. Dan agar mereka berhasil berinteraksi, kita perlu mempertimbangkan:

  • respon cepat;
  • bandwidth
  • kinerja dalam hal satu unit sumber daya;
  • kemampuan skala;
  • kemampuan integrasi;
  • fitur platform yang digunakan;
  • fitur dari proses bisnis yang ada;
  • dan banyak lagi…

Pada saat yang sama, orang tidak bisa tidak mengingat kutipan berikut:

“Kode program yang benar tidak memerlukan biaya tenaga kerja yang besar untuk pembuatan dan pemeliharaannya. Perubahan dilakukan dengan cepat dan mudah. Kesalahan sedikit. Biaya tenaga kerja minimal, sementara fungsi dan fleksibilitas maksimum . "

Robert Cecil Martin

Artinya, menulis program idealnya satu kali (jika ditulis dengan baik), peningkatannya akan minimal. Bagaimana cara mencapai ini dan menghubungkan satu dan yang lainnya? Untuk menjawab pertanyaan ini, kita beralih ke sejarah.


?


Jadi, kami menyadari bahwa kami perlu menyusun produk perangkat lunak dengan benar. Tetapi apa tujuan arsitektur perangkat lunak? Lagi pula, mengapa kita menggunakan frasa "kaki tumbuh" dalam judul artikel ini?

Masalahnya adalah bahwa ketika Anda memulai pemrograman, Anda sudah tahu apa yang ingin Anda bangun. Awalnya, semuanya dimulai dengan proses bisnis. Ada pesanan dan pelanggan yang menjelaskan (setidaknya dalam kata-kata) bagaimana sistemnya seharusnya bekerja. Dan pada awalnya sistem ini hanya ada dalam bentuk yang dijelaskan olehnya. Maka proses ini diformalkan dan diuraikan, tetapi ini masih setengah pertempuran, karena pengembangan lebih lanjut dimulai. Dan pengembang perlu mengubah proses ini menjadi produk perangkat lunak, yang seharusnya ...

Maka inilah saatnya untuk mengingat kutipan lain:

"Tujuan dari arsitektur perangkat lunak adalah untuk mengurangi tenaga manusia yang dibutuhkan untuk membuat dan memelihara suatu sistem."

Robert Cecil Martin


Seharusnya tidak mengherankan bahwa tujuannya dibentuk oleh frasa umum seperti itu. Faktanya adalah bahwa arsitektur hidup dalam ide-ide abstrak. Mengapa? Karena orang yang terlibat dalam arsitektur perangkat lunak mengubah visi pelanggan bisnis menjadi visi pengembang . Dan jika kita berbicara tentang arsitek tim pengembangan dan arsitek Perusahaan, maka masing-masing dari mereka memiliki tujuan yang berbeda, tetapi keduanya berjuang untuk satu hal - untuk mengurangi biaya tenaga kerja manusia.

Dalam konteks ini, menarik untuk melihat nilai-nilai perangkat lunak:

  • Kode memenuhi persyaratan proses bisnis;
  • ada kemungkinan perubahan perilaku yang cepat

Dan di sini muncul pertanyaan: apa yang lebih penting, pengoperasian sistem atau kesederhanaan mengubahnya ? Untuk menjawabnya, mari kita lihat program dari sudut pandang kegunaan:

Jika ada program yang berfungsi dengan benar yang tidak memungkinkan perubahan, maka program seperti itu pada akhirnya akan menjadi tidak relevan - ketika persyaratan berubah.

Jika program tidak bekerja dengan benar, tetapi perubahan dapat dibuat di dalamnya, maka itu dapat dibuat untuk bekerja dengan benar dalam kerangka perubahan persyaratan. Program ini akan selalu bermanfaat.

Paradigma (model) pemrograman


Menurut Anda apa model pemrograman yang paling terkenal (paling pertama)? Tentu saja, monolit . Adalah pantas di sini lagi untuk sejenak kembali ke tahun 1968 dan mengingat kembali Edsger Dijkstra, yang menunjukkan bahwa penggunaan transisi yang merajalela (instruksi goto) berbahaya bagi struktur program. Dia menyarankan untuk mengganti transisi dengan lebih dimengerti jika / lalu / lain dan lakukan / sementara / sampai konstruksi.

Sekarang instruksi goto dapat dilihat lebih jarang. Tapi sebelumnya, instruksi goto sangat umum. Secara umum, ini adalah bentuk kejahatan, karena ketika Anda melihat kode di mana ada instruksi goto, Anda merasa bahwa Anda mungkin tidak menemukan titik di mana ia pergi. Dan semakin goto, semakin rumit, yaitu, kita mendapatkan kode spageti. Kami sekarang menyebutnya kode "spaghetti", di mana, misalnya, 20 jika bersarang dan, mungkin, satu kebohongan. Ini juga bukan kode yang sangat jelas. Bayangkan bahwa Anda memiliki 10-15, dan Anda mencoba memahami bagaimana siklus bekerja - itulah yang ada dalam pikiran Dijkstra.

Kode spaghetti adalah program yang tidak terstruktur, membingungkan, dan sulit dipahami yang berisi banyak pernyataan kebohongan (terutama lompatan), pengecualian, dan konstruksi lain yang merusak struktur. Secara umum, antipattern pemrograman yang terkenal dan cukup umum. Program semacam itu membutuhkan banyak waktu untuk memahami, mendukung, dan menguji.

Pemrograman struktural


Ada bahasa pemrograman, mereka menyadari beberapa tujuan. Sampai titik tertentu, struktur program tidak banyak mempengaruhi pelaksanaannya. Tetapi program tumbuh, di antara mereka banyak ikatan terbentuk. Dan pada satu titik, seseorang merasa bahwa penting untuk mengemas algoritma ke dalam struktur yang mudah dibaca, diuji. Perubahan telah dimulai di tingkat struktur program. Artinya, tidak hanya program itu sendiri yang harus memenuhi hasil, tetapi struktur program juga harus memenuhi beberapa kriteria.

Dengan demikian, kami dengan lancar beralih ke pemrograman struktural . Menurutnya, program ini dibangun tanpa menggunakan operator goto dan terdiri dari tiga struktur kontrol dasar:

  • urutan,
  • percabangan
  • siklus.

Subprogram digunakan, pengembangan itu sendiri dilakukan langkah demi langkah, dari atas ke bawah.
Dan lagi, kembali pada tahun 1966 ... Tahun ini, Ole-Johan Dahl dan Kristen Nyugor memperhatikan bahwa dalam bahasa ALGOL adalah mungkin untuk memindahkan bingkai stack panggilan fungsi ke memori dinamis (heap), sehingga variabel lokal yang dideklarasikan di dalam fungsi dapat disimpan setelah keluar dari sana. Akibatnya, fungsi berubah menjadi konstruktor kelas, variabel lokal menjadi variabel instan, dan fungsi bersarang menjadi metode. Ini mengarah pada penemuan polimorfisme melalui penggunaan pointer fungsi secara ketat.

Pemrograman berorientasi objek


Seperti yang Anda semua tahu, dalam OOP, program direpresentasikan sebagai kumpulan objek, yang masing-masing adalah turunan dari kelas tertentu, dan kelas membentuk hierarki warisan.

Prinsip dasar penataan:

  • abstraksi;
  • warisan;
  • polimorfisme.

Anda dapat melihat semua prinsip ini dari perspektif lain. Robert Martin mengembangkan prinsip-prinsip SOLID, yang, di satu sisi, menentukan bagaimana seorang programmer bekerja dengan abstraksi, dan di sisi lain, membentuk proses polimorfisme dan pewarisan.

Pemrograman imperatif


Program penting mirip dengan perintah yang harus dijalankan komputer. Program-program tersebut ditandai oleh:

  • instruksi ditulis dalam kode sumber program;
  • instruksi harus diikuti secara berurutan;
  • data yang diperoleh selama pelaksanaan instruksi sebelumnya dapat dibaca dari memori dengan instruksi selanjutnya;
  • data yang diperoleh dengan menjalankan instruksi dapat ditulis ke memori.

Juga desain yang sangat kuno. Fitur utama dari bahasa imperatif:

  • penggunaan variabel bernama;
  • penggunaan operator penugasan;
  • penggunaan ekspresi majemuk;
  • penggunaan rutinitas.

Namun, kami melanjutkan "perjalanan waktu". Kali ini kami akan kembali sejenak di tahun 1936 (!). Sangat menarik bahwa tahun ini Gereja Alonzo menemukan kalkulus lambda (atau λ-kalkulus), yang kemudian, pada tahun 1958, membentuk dasar bahasa LISP yang ditemukan oleh John McCarthy. Konsep dasar kalkulus λ adalah kekekalan - yaitu, ketidakmungkinan mengubah nilai-nilai simbol.

Pemrograman fungsional


Pemrograman fungsional melibatkan melakukan perhitungan hasil fungsi dari sumber data dan hasil fungsi lainnya dan tidak menyiratkan penyimpanan eksplisit dari keadaan program.

Bahkan, ini berarti bahwa bahasa fungsional tidak memiliki pernyataan penugasan.

Mari kita lihat perbedaan antara gaya imperatif dan gaya menggunakan contoh:

#  
target = []  #   
for item in source_list:  #     
    trans1 = G(item)  #   G()
    trans2 = F(trans1)  #   F()
    target.append(trans2)  #     
#  
compose2 = lambda A, B: lambda x: A(B(x))
target = map(compose2(F, G), source_list)

Jadi apa itu arsitektur perangkat lunak?


Arsitektur perangkat lunak adalah seperangkat keputusan tentang pengorganisasian sistem perangkat lunak.

Itu termasuk:

  • pemilihan elemen struktural dan antarmuka mereka;
  • perilaku elemen dan antarmuka yang dipilih, interaksinya;
  • menggabungkan elemen struktur dan perilaku yang dipilih ke dalam sistem yang lebih besar;
  • gaya arsitektur yang memandu seluruh organisasi.

Harap dicatat: pertama kami sampai pada kesimpulan bahwa goto tidak cocok dengan kami, kemudian kami melihat bahwa ada aturan tertentu (enkapsulasi, pewarisan, polimorfisme), kemudian kami menyadari bahwa aturan ini tidak hanya berfungsi, tetapi sesuai dengan prinsip-prinsip tertentu. Poin keempat adalah gaya arsitektur, dan kita akan membicarakannya nanti.

Tujuan utama arsitektur adalah untuk mendukung siklus hidup sistem. Arsitektur yang baik membuat sistem mudah dipelajari, mudah dikembangkan, dipelihara, dan digunakan. Tujuan utamanya adalah untuk meminimalkan biaya selama umur sistem dan memaksimalkan produktivitas programmer, dan lebih tepatnya, tim pengembangan.

Awalnya kami berbicara tentang aturan apa yang kami butuhkan untuk menulis program. Tapi, selain menulis program, ada juga dukungan, pengembangan, dan penyebaran. Artinya, arsitektur tidak menangkap area pemrograman tertentu, tetapi seluruh siklus pengembangan.

Arsitektur yang baik harus menyediakan:

  1. Berbagai kasus penggunaan dan operasi sistem yang efektif.
  2. Kesederhanaan pemeliharaan sistem.
  3. Kemudahan desain sistem.
  4. Penerapan sistem yang mudah.

Gaya arsitektur


Monolit


Pertama-tama, mari kita bicara tentang monolit yang terkenal itu . Namun, gaya ini masih ditemukan dalam sistem kecil. Arsitektur monolitik berarti bahwa aplikasi Anda adalah modul besar yang terhubung. Semua komponen dirancang untuk bekerja bersama, berbagi memori dan sumber daya. Semua fungsi atau bagian utamanya dikonsentrasikan dalam satu proses atau wadah, yang dibagi menjadi beberapa lapisan atau pustaka internal.



Keuntungan:

  1. Mudah diimplementasikan. Tidak perlu membuang waktu untuk memikirkan komunikasi antarproses.
  2. Sangat mudah untuk mengembangkan tes ujung ke ujung.
  3. Mudah digunakan.
  4. Skala dengan Loadbalancer dengan mudah di beberapa instance aplikasi Anda.
  5. Mudah dioperasikan.



Tetapi sekarang dia memiliki lebih banyak kekurangan :

  1. Kohesi yang kuat mengarah ke keterikatan dengan evolusi aplikasi.
  2. Penskalaan komponen independen menyebabkan komplikasi dan pengujian ulang fungsionalitas lengkap.
  3. Lebih sulit dimengerti.
  4. Dengan meningkatnya kompleksitas, waktu pengembangan tumbuh.
  5. Kurangnya isolasi komponen.

Di satu sisi, monolit itu baik, tetapi begitu Anda mulai mengembangkannya, kesulitan muncul.

Apa itu layanan?


Sekarang semua orang tahu apa itu layanan. Ini dapat didefinisikan sebagai sumber daya yang terlihat yang melakukan tugas yang berulang dan dijelaskan oleh instruksi eksternal.

Layanan modern memiliki fitur berikut :

  • layanan berorientasi bukan pada kemampuan TI, tetapi pada kebutuhan bisnis;
  • layanan mandiri dan dijelaskan dalam hal antarmuka, operasi, semantik, karakteristik dinamis, kebijakan, dan properti layanan;
  • penggunaan kembali layanan disediakan oleh perencanaan modular mereka;
  • perjanjian layanan disimpulkan antara entitas yang disebut pemasok dan pengguna, dan tidak mempengaruhi implementasi layanan itu sendiri;
  • selama siklus hidupnya, layanan di-host dan dibuat terlihat melalui metadata layanan, registrasi, dan repositori;
  • agregasi: menggabungkan proses bisnis dan aplikasi kompleks untuk satu atau beberapa perusahaan dibangun di atas layanan yang digabungkan secara longgar.

Sebagai hasil dari fitur di atas, konsep arsitektur berorientasi layanan (SOA) muncul.

Arsitektur Berorientasi Layanan (SOA)


SOA adalah gaya arsitektur untuk menciptakan arsitektur TI perusahaan, menggunakan prinsip-prinsip orientasi layanan untuk mencapai hubungan yang erat antara bisnis dan sistem informasi pendukungnya.



SOA memiliki karakteristik sebagai berikut :

  1. Meningkatkan hubungan antara arsitektur perusahaan dan bisnis.
  2. Memungkinkan Anda membuat aplikasi kompleks dari serangkaian layanan terintegrasi.
  3. Menciptakan proses bisnis yang fleksibel.
  4. Itu tidak tergantung pada seperangkat teknologi.
  5. Otonomi dalam arti evolusi dan penyebaran independen.

Model penyebaran SOA terdiri dari intelijen dan pengembangan bisnis dan intelijen dan pengembangan TI. Perakitan terdiri dari layanan pemrograman dan membangun aplikasi yang kompleks. Hosting terdiri dari aplikasi hosting dan alat runtime seperti Enterprise Service Buses (ESBs). Adapun manual , itu terdiri dari mendukung lingkungan operasi, memantau kinerja layanan dan memantau kepatuhan dengan kebijakan layanan.



Arsitektur microservice


Saatnya berbicara tentang arsitektur layanan mikro . Di dalamnya, aplikasi terdiri dari aplikasi layanan independen kecil, masing-masing dengan sumber dayanya sendiri. Layanan saling berinteraksi untuk melakukan tugas yang terkait dengan peluang bisnis mereka. Ada beberapa unit penempatan. Setiap layanan dikerahkan secara independen.



Keuntungan:

  1. Mendukung modularitas seluruh sistem.
  2. Layanan yang tidak terkait lebih mudah dimodifikasi untuk melayani berbagai aplikasi.
  3. Layanan yang berbeda mungkin milik tim yang berbeda.
  4. Layanan layanan dapat digunakan kembali di seluruh perusahaan.
  5. Lebih mudah dipahami dan diuji.
  6. Tidak terikat dengan teknologi yang digunakan dalam layanan lain.
  7. Isolasi layanan meningkatkan keandalan keseluruhan semua fungsi.



Kekurangan:

  1. Kesulitan dengan implementasi fungsi keseluruhan (logging, hak akses, dll.).
  2. Sulit untuk melakukan tes sistem ujung ke ujung.
  3. Pengoperasian dan dukungan yang lebih sulit.
  4. Lebih banyak peralatan dibutuhkan daripada monolit.
  5. Dukungan oleh beberapa tim mengarah pada koordinasi interaksi di antara mereka.

Perlu dicatat bahwa dalam arsitektur ini sangat sulit untuk melakukan apa pun tanpa DevOps.

Arsitektur berlapis


Layered architecture adalah pola arsitektur yang paling umum. Ini juga disebut arsitektur n-tier, di mana n adalah jumlah level.

Sistem ini dibagi menjadi beberapa level, yang masing-masing berinteraksi dengan hanya dua yang bertetangga.

Arsitektur tidak menyiratkan jumlah level wajib - mungkin ada tiga, empat, lima atau lebih. Paling sering, sistem tiga-tier digunakan: dengan tingkat presentasi (klien), tingkat logika, dan tingkat data.
Lapisan yang paling umum adalah :

  • lapisan presentasi (untuk bekerja dengan pengguna);
  • lapisan aplikasi (layanan - keamanan, akses);
  • lapisan logika bisnis (implementasi domain);
  • lapisan akses data (representasi antarmuka ke basis data).

Lapisan tertutup


Konsep isolasi level secara ketat memisahkan satu level dari yang lain: Anda hanya bisa naik dari satu level ke level berikutnya dan Anda tidak bisa melompati beberapa level sekaligus.



Lapisan terbuka


Sistem ini memungkinkan Anda untuk melompati level terbuka dan jatuh pada yang berada di bawah.



MVC


Konsep MVC dijelaskan pada tahun 1978. Versi terakhir dari konsep MVC diterbitkan hanya pada tahun 1988 dalam jurnal Technology Object.

Tujuan utamanya adalah untuk memisahkan logika bisnis (model) dari visualisasinya (presentasi, tampilan). Apa yang diberikannya:

  • Kemungkinan penggunaan kembali kode meningkat.
  • pengguna dapat melihat data yang sama secara bersamaan dalam konteks yang berbeda.



Model ini menyediakan data dan merespons perintah pengontrol, mengubah kondisinya. Tampilan bertanggung jawab untuk menampilkan data model kepada pengguna, merespons perubahan model. Kontroler menafsirkan tindakan pengguna, memberi tahu model perlunya perubahan.



Arsitektur Berbasis Acara


Arsitektur lain yang menarik. Ini digunakan dalam pengembangan dan implementasi sistem yang mentransmisikan peristiwa di antara elemen perangkat lunak yang digabungkan secara longgar.

Terdiri dari komponen pemrosesan peristiwa satu tujuan yang berbeda yang menerima dan memproses acara secara tidak sinkron.

Template terdiri dari dua topologi utama - perantara dan broker.

Topologi Pengecer


Ada proses di mana kontrol atas urutan langkah diperlukan. Di sini kami adalah perantara yang bermanfaat.

Jenis utama komponen arsitektur:

  • antrian acara;
  • mediator acara;
  • saluran acara;
  • penangan acara.

Peristiwa

Peristiwa dapat didefinisikan sebagai "perubahan signifikan dalam kondisi". Suatu acara dapat terdiri dari dua bagian:

  • header (nama acara, stempel waktu untuk acara tersebut, dan jenis acara);
  • tubuh (menggambarkan apa yang sebenarnya terjadi).

Topologi mediator

Klien mengirimkan acara ke antrian acara, yang digunakan untuk mengirim acara ke mediator.

Mediator menerima acara awal dan mengirimkan acara asinkron tambahan ke saluran acara untuk setiap langkah proses.

Pemroses acara, yang mendengarkan saluran acara, menerima acara dari perantara dan menjalankan logika bisnis tertentu dengan memproses acara tersebut.



Topologi broker

Topologi broker berbeda dari topologi perantara karena tidak ada mediator acara pusat. Alur pesan didistribusikan di antara komponen prosesor acara dalam rantai melalui perantara pesan yang ringan (misalnya, ActiveMQ, HornetQ, dll.). Topologi ini berguna ketika ada aliran pemrosesan peristiwa yang relatif sederhana dan tidak perlu untuk orkestrasi acara terpusat.

Setiap komponen dari event-prosesor bertanggung jawab untuk menangani acara dan menerbitkan acara baru yang mengindikasikan tindakan yang baru saja selesai.



Jika situasi pertama asinkron "di suatu tempat di bawah", maka situasi kedua asinkron, bisa dikatakan, sepenuhnya. Satu peristiwa menghasilkan beberapa peristiwa, dan mereka dapat meningkat dan meningkat.

Keuntungan arsitektur event driven:

  • komponen diisolasi dan memungkinkan masing-masing diselesaikan tanpa mempengaruhi sisa sistem;
  • kemudahan penyebaran;
  • kinerja tinggi. Mengizinkan operasi asinkron paralel;
  • sisik dengan baik.

Kekurangan:

  • sulit untuk diuji;
  • sulit untuk dikembangkan karena diucapkan sebagai sinkronisasi.

Arsitektur tanpa server


Ini adalah cara untuk membuat dan menjalankan aplikasi dan layanan tanpa memerlukan manajemen infrastruktur. Aplikasi masih berjalan di server, tetapi platform sepenuhnya mengendalikan server ini.

Seluruh infrastruktur didukung oleh penyedia pihak ketiga, dan fungsionalitas yang diperlukan ditawarkan dalam bentuk layanan yang bertanggung jawab untuk otentikasi, pengiriman pesan, dll

. Terminologi berikut dibedakan:

  1. (Function-as-a-Service) — , .
  2. (Backend as a Service) — , - API, . , , , .

Jika kita mempertimbangkan arsitektur "Client-server", maka sebagian besar logika dalam sistem (otentikasi, navigasi halaman, pencarian, transaksi) diimplementasikan oleh aplikasi server.



Dalam arsitektur tanpa server, semuanya agak berbeda. Otentikasi digantikan oleh layanan BaaS pihak ketiga (layanan cloud siap pakai), akses ke database juga digantikan oleh layanan BaaS lain. Logika aplikasi sebagian sudah ada di dalam klien - misalnya, melacak sesi pengguna.

Klien sudah dalam perjalanan untuk menjadi aplikasi satu halaman. Pencarian dapat dilakukan melalui layanan pencarian (FaaS - berfungsi sebagai layanan). Fungsi pembelian juga terisolasi dari pelanggan sebagai layanan terpisah (FaaS).



Nah, itu saja, jika Anda tertarik dengan detailnya, tonton seluruh videonya. Sedangkan untuk kursus baru, Anda dapat membiasakan diri dengan programnya di sini.

All Articles