Akmal76 / AdPro-Module1_4

Tutorial Pemrograman Lanjut (Advanced Programming) 2023/2024 Genap

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

tutorial-1

Tutorial Pemrograman Lanjut (Advanced Programming) 2023/2024 Genap

  • Nama : Akmal Ramadhan
  • NPM : 2206081534
  • Kelas : Pemrograman Lanjut - A

SonarCloud Report

Coverage Code Smells Security Rating Quality Gate Status

Aplikasi dapat diakses melalui link diatas.

Module 3: Maintainability & OO Principles

Reflection

Prinsip S.O.L.I.D yang Diterapkan

1. Single Responsibility Principle (SRP)

Diterapkan pada HomePageController, ProductController, dan CarController.

  • HomePageController memiliki tanggung jawab untuk melakukan mapping dengan endpoint /.
  • ProductController memiliki tanggung jawab untuk melakukan mapping dengan endpoint /product.
  • CarController memiliki tanggung jawab untuk melakukan mapping dengan endpoint /car. Oleh karena itu, saya membuat tiga class yang berbeda.

2. Liskov Substitution Principle (LSP)

Pada branch before-solid, ProductController.java memiliki subclass yaitu CarController. Padahal, CarController memiliki perilaku yang berbeda dengan superclass-nya. Contohnya editProductPost pada ProductController menggunakan method PUT dan editCarPost pada CarController menggunakan method POST. Oleh karena itu, objek dari superclass tidak dapat digantikan oleh objek dari subclass-nya. Solusi saya menghapus extends dari CarController dan membuat CarController menjadi class yang berdiri sendiri di file yang berbeda.

3. Interface Segregation Principle (ISP)

Sudah diterapkan pada CarService. Menurut saya, tidak perlu dipisah lagi karena interface ini fokus pada satu hal yaitu CRUD (Create, Read, Update, Delete) untuk Car.

4. Dependency Inversion Principle (DIP)

Pada branch before-solid, CarController bergantung langsung dengan CarServiceImpl. Hal ini tidak baik karena CarController seharusnya bergantung dengan interface CarService. Oleh karena itu, saya mengganti tipe data dari variabel carService pada CarController menjadi CarService.

Keuntungan Menggunakan Prinsip S.O.L.I.D

Menurut saya, dengan menerapkan prinsip S.O.L.I.D, kode yang saya buat menjadi lebih modular, rapi, dan mudah untuk di-maintain secara berkelanjutan. Ketika ingin melakukan modifikasi kode jadi lebih low effort karena tidak perlu mengubah banyak bagian kode. Terakhir, apabila bekerja dalam tim, menurut saya S.O.L.I.D dapat mempermudah code review dan menghindari kode yang sulit dipahami. Contoh penerapannya sudah saya jelaskan di atas.

Kekurangan Tidak Menggunakan Prinsip S.O.L.I.D

Bagi saya, ini hanya keterbalikan dari apa yang sudah sebutkan diatas. Kode yang saya buat sulit untuk di-maintain dan membutuhkan effort yang lebih besar untuk melakukan modifikasi kode. Selain itu, apabila bekerja dalam tim, akan sulit untuk melakukan code review dan kode yang sulit dipahami.

Contoh: Misalkan saya tidak menerapkan SRP CarController, bagi saya akan mudah saja mencari kode bagian mana yang mengatur mapping dengan endpoint /car karena saya sendiri yang membuatnya. Namun, jika orang lain membaca repositori kita, akan sulit mencari kode tersebut karena disatukan dengan file ProductController. Selain itu, jika tidak diterapkan LSP, subclass CarController tidak dapat menggantikan superclass-nya.

Reflection pada Module Sebelumnya

Module 2: CI/CD Dev Ops

Module 2: CI/CD & Dev Ops

Reflection

Daftar Isu Code Quality yang Diperbaiki

Berikut adalah isu-isu code quality yang dideteksi oleh PMD dan SonarCloud yang saya perbaiki:

1. Position literals first in String comparisons

Permasalahan: Perlu memposisikan literals terlebih dahulu dalam perbandingan String. Jika tidak, apabila argumen .equals() bernilai null, maka akan terjadi NullPointerException.

Contoh Isu pada Proyek:

if (product.getProductName().equals("")) product.setProductName("Produk Tidak Diketahui");

Solusi: Menukar kedua argumen pada perbandingan String.

if ("".equals(product.getProductName())) product.setProductName("Produk Tidak Diketahui");

2. This statement should have braces

Permasalahan: Pernyataan percabangan atau perulangan yang tidak memiliki braces {}.

Contoh Isu pada Proyek:

if (product.getProductQuantity() < 0) product.setProductQuantity(0);

Solusi: Menambahkan braces {} pada pernyataan tersebut.

if (product.getProductQuantity() < 0) {
    product.setProductQuantity(0);
}

3. Unnecessary modifier public on method ...: the method is declared in an interface type

Permasalahan: Modifier public tidak diperlukan karena dalam interface sudah secara default bersifat public.

Contoh Isu pada Proyek:

public interface ProductService {
    public Product create (Product product);
}

Solusi: Menghapus modifier public pada method tersebut.

public interface ProductService {
    Product create (Product product);
}

4. Unused import org.springframework.web.bind.annotation.*

Permasalahan tidak relevan, karena import tersebut memang tidak digunakan.

5. Missing Description

Permasalahan: Komentar yang tidak jelas atau tidak ada.

Contoh Isu pada Proyek:

<table border="1" class="table table-striped table-responsive-md">
    <thead>
    <tr>
        <th scope="col">Product Name</th>

Solusi: Menambahkan komentar yang jelas pada tag <table>.

<table border="1" class="table table-striped table-responsive-md">
    <!-- Tabel untuk menampilkan produk dengan detail nama, kuantitas, dan tombol edit serta delete -->
    <thead>
    <tr>
        <th scope="col">Product Name</th>

6. as pada Dockerfile

Contoh Isu pada Proyek:

FROM docker.io/library/eclipse-temurin:21-jdk-alpine as builder

Solusi: Mengubah as menjadi AS pada Dockerfile.

FROM docker.io/library/eclipse-temurin:21-jdk-alpine AS builder

7. Unused Private Modifier

Permasalahan: Terdapat modifier private yang tidak berguna.

Contoh Isu pada Proyek:

public class Product {
    private String productId;
    private String productName;
    private int productQuantity;
    ...
}

Solusi: Menghapus modifier private yang tidak berguna.

public class Product {
    String productId;
    String productName;
    int productQuantity;
    ...
}

8. Missing Alt Image

Permalsahan: Tag <img> yang tidak memiliki attribute alt.

Contoh Isu pada Proyek:

<img src="https://cdn.vcgamers.com/news/wp-content/uploads/2023/02/PODUSZKA-ROBLOX-MAN-FACE-PREZENT.jpg">

Solusi: Menambahkan attribute alt pada tag <img>.

<img src="https://cdn.vcgamers.com/news/wp-content/uploads/2023/02/PODUSZKA-ROBLOX-MAN-FACE-PREZENT.jpg" alt="Roblox Man Face">

9. Method Name Using Snake Case

Permasalahan: Nama method menggunakan snake case.

Contoh Isu pada Proyek:

void createProductPage_isCorrect(ChromeDriver driver) throws Exception {
    ...
}

Solusi: Mengubah nama method menggunakan camel case.

void createProductPageIsCorrect(ChromeDriver driver) throws Exception {
    ...
}

10. Handle Duplication

Permasalahan: Terdapat duplikasi kode yang tidak perlu seperti pada unit test untuk ProductRepositoryTest.java.

Solusi: Menggabungkan kode yang duplikat ke dalam satu method yang sama.

Product initiateProduct() {
    Product product = new Product();
    product.setProductId("eb558e9f-1c39-460e-8860-71af6af63bd6");
    product.setProductName("Sampo Cap Bambang");
    product.setProductQuantity(100);
    productRepository.create(product);
    return product;
}

CI/CD di Workflow Saya

Saya pikir, saya sudah mengimplementasikan CI/CD pada proyek saya. Saya menggunakan GitHub Actions untuk menjalankan workflow yang saya buat seperti ci.yml, scorecard, sonarcloud.yml, dan pmd.yml. Workflow-workflow ini secara otomatis akan dijalankan ketika ada push atau pull request ke suatu branch. Pada titik ini, saya sudah menerapkan Continuous Integration (CI). Untuk Continuous Deployment (CD), saya menggunakan Koyeb sebagai platform yang akan secara otomatis deploy aplikasi saya ketika ada push atau pull request ke suatu branch.

Module 1: Coding Standard

Module 1: Coding Standard

Reflection 1

Penerapan Prinsip Clean Code

1. Meaningful Names

Saya menggunakan nama yang jelas untuk penamaan variabel, fungsi, kelas, dan argumen dalam tutorial kali ini. Dengan nama yang jelas tersebut, saya tidak perlu lagi memberikan komentar untuk menjelaskan apa maksud dari keempat hal tersebut. Contoh:

@Test
    void testEditQuantityToNegative() {
        Product product = new Product();
        ...

2. Functions

Saya membuat fungsi yang menggunakan nama yang deskriptif, pendek, dan hanya melakukan satu hal. Saya juga berusaha untuk membuat fungsi yang dapat tampil pada layar saya tanpa harus melakukan scroll.

3. Comments

Saya berusaha untuk membuat komentar yang jelas dan tidak terlalu panjang. Saya juga menghindari penggunaan komentar bagi kode yang sudah terlihat jelas maksudnya. Selama pengerjaan, saya juga menerapkan "TO-DO" untuk menandai kode yang belum selesai.

4. Objects and Data Structures

Salah satu contoh yang saya terapkan yaitu ketika generate string UUID untuk tiap Product yang dibuat. Kode tersebut saya letakkan pada constructor dari Product itu sendiri. Hal ini sesuai dengan prinsip OOP daripada saya meletakkan kode tersebut pada ProductService.java atau ProductRepository.java.

Penerapan Secure Coding

Praktis yang saya terapkan yaitu input validation ketika membuat sebuah Product tanpa sebuah nama atau ketika jumlahnya bernilai negatif.

Cara Melakukan Improve Code

Hal pertama yang saya lakukan ketika mendapatkan sebuah kesalahan kode yaitu cek forum Discord Advanced Programming. Jika tidak ada, saya akan mencari di Stack Overflow atau Google. Apabila masih belum terpecahkan, saya mencoba untuk menghubungi asisten dosen, terkadang juga bertanya kepada teman. Selama menunggu jawaban, saya juga tidak jarang untuk mencoba bantuan AI seperti ChatGPT.

Reflection 2

Seputar Unit Test

  1. Perasaan dalam Membuat Unit Test

Setelah menulis kode unit test, saya merasa mudah untuk mencari bug dalam kode saya. Misal, saya ingin tau apakah kode ketika membuat Product saya benar atau tidak. Alih-alih dengan membuka localhost:8080/product/create dan manual memasukkan data, dengan unit test, saya cukup menjalankan test-nya saja. Selain itu, unit test membuat saya lebih yakin dengan kode yang saya buat.

  1. Banyaknya Test yang Diperlukan dalam Sebuah Class dan Cara untuk Yakin Bahwa Test Sudah Cukup

Menurut saya tidak ada batasan seberapa banyak test yang perlu kita buat dalam sebuah class. Semakin banyak test yang kita buat, semakin baik. Namun, kita juga harus memperhatikan code coverage yang dibutuhkan. Code coverage adalah alat ukur untuk mengukur test yang sudah dibuat oleh developer. Yang pernah saya baca, rule of thumb untuk code coverage yaitu >= 80%.

  1. Arti Code Coverage 100%

Dengan code coverage 100%, belum tentu menjamin bahwa kode yang kita buat terhindar dari bugs dan errors. Misalkan kita punya kode seperti berikut ini.

public int pangkat (int a, int b) {
    return a * b;
}

Dan kita memiliki test seperti dibawah ini.

@Test
void testPangkat() {
    assertEquals(4, pangkat(2, 2));
}

Walaupun test tersebut sudah benar dan code coverage terpenuhi, namun ada kasus dimana fungsi pangkat tersebut salah karena tidak sesuai dengan tujuannya.

Clean Code pada Functional Test

Menurut saya, hal tersebut bukan cara yang baik dalam menerapkan prinsip clean code. Tentunya mengurangi kualitas dari clean code-nya. Isu yang muncul ada karena kita menggunakan suatu prosedur dan variabel yang sama. Saran saya, hal tersebut bisa kita buatkan ke dalam satu 'Class'. Lalu kita dapat memisahkan ke dalam fungsi yang berbeda untuk setiap test yang kita buat seperti prinsip Do One Thing.

About

Tutorial Pemrograman Lanjut (Advanced Programming) 2023/2024 Genap


Languages

Language:Java 70.7%Language:HTML 27.9%Language:Dockerfile 1.4%