Sprint Blog #4

Bram Sedana
slovneek
Published in
11 min readApr 15, 2019

Haloo!! Ini saya lagi, Bram Sedana, dan kembali lagi dengan blog yang saya buat dengan sepenuh hati tiap dua minggu sekali, Sprint Blog! Tidak terasa ternyata sekarang sudah sampai Sprint Blog #4.

Kalau pada Sprint Blog lalu terdapat kendala UTS, pada Sprint Blog kali ini kendala yang saya alami adalah saya terjatuh sakit (ada aja masalahnya wkwk). Tapi meskipun sakit-sakit gini tetep harus semangat dong buat kuliah dan ngelaksanain Sprint hehehe.

Nah udah cukup buat curhatnya, jadi pada sprint kali ini saya mau menjelaskan tentang tiga hal, yaitu GIT, Software Environment, Deployment dan Refactoring and Design Pattern.

GIT (Again?!)

Logo GIT

Jadi ini ceritanya saya mau membahas tentang git lagi karena belum dapet nilai 3 hehehhe. Tapi, pada waktu Sprint Blog #2 saya sudah menjelaskan secara mendetil, jadi mungkin saya bakal ngereview hal-hal yang pernah saya bahas saja.

Nah apa itu GIT? GIT ini merupakan sebuah version control yang berguna untuk bekerja dalam sebuah tim. Apa sih version control itu? Version control ini adalah software yang membantu tim software developer dalam mengelola perubahan source code yang terjadi. Version control ini mencatat perubahan-perubahan yang terjadi pada kode dan disimpan dalam suatu database khusus. Pada PPL ini kita menggunakan GIT sebagai version control kita.

Git flow

Git Flow PPL

Nah jadi pada PPL ini, git flow yang kita gunakan berbentuk seperti ini. Pada flow ini, terlihat bahwa terdapat beberapa branch, yaitu:

  • master: branch utama yang digunakan untuk menyimpan fitur yang memang sudah siap untuk diluncurkan ke production, tidak semua orang bisa mengakses branch ini.
  • staging: branch yang digunakan untuk menggabungkan yang telah berhasil diimplementasi.
  • user-story: branch yang digunakan untuk mengembangkan suatu fitur.
  • coldfix: branch yang digunakan untuk menghapus fitur yang tidak sesuai yang sudah dimerge dengan branch staging.
  • hotfix: branch yang digunakan untuk melakukan pembenaran error atau bug yang terdapat pada branch master.

Git Commands

Nah dalam menggunakan git, terdapat beberapa command berguna yang dapat digunakan. Berikut adalah beberapa command tersebut:

  • git init: melakukan inisialisasi suatu git repository baru.
  • git clone: menyalin remote repository ke local repository.
  • git remote: remote repository yang dirujuk.
  • git branch: melakukan operasi pada branch-branch yang ada, seperti melihat branch yang ada atau membuat branch baru.
  • git checkout: bisa digunakan untuk berpindah branch, bisa digunakan untuk menghapus perubahan yang telah dibuat pada suatu file, bisa juga digunakan untuk kembali ke state file-file di saat suatu commit dilakukan.
  • git pull: mengambil perubahan yang terjadi pada remote repository ke local repository.
  • git add: memindahkan file yang telah diubah di local repository ke stage dan siap untuk di-commit.
  • git commit: membuat sebuah versi untuk file-file yang ada di stage sehingga siap untuk di-push.
  • git push: meng-upload commit yang ada dari local repository ke remote repository.
  • git stash: menyimpan perubahan yang telah dilakukan pada file-file tetapi tidak ingin di-commit.
  • git merge: menggabungkan perubahan yang terjadi pada suatu branch ke branch lain, namun hanya ada satu branch yang berubah yaitu branch tujuan. Commit tidak akan ke-squash jika menggunakan command ini, tidak seperti git rebase.
  • git rebase: menggabungkan perubahan yang terjadi pada dua branch dan commitnya di-squash. Berbeda dengan command git merge, terjadi perubahan pada kedua branch.
  • git log: melihat beberapa commit terakhir yang terjadi pada branch sekarang.
  • git revert: melakukan rollback untuk mengubah commit yang telah dilakukan.

Software Environment: Container Based (Docker), Development, Staging, and Production Environment

Environment

Gambar diatas menunjukkan lingkungan dari suatu rumah, yaitu pohon-pohon di sekitar, gunung yang ada di dekat rumah tersebut, dan lain-lainnya. Nah sama halnya denngan gambar diatas, software environment itu merupakan lingkungan untuk suatu software. Yang termasuk sebagai software environment itu adalah Operating System, Database System, tools development tertentu dan juga compiler.

Development, Staging, and Production Environment

Ketiga environment ini berguna untuk memudahkan pengembangan software sehingga dapat berjalan dengan baik. Apa aja sih fungsi dari ketiga environment tersebut? Fungsi dari ketiga environment tersebut pada PPL ini adalah:

  • Development Environment: Merupakan suatu lingkungan pengembangan yang digunakan untuk menguji kode dan biasanya hanya digunakan untuk unit testing. Environment ini berfungsi untuk mencoba apakah sebuah kode bisa berfungsi di sistem.
  • Staging Environment: Merupakan environment yang digunakan untuk sprint review. Semua branch userStory yang sudah dimerge dengan staging seharusnya dapat dilihat pada environment ini.
  • Production Environment: Aplikasi yang berada di environment ini harus merupakan hasil sprint review yang sudah diapprove oleh product owner saat sprint review.

Container Based (Docker)

Dock?
Docker

Sebelum membahas tentang Container Based, saya akan menjelaskan dulu apa yang dimaksud dengan container. Jadi, container itu adalah package yang mengandalkan virtual isolation untuk mendeploy ataupun menjalankan aplikasi yang mengakses OS kernel yang sama tanpa menggunakan virtual machine.

Container Based, atau Application Container seperti Docker, mengenkapsulasi file, dependency, dan library dari suatu aplikasi agar bisa dijalankan pada suatu OS. Application Container memperbolehkan pengguna untuk membuat dan menjalankan beberapa container untuk tiap service yang berbeda dalam satu aplikasi. Pada PPL kami, docker digunakan untuk mengsetup server frontend (NodeJS) dan backend (Django REST Framework).

Meskipun sekilas sama dengan virtual machine, namun docker berbeda dengan virtual machine. Docker tidak membuat suatu OS virtual seperti virtual machine, melainkan docker membiarkan aplikasi menggunakan kernel yang sama dengan sistem yang menjalankan dan hanya perlu menjalankan hal-hal yang belum dijalankan oleh komputer.

Saat menggunakan docker, kita akan menggunakan yang namanya Image, Image ini adalah suatu template read-only yang berisi instruksi dalam membuat suatu docker container. Untuk membuat image, kita perlu membuat Dockerfile dengan syntax sederhana untuk menetapkan tahapan-tahapan yang diperlukan untuk membuat image lalu dijalankan.

Berikut adalah cara kerja docker:

  • Docker daemon (dockerd): mendengarkan docker API request dan mengelola docker object seperti image, container, daemon juga dapat berkomunikasi dengan daemon lain untuk mengelola Docker service.
  • Docker Client: client ini adalah cara user berinteraksi dengan docker. Jika user menjalankan command seperti docker run, maka command tersebut akan dikirim ke dockerd.
  • Docker Registry: berfungsi untuk menyimpan docker image. Salah satu contoh registry ini adalah Docker Hub yaitu registry publik yang bisa dipakai semua orang, secara default Docker akan mencari image dari Docker Hub. Di saat user menjalankan docker pull atau docker run, image yang diperlukan akan diambil dari registry. Sedangkan di saat menjalankan command docker push, image akan dipush ke dalam registry.

Docker kami terdeploy pada http://152.118.201.222:24674/

Deployment

Jadi pada bagian ini saya akan membahas tentang Deployment, terutama tentang CI/CD serta kegunaannya dalam deployment.

Continuous Integration

Apa sih maksud dari gambar diatas? Apa nyambungnya sama deployment? Nah, sebelum saya menjelaskan tentang gambar tersebut, saya mau menjelaskan dulu tentang Continuous Integration (CI) itu sendiri, apa itu CI dan apa gunanya?

Jadi, CI itu adalah suatu kebiasaan dalam software development untuk melakukan integrasi kode secara terus-menerus pada repository kode bersama. Biasanya, hal ini dilakukan setidaknya sekali dalam sehari namun bisa saja lebih, tergantung dari banyaknya commit. Selain itu, CI juga lebih mendorong kita agar lebih baik sering melakukan commit dengan perubahan file yang sedikit-sedikit daripada jarang melakukan commit tetapi sekalinya melakukan commit langsung terdapat banyak perubahan terhadap file. Setiap commit akan memicu build terhadap test sehingga dapat tahu jika terdapat suatu masalah akibat perubahan tersebut.

Gitlab CI

Setiap kali ada yang melakukan push, gitlab akan melakukan integrasi secara otomatis pada repositori sehingga bisa dideploy. Dengan adanya integrasi otomatis ini sangatlah memudahkan pengerjaan berkelompok di suatu repositori yang sama karena tidak perlu melakukan integrasi secara manual, sehingga kemungkinan terjadi human error lebih kecil. Integrasi otomatis ini dapat diatur pada file .gitlab-ci.yml. Pada proses integrasi slovneek terdapat tiga tahap/stages yaitu:

Berikut adalah potongan kode untuk tahap build:

Jadi image yang digunakan pada stage ini adalah alpine (Alpine Linux package management atau apk). Service yang digunakan adalah docker:dind (Docker in docker) yang digunakan untuk memulai Docker Daemon. Variabel IMAGE_TAG merupakan link untuk Dockerfile yang akan digunakan. Sebelum melakukan build, dilakukan install docker dahulu dengan menjalankan apk add docker. Jika berhasil menginstall docker, maka akan dijalankan script docker build … yang akan membuat image dari Dockerfile dan docker push … untuk melakukan push image ke dalam registry. Script tersebut hanya dijalankan jika dilakukan push pada branch staging saja dan tidak dijalankan jika melakukan push di branch lain.

Berikut adalah potongan kode untuk tahap test:

Pada tahap ini, terdapat perbedaan pada image yang digunakan antara frontend dan backend, hal tersebut karena test frontend dijalankan dengan menggunakan node sedangkan backend dijalankan dengan menggunakan python. Pada backend, digunakan service yaitu elasticsearch untuk membantu dalam melakukan search pada aplikasi. Kode yang dijalankan pada before script adalah untuk menginstall requirements yang dibutuhkan untuk melakukan testing. Potongan kode pada script dijalankan setelah menjalankan potongan kode pada before script, isi script adalah command untuk menjalankan testing.

Berikut adalah potongan kode untuk tahap deploy:

Image yang digunakan pada build ini adalah gitlab/dind:latest agar bisa melakukan build docker pada gitlab. Pada beforescript dilakukan penentuan lokasi dari dockerfile yang akan digunakan. Setelah menjalankan beforescript, akan menjalankan script untuk membuat image dari dockerfile yang lokasinya sudah ditentukan sebelumnya. kemudian image tersebut dipush ke registry dan kemudian dipull ke gitlab dengan menggunakan command curl link.

Refactoring and Design Pattern

Sekarang saya akan menjelaskan tentang Refactoring dan Design Pattern, kedua hal ini telah saya pelajari di mata kuliah Advanced Programming, tetapi sayang sekali saya sedikit sekip pada mata kuliah tersebut wkwk. Jadi pada Sprint Blog kali ini, saya akan mencoba memahami ulang tentang kedua hal ini.

Refactoring

Refactoring, there’s no end to it

Refactoring atau Code Refactoring ini adalah proses mengubah suatu source code tanpa mengubah fungsionalitas dari kode tersebut.

Guna dari refactoring ini adalah untuk memperbaiki non fungsionalitas dari kode, seperti readability dari kode dan mengurangi kompleksitas dari kode. Hal tersebut dapat mempermudah dalam merawat source code. Selain itu, dengan melakukan refactor kode kita sehingga menggunakan design pattern, kita dapat meningkatkan kemampuan dari aplikasi kita dan juga membuat kode kita menjadi lebih fleksibel.

Nah bagaimana sih cara-cara melakukan refactor? Jadi, ada beberapa metode yang termasuk dalam refactoring, yaitu:

  • Rename method/class/file: Terkadang di saat pertama kali kita membuat kode, terdapat beberapa penamaan kepada metode/class/file yang aneh dan kurang deskriptif, maka dari itu kita lakukan renaming sehingga kita dapat memberikannya nama yang lebih deskriptif dan jelas.
  • Move file: Dalam pembuatan kode, terkadang kita lupa untuk menerapkan best practice, seperti best practice untuk direktori kode. Agar kita dapat memenuhi best practice tersebut, kita bisa memindahkan file-file ke tempat yang mereka seharusnya.
  • Extract method: Terkadang, kita terdapat potongan kode yang bisa dikelompokkan yang kita jalankan berkali-kali. Lebih baik jika kita membuat potongan kode tersebut menjadi sebuah method, sehingga kita tidak perlu mengulang banyak potongan kode yang sama, melainkan kita cukup memanggil method tersebut.
  • Extract class: Jika terdapat suatu class yang sepertinya melakukan kerja dari dua class, kita dapat memisahkan class tersebut menjadi dua class, sehingga terlihat lebih rapi.
  • Collapse hierarchy: Jika terdapat class hierarchy pada potongan kode dimana subclass sama dengan superclassnya, kita dapat menggabungkan subclass dan superclass tersebut.

Best Practices

Dalam melakukan refactoring, kita akan berusaha “mengubah” source code kita supaya lebih mengikuti best practice yang ada untuk bahasa/framework yang kita gunakan. Berikut adalah beberapa best practice yang ada untuk framework yang saya gunakan pada PPL ini.

— ReactJS

  • Directory Layout: Pada React, best practice dalam penyimpanan file kode adalah untuk kode milik suatu komponen yang sama diletakkan pada satu folder (kecuali tests).
  • CSS in JavaScript: Semakin besar aplikasi kita, semakin sering terjadi naming collision. Agar dapat menghindari hal tersebut, best practice yang dilakukan adalah untuk menggunakan salah satu dari beberapa solusi ini: StyledComponents, EmotionJS atau Glamorous. Yang saya gunakan untuk PPL ini adalah StyledComponents.
  • Props: Penggunaan fungsi mapStateToProps dan mapDispatchToProps sangatlah membantu dalam membuat kode lebih mudah dibaca. mamStateToProps menyimpan isi dari state component yang diambil dari selector ke dalam prop. mapDispatchToProps yaitu menyimpan action yang dapat digunakan oleh component tersebut dan disimpan ke dalam props.

TDD (Red, Green, Refactor)

  1. Buatlah test dulu sebelum menulis kode. Pada test tersebut, tentukan spesifikasi dan fungsionalitas dari kode yang akan kita tulis.
  2. Tulis kode yang dapat memenuhi kebutuhan dari test, hindari kompleksitas agar kode mudah dibaca.
  3. Fungsi suatu method harus terfokus dengan tujuan dari method tersebut. Berikan nama yang deskriptif dan jelas pada method tersebut.
  4. Pastikan suatu method hanya memiliki satu tujuan. Dengan itu lebih mudah untuk melakukan testing terhadap kode tersebut.
  5. Selalu melakukan testing sebelum dan sesudah melakukan refactor terhadap kode. Hal tersebut membantu memastikan agar tidak ada perubahan fungsionalitas pada potongan kode yang diubah.

Design Pattern

Design Pattern dan macam-macamnya

Design pattern itu adalah suatu solusi untuk masalah yang sering terjadi dalam dunia software engineering. Tapi, sesuai dengan namanya, solusi tersebut hanyalah sebuah “design”, kita tidak bisa mengubah solusi tersebut langsung menjadi sebuah kode yang dapat menyelesaikan masalah kita. Design pattern ini adalah sebuah template untuk bagaimana menyelesaikan suatu masalah.

Dengan menggunakan design pattern, kita dapat mempercepat proses pengembangan software karena design pattern sendiri merupakan paradigma pengembangan yang sudah ditest. Selain itu, penggunaan design pattern dapat menghindari isu kecil yang biasanya tidak terlihat namun dapat menyebabkan masalah besar kedepannya.

Design pattern sendiri dapat dibagi menjadi 3, yaitu:

— Creational Design Pattern: Design pattern ini lebih ke arah instansiasi suatu class. Pattern ini kemudian dapat dipisah menjadi class-creation pattern dan object-creation pattern. Macam-macam creational design pattern adalah:

  • Abstract Factory
  • Builder
  • Factory Method
  • Object Pool
  • Prototype
  • Singleton

— Structural Design Pattern: Design pattern ini lebih ke arah komposisi class dan object. Macam-macam structural design pattern adalah:

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Private Class Data
  • Proxy

— Behavioral Design Pattern: Design pattern ini lebih ke arah komunikasi objek class. Macam-macam behavioral design pattern adalah:

  • Chain of Responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Null Object
  • Observer
  • State
  • Strategy
  • Template method
  • Visitor

Dalam pengimplementasian Design pattern pada PPL ini, saya menggunakan Behavioral Design Pattern State.

Contoh Design Pattern State

State design pattern merupakan state dimana behavior suatu objek berubah tergantung dari statenya. Seperti pada contoh diatas, objek dari suatu class Order memiliki 4 state, yaitu initialState, paidState, confirmedState, canceledState. Pada tiap state tersebut, fungsi dari order tersebut berbeda-beda.

Nah apa sih hubungannya design pattern state ini dengan PPL? Hubungannya itu adalah, pada PPL ini kami menggunakan React-Redux, yang memang terkenal stateful.

Redux Unidirectional Pattern

Component-component pada react memiliki state yang jika diubah statenya maka akan terjadi perubahan pada component tersebut. Perubahan state tersebut dikendalikan oleh sesuatu yang namanya redux. Seperti gambar diatas, maksudnya dari flow redux adalah jika dilakukan suatu interaksi pada suatu component react maka akan didispatch action yang memiliki attribute payload dan tipe action, action tersebut kemudian diterima oleh reducer yang ada di store, reducer tersebut kemudian akan mengubah state dari component tergantung action yang diterima.

See you later

Tidak terasa ini sudah sprint ketiga dari terakhir, mungkin setelah itu saya tidak akan melanjutkan lagi bi-weekly blog ini (atau iya?). Tapi sebelum ini berakhir saya akan berusaha sebisa mungkin untuk membuat blog ini seinformatif dan semenarik mungkin. Sekian dari saya, sampai jumpa di Sprint Blog selanjutnya, Bye!

--

--