From 98132f0474c821e88e9e2e322cb7962d5b0b8810 Mon Sep 17 00:00:00 2001 From: linhptm Date: Mon, 29 May 2023 08:22:21 +0700 Subject: [PATCH] week4-code-practive --- docs/coding-practices/comment.md | 90 +++++++++++++++++ docs/coding-practices/if-else.md | 151 +++++++++++++++++++++++++++++ docs/coding-practices/unit-test.md | 137 ++++++++++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 docs/coding-practices/comment.md create mode 100644 docs/coding-practices/if-else.md create mode 100644 docs/coding-practices/unit-test.md diff --git a/docs/coding-practices/comment.md b/docs/coding-practices/comment.md new file mode 100644 index 0000000..e873d62 --- /dev/null +++ b/docs/coding-practices/comment.md @@ -0,0 +1,90 @@ +# clean code trong comments code +Một số hướng dẫn để clean trong comment +## 1. Giải thích mục đích và chức năng của code (todo comment) + +**bad** +```php +function processData($data) { + ... +} +``` +**good** +```php +// TODO: Handle validation errors +// Hàm xử lý dữ liệu đầu vào +function processData($data) { + ... +} +``` + +## 2. Chú thích các phần quan trọng hay giải thích trong mã + +**good** +```php +private function filterByCompletionMonthDay(Builder $builder, string $startDate, string $endDate): Builder + { + //Retrieve records by start time or end time compared to current time + //The start time or end time may be in the future + $startTime = $startDate ? Carbon::parse($startDate) : ''; + $endTime = $endDate ? Carbon::parse($endDate) : ''; + if ($startTime && $endTime) { + $builder->whereBetween(DB::raw("DATE_FORMAT(completion_date, '%m-%d')"), sortDatesAscending($startTime->format('m-d'), $endTime->format('m-d'))); + } + + return $builder; + } +``` + +## 3. Loại bỏ các comment không cần thiết +- Chú thích chỉ những phần quan trọng và cần thiết + +**bad** +```php +// Hàm tính tổng hai số nguyên +function calculateDiscount($price) { + // Tính giảm giá + $discount = $price * 0.2; + // Trả về giá sau khi được giảm giá + return $price - $discount; +} +``` +**good** +```php +function calculateDiscount($price) { + $discount = $price * 0.2; + return $price - $discount; +} +``` + +## 4. Tuân thủ quy ước về đặt tên và format comment: +- viết comment sao cho dễ hiểu và tuân thủ quy ước về đặt tên biến, hàm, lớp... dùng 1 loại ngôn ngữ + +**bad** +```php +//xử lý +function process_data($data) { + // code here + // ... +} +``` +**good** +```php +// Hàm xử lý dữ liệu đầu vào +function processData($data) { + // Code xử lý dữ liệu + // ... +} +``` +## 5. Sử dụng các công cụ hỗ trợ comment +- có thể sử dụng các công cụ như PHPDoc để tạo ra các comment có định dạng chuẩn cho các hàm, lớp và biến + +**good** +```php + /** + * @return string + */ +public function getModel() +{ + return User::class; +} +``` \ No newline at end of file diff --git a/docs/coding-practices/if-else.md b/docs/coding-practices/if-else.md new file mode 100644 index 0000000..e86e72b --- /dev/null +++ b/docs/coding-practices/if-else.md @@ -0,0 +1,151 @@ +# clean code cho if else 2 +## 1. Giữ đơn giản, dễ đọc và sử dụng toán tử logic một cách hiệu quả: +- Tránh việc sử dụng các điều kiện lồng nhau phức tạp, có thể làm code trở nên khó hiểu +- giúp giảm số lượng câu lệnh if-else và làm cho code ngắn gọn hơn + + **bad** +```php +if ($age >= 18 && $age <= 60) { + if ($salary > 5000) { + if ($position == "Manager") { + // todo something + } + } +} +``` +**good** +```php +if ($age >= 18 && $age <= 60 && $salary > 5000 && $position == "Manager") { + // todo something +} +``` +## 2.Xử lý các trường hợp mặc định hoặc đặc biệt hiệu quả: +- thêm một câu lệnh else để xử lý các trường hợp không khớp với bất kỳ điều kiện if nào + +**bad** +```php +if ($day == "Monday") { + // Làm việc từ 9:00 đến 17:00 +} else { + if ($day == "Tuesday") { + // Làm việc từ 10:00 đến 18:00 + } else { + // Nghỉ làm + } +} +``` +**good** +```php +if ($day == "Monday") { + // Làm việc từ 9:00 đến 17:00 +} elseif ($day == "Tuesday") { + // Làm việc từ 10:00 đến 18:00 +} else { + // Nghỉ làm +} +``` +## 3.Sắp xếp các điều kiện một cách cẩn thận: +- Sắp xếp các điều kiện theo một thứ tự logic +- Đặt các điều kiện thường xảy ra nhất hoặc đơn giản nhất đầu tiên để cải thiện hiệu suất thực thi của chương trình. + +**bad** +```php +function calculateGrade($score) { + if ($score >= 90) { + return 'A'; + } elseif ($score >= 80) { + return 'B'; + } elseif ($score >= 70) { + return 'C'; + } elseif ($score >= 60) { + return 'D'; + } else { + return 'F'; + } +} +``` +**good** +```php +function calculateGrade($score) { + if ($score < 60) { + return 'F'; + } else { + if ($score >= 90) { + return 'A'; + } elseif ($score >= 80) { + return 'B'; + } elseif ($score >= 70) { + return 'C'; + } else { + return 'D'; + } + } +} +``` +## 4.Giảm thiểu sự trùng lặp code: +- Tránh việc trùng lặp code trong các khối if và else. +- Nếu có các tác vụ hoặc thao tác chung, hãy tách ra thành các hàm hoặc biến riêng biệt để tránh lặp lại code + +**bad** +```php +if ($isLoggedIn) { + // Hiển thị nút "Đăng xuất" + echo 'Đăng xuất'; + // Hiển thị chào mừng người dùng đã đăng nhập + echo 'Chào mừng ' . $username; +} else { + // Hiển thị nút "Đăng nhập" + echo 'Đăng nhập'; + // Hiển thị chào mừng khách truy cập + echo 'Chào mừng khách truy cập'; +} +``` +**good** +```php +if ($isLoggedIn) { + // Hiển thị nút "Đăng xuất" + $buttonText = 'Đăng xuất'; + $buttonLink = 'logout.php'; + $welcomeMessage = 'Chào mừng ' . $username; +} else { + // Hiển thị nút "Đăng nhập" + $buttonText = 'Đăng nhập'; + $buttonLink = 'login.php'; + $welcomeMessage = 'Chào mừng khách truy cập'; +} + +echo '' . $buttonText . ''; +echo $welcomeMessage; +``` +## 5.early returns: +- Giảm độ sâu của khối if-else lồng nhau, làm cho code dễ đọc và hiểu hơn +- Đưa ra các xử lý đặc biệt cho các trường hợp không hợp lệ sớm hơn, giúp tránh việc thực hiện các câu lệnh không cần thiết. + +**bad** +```php +function calculateDiscount($amount, $isPremiumMember) { + if ($amount > 100) { + if ($isPremiumMember) { + return $amount * 0.2; // Giảm giá 20% cho thành viên Premium nếu tổng số tiền mua hàng vượt quá 100 + } else { + return $amount * 0.1; // Giảm giá 10% cho thành viên không Premium nếu tổng số tiền mua hàng vượt quá 100 + } + } else { + return 0; // Không giảm giá nếu tổng số tiền mua hàng không vượt quá 100 + } +} +``` +**good** +```php +function calculateDiscount($amount, $isPremiumMember) { + if ($amount <= 100) { + return 0; // Không giảm giá nếu tổng số tiền mua hàng không vượt quá 100 + } + + if ($isPremiumMember) { + return $amount * 0.2; // Giảm giá 20% cho thành viên Premium nếu tổng số tiền mua hàng vượt quá 100 + } + + return $amount * 0.1; // Giảm giá 10% cho thành viên không Premium nếu tổng số tiền mua hàng vượt quá 100 +} +``` \ No newline at end of file diff --git a/docs/coding-practices/unit-test.md b/docs/coding-practices/unit-test.md new file mode 100644 index 0000000..c9f6035 --- /dev/null +++ b/docs/coding-practices/unit-test.md @@ -0,0 +1,137 @@ +# clean code trong việc viết unit test +## 1. Sử dụng tên test case mô tả chính xác và rõ ràng: +- Tên phải nêu rõ mục tiêu và kỳ vọng của test + +**bad** +```php +public function test1() { + // ... +} +``` +**good** +```php +public function testViewListContractSuccess() { + // ... +} +``` +## 2. Giới hạn mỗi test case chỉ kiểm tra 1 điều kiện +- Mỗi test case nên tập trung vào kiểm tra 1 tính năng, giúp dễ dàng xác định nguyên nhân khi test case không thành công. + +**bad** +```php +public function testViewCreateSuccessAndCreateContractSuccess() { + // ... +} +``` +**good** +```php +public function testViewCreateContractSuccess() { + // ... +} + +public function testCreateContractSuccess() { + // ... +} +``` +## 3. Sử dụng dữ liệu mẫu cho việc khởi tạo và chuẩn bị dữ liệu +- Đảm bảo rằng dữ liệu được khởi tạo và chuẩn bị đúng cách trước khi thực hiện test case +- Sử dụng kiểu dữ liệu mẫu cho việc khởi tạo dữ liệu giúp giảm sự phức tạp và tăng tính nhất quán của test case + +**bad** +```php +public function testFunctionAddItemToCartSuccess() { + // Arrange + $cart = new Cart(); + $item = new Item("Sample Item", 10.99); + + // Act + $cart->addItem($item); + + // Assert + $this->assertEquals(1, $cart->getItemCount()); +} +``` +**good** +```php +public function testFunctionAddItemToCartSuccess() { + // Arrange + $cart = new Cart(); + $item = $this->createSampleItem(); + + // Act + $cart->addItem($item); + + // Assert + $this->assertEquals(1, $cart->getItemCount()); +} + +private function createSampleItem() { + return new Item("Sample Item", 10.99); +} +``` +## 4. Sử dụng helper functions để tránh lặp lại code: +- Nếu có một đoạn code được sử dụng nhiều lần trong các test case khác nhau, nên tạo các helper functions để tái sử dụng code và giảm sự lặp lại. + +**bad** +```php +public function testAddItemToCart() { + // Arrange + ... + + // Act + $cart->addItem($item); + + // Assert + $this->assertEquals(1, $cart->getItemCount()); + $this->assertTrue($cart->containsItem($item)); +} + +public function testRemoveItemFromCart() { + // Arrange + ... + + // Act + $cart->removeItem($item); + + // Assert + $this->assertEquals(0, $cart->getItemCount()); + $this->assertFalse($cart->containsItem($item)); +} +``` +**good** +```php +public function testAddItemToCart() { + // Arrange + ... + + // Act + $cart->addItem($item); + + // Assert + $this->assertCartContainsItem($cart, $item); +} + +public function testRemoveItemFromCart() { + // Arrange + ... + $cart->addItem($item); + + // Act + $cart->removeItem($item); + + // Assert + $this->assertCartDoesNotContainItem($cart, $item); +} + +//helper function + +private function assertCartContainsItem(Cart $cart, Item $item) { + $this->assertEquals(1, $cart->getItemCount()); + $this->assertTrue($cart->containsItem($item)); +} + +private function assertCartDoesNotContainItem(Cart $cart, Item $item) { + $this->assertEquals(0, $cart->getItemCount()); + $this->assertFalse($cart->containsItem($item)) +} +``` \ No newline at end of file