<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nguyen Hoang</title>
    <description>The latest articles on DEV Community by Nguyen Hoang (@timthoi).</description>
    <link>https://dev.to/timthoi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1953389%2F302da5ba-8b79-48d8-9e8a-c42b2496cfb2.jpg</url>
      <title>DEV Community: Nguyen Hoang</title>
      <link>https://dev.to/timthoi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/timthoi"/>
    <language>en</language>
    <item>
      <title>bancon</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Fri, 07 Feb 2025 03:46:37 +0000</pubDate>
      <link>https://dev.to/timthoi/bancon-1dnh</link>
      <guid>https://dev.to/timthoi/bancon-1dnh</guid>
      <description>&lt;p&gt;$cycle_length = 2 * ($friends - 1);&lt;br&gt;
    $effective_time = $time % $cycle_length;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$current = 1;
$direction = 1;

for ($i = 0; $i &amp;lt; $effective_time; $i++) {
    $current += $direction;

    if ($current &amp;gt; $friends) {
        $direction = -1;
        $current = $friends - 1;
    } elseif ($current &amp;lt; 1) {
        $direction = 1;
        $current = 2;
    }
}

return [$current - $direction, $current];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;add $effective_time == 0 =  $cycle_length *2&lt;/p&gt;

</description>
      <category>php</category>
      <category>programming</category>
    </item>
    <item>
      <title>baton</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Fri, 07 Feb 2025 03:04:04 +0000</pubDate>
      <link>https://dev.to/timthoi/baton-1pao</link>
      <guid>https://dev.to/timthoi/baton-1pao</guid>
      <description>&lt;p&gt;&amp;lt;?php&lt;/p&gt;

&lt;p&gt;/*&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete the 'batonPass' function below.
*&lt;/li&gt;
&lt;li&gt;The function is expected to return an INTEGER_ARRAY.&lt;/li&gt;
&lt;li&gt;The function accepts following parameters:&lt;/li&gt;
&lt;li&gt; 1. INTEGER friends&lt;/li&gt;
&lt;li&gt; 2. LONG_INTEGER time
*/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;function batonPass($friends, $time) {&lt;br&gt;
   $current = 1;&lt;br&gt;&lt;br&gt;
    $direction = 1; // 1, -1&lt;br&gt;
    $last_passer = null;&lt;br&gt;
    $last_received = null;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for ($i = 0; $i &amp;lt; $time; $i++) {
    $next = $current + $direction;

    if ($next &amp;gt; $friends) {
        $direction = -1;
        $next = $current - 1;
    } elseif ($next &amp;lt; 1) {
        $direction = 1;
        $next = $current + 1;
    }

    $last_passer = $current;
    $last_received = $next;

    $current = $next;
}

return [$last_passer, $last_received];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;$fptr = fopen(getenv("OUTPUT_PATH"), "w");&lt;/p&gt;

&lt;p&gt;$friends = intval(trim(fgets(STDIN)));&lt;/p&gt;

&lt;p&gt;$time = intval(trim(fgets(STDIN)));&lt;/p&gt;

&lt;p&gt;$result = batonPass($friends, $time);&lt;/p&gt;

&lt;p&gt;fwrite($fptr, implode("\n", $result) . "\n");&lt;/p&gt;

&lt;p&gt;fclose($fptr);&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Khi nào dùng cái nào? ✅ Nếu hệ thống nhỏ, đơn giản dùng Choreography-based SAGA (event-driven) ✅ Nếu hệ thống phức tạp, có nhiều bước dùng Orchestration-based SAGA</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Mon, 03 Feb 2025 02:43:41 +0000</pubDate>
      <link>https://dev.to/timthoi/khi-nao-dung-cai-nao-neu-he-thong-nho-don-gian-dung-choreography-based-saga-event-driven-3md3</link>
      <guid>https://dev.to/timthoi/khi-nao-dung-cai-nao-neu-he-thong-nho-don-gian-dung-choreography-based-saga-event-driven-3md3</guid>
      <description></description>
      <category>architecture</category>
      <category>microservices</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>Symbols - JavaScript const KEY1: unique symbol = Symbol('key1'); const KEY2: unique symbol = Symbol('key2'); const obj = { [KEY1]: 'Data for KEY1', [KEY2]: 'Data for KEY2', }; console.log(obj[KEY1]); // 'Data for KEY1'</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Mon, 30 Dec 2024 07:14:48 +0000</pubDate>
      <link>https://dev.to/timthoi/symbols-javascript-const-key1-unique-symbol-symbolkey1-const-key2-unique-symbol--242f</link>
      <guid>https://dev.to/timthoi/symbols-javascript-const-key1-unique-symbol-symbolkey1-const-key2-unique-symbol--242f</guid>
      <description></description>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>set vs array</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Fri, 27 Dec 2024 03:27:01 +0000</pubDate>
      <link>https://dev.to/timthoi/set-vs-array-47pa</link>
      <guid>https://dev.to/timthoi/set-vs-array-47pa</guid>
      <description>&lt;p&gt;Tập hợp (Set) và mảng (Array) đều là iterable objects trong JavaScript và TypeScript, nghĩa là bạn có thể duyệt qua các phần tử của chúng bằng các cấu trúc lặp như for...of. Tuy nhiên, chúng có một số khác biệt quan trọng:&lt;/p&gt;

&lt;p&gt;Sự khác biệt giữa Set và Array:&lt;br&gt;
Tính duy nhất của phần tử:&lt;/p&gt;

&lt;p&gt;Set: Các phần tử trong Set là duy nhất, tức là không có phần tử nào lặp lại. Nếu bạn thêm một phần tử đã tồn tại vào Set, nó sẽ không thay đổi.&lt;br&gt;
Array: Mảng có thể chứa các phần tử trùng lặp.&lt;br&gt;
Thứ tự các phần tử:&lt;/p&gt;

&lt;p&gt;Set: Các phần tử trong Set được lưu trữ theo thứ tự chèn vào, nhưng không có chỉ mục (index) như trong mảng.&lt;br&gt;
Array: Các phần tử trong mảng có thứ tự và được truy cập thông qua chỉ mục.&lt;br&gt;
Hiệu suất:&lt;/p&gt;

&lt;p&gt;Set: Các thao tác như tìm kiếm, thêm, và xóa phần tử trong Set thường có hiệu suất tốt hơn so với mảng, đặc biệt là khi Set chứa nhiều phần tử.&lt;br&gt;
Array: Các thao tác tương tự trên mảng có thể chậm hơn, đặc biệt là khi mảng lớn và chứa nhiều phần tử trùng lặp.&lt;br&gt;
Ví dụ minh họa:&lt;br&gt;
Tạo và sử dụng Set:&lt;br&gt;
TypeScript&lt;br&gt;
const mySet = new Set();&lt;/p&gt;

&lt;p&gt;// Thêm phần tử vào Set&lt;br&gt;
mySet.add(1);&lt;br&gt;
mySet.add(2);&lt;br&gt;
mySet.add(2); // Không thêm phần tử này vì nó đã tồn tại&lt;/p&gt;

&lt;p&gt;console.log(mySet); // Output: Set { 1, 2 }&lt;/p&gt;

&lt;p&gt;// Duyệt qua các phần tử của Set&lt;br&gt;
for (let value of mySet) {&lt;br&gt;
    console.log(value);&lt;br&gt;
}&lt;br&gt;
// Output:&lt;br&gt;
// 1&lt;br&gt;
// 2&lt;/p&gt;

&lt;p&gt;// Kiểm tra sự tồn tại của một phần tử&lt;br&gt;
console.log(mySet.has(1)); // Output: true&lt;br&gt;
console.log(mySet.has(3)); // Output: false&lt;/p&gt;

&lt;p&gt;// Xóa một phần tử&lt;br&gt;
mySet.delete(1);&lt;br&gt;
console.log(mySet); // Output: Set { 2 }&lt;br&gt;
Tạo và sử dụng Array:&lt;br&gt;
TypeScript&lt;br&gt;
const myArray = [1, 2, 2];&lt;/p&gt;

&lt;p&gt;// Duyệt qua các phần tử của Array&lt;br&gt;
for (let value of myArray) {&lt;br&gt;
    console.log(value);&lt;br&gt;
}&lt;br&gt;
// Output:&lt;br&gt;
// 1&lt;br&gt;
// 2&lt;br&gt;
// 2&lt;/p&gt;

&lt;p&gt;// Kiểm tra sự tồn tại của một phần tử&lt;br&gt;
console.log(myArray.includes(1)); // Output: true&lt;br&gt;
console.log(myArray.includes(3)); // Output: false&lt;/p&gt;

&lt;p&gt;// Xóa một phần tử (sử dụng filter để tạo một mảng mới không chứa phần tử đó)&lt;br&gt;
const newArray = myArray.filter(item =&amp;gt; item !== 1);&lt;br&gt;
console.log(newArray); // Output: [2, 2]&lt;br&gt;
2 vulnerabilities detected&lt;br&gt;
Tóm tắt:&lt;br&gt;
Set đảm bảo tính duy nhất của các phần tử và thường có hiệu suất tốt hơn cho các thao tác tìm kiếm, thêm, và xóa.&lt;br&gt;
Array cho phép các phần tử trùng lặp và các phần tử có thứ tự, truy cập thông qua chỉ mục.&lt;br&gt;
Hy vọng điều này giúp bạn hiểu rõ hơn về sự khác biệt giữa Set và Array!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>larvel queue not dispath</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Thu, 05 Dec 2024 06:43:54 +0000</pubDate>
      <link>https://dev.to/timthoi/larvel-queue-not-dispath-5b91</link>
      <guid>https://dev.to/timthoi/larvel-queue-not-dispath-5b91</guid>
      <description>&lt;p&gt;queue:listen and queue:work not working on windows&lt;/p&gt;

&lt;p&gt;It ok &lt;br&gt;
append "database"&lt;/p&gt;

&lt;p&gt;php artisan queue:work database --queue=email-marketing-queue --sleep=3 --tries=3&lt;/p&gt;

</description>
    </item>
    <item>
      <title>add item to array</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Mon, 25 Nov 2024 02:07:32 +0000</pubDate>
      <link>https://dev.to/timthoi/add-item-to-array-538g</link>
      <guid>https://dev.to/timthoi/add-item-to-array-538g</guid>
      <description>&lt;p&gt;const [items, setItems] = useState([]);&lt;br&gt;
  const [input, setInput] = useState("");&lt;/p&gt;

&lt;p&gt;const handleAddItem = () =&amp;gt; {&lt;br&gt;
    if (input.length &amp;gt; 0) { &lt;br&gt;
      setItems([...items, input]);&lt;br&gt;
      setInput('');&lt;br&gt;
    }&lt;br&gt;
  };&lt;/p&gt;

</description>
    </item>
    <item>
      <title>react day 1</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Fri, 22 Nov 2024 05:07:48 +0000</pubDate>
      <link>https://dev.to/timthoi/react-day-1-49ih</link>
      <guid>https://dev.to/timthoi/react-day-1-49ih</guid>
      <description>&lt;p&gt;Your task is to create a React application called "Code Review Feedback" that tracks and manages feedback on various aspects of code quality. The component should have upvote and downvote functionality for each aspect, and it must meet all specified requirements.&lt;/p&gt;

&lt;p&gt;image&lt;/p&gt;

&lt;p&gt;Detailed Requirements&lt;/p&gt;

&lt;p&gt;The CodeReviewFeedback component displays five aspects: Readability, Performance, Security, Documentation, and Testing.&lt;br&gt;
Each aspect has two buttons labeled "Upvote" and "Downvote" to allow users to vote.&lt;br&gt;
The initial count for upvotes and downvotes for each aspect is set to zero.&lt;br&gt;
Clicking the "Upvote" button should increment the upvote count for that aspect by 1.&lt;br&gt;
Clicking the "Downvote" button should increment the downvote count for that aspect by 1.&lt;br&gt;
Ensure the counts update in the UI immediately upon clicking.&lt;br&gt;
The component should have a subtle animation when the voting count is updated to enhance the user experience.&lt;/p&gt;

&lt;p&gt;Sample Interaction&lt;br&gt;
Initial State&lt;/p&gt;

&lt;p&gt;Display all five aspects with their respective upvote and downvote buttons.&lt;br&gt;
Each aspect shows an initial count of 0 for upvotes and downvotes.&lt;br&gt;
User Action 1&lt;/p&gt;

&lt;p&gt;User clicks "Upvote" for Readability.&lt;br&gt;
The upvote count for Readability displays 1.&lt;br&gt;
User Action 2&lt;/p&gt;

&lt;p&gt;User clicks "Downvote" for Performance.&lt;br&gt;
The downvote count for Performance displays 1.&lt;br&gt;
User Action 3 3. User clicks "Upvote" for Security and Documentation multiple times. 4. The upvote count for Security displays 2 and Documentation displays 3.&lt;/p&gt;

&lt;p&gt;Hey there! Please enter the full-screen mode for the best experience&lt;br&gt;
Authorishanhackerrank&lt;br&gt;
DifficultyMedium&lt;br&gt;
Max Score60&lt;br&gt;
Submitted By195&lt;br&gt;
Need Help?&lt;br&gt;
View discussions&lt;br&gt;
View top submissions&lt;br&gt;
rate this challenge&lt;/p&gt;

&lt;p&gt;MORE DETAILS&lt;br&gt;
Download problem statement&lt;br&gt;
Suggest Edits&lt;br&gt;
Share on Facebook&lt;/p&gt;

&lt;p&gt;`import React, { useState } from "react";&lt;/p&gt;

&lt;p&gt;const categories = [&lt;br&gt;
  { id: 0, name: "Readability" },&lt;br&gt;
  { id: 1, name: "Performance" },&lt;br&gt;
  { id: 2, name: "Security" },&lt;br&gt;
  { id: 3, name: "Documentation" },&lt;br&gt;
  { id: 4, name: "Testing" },&lt;br&gt;
];&lt;/p&gt;

&lt;p&gt;const FeedbackCategory = ({ id, name, upvotes, downvotes, onUpvote, onDownvote }) =&amp;gt; (&lt;br&gt;
  &lt;/p&gt;
&lt;br&gt;
    &lt;h2&gt;{name}&lt;/h2&gt;
&lt;br&gt;
    &lt;br&gt;
      {/* Upvote button &lt;em&gt;/}&lt;br&gt;
      
        className="py-10 px-15"&lt;br&gt;
        data-testid={`upvote-btn-${id}`}&lt;br&gt;
        onClick={() =&amp;gt; onUpvote(id)}&lt;br&gt;
      &amp;gt;&lt;br&gt;
        👍 Upvote&lt;br&gt;
      &lt;br&gt;
      {/&lt;/em&gt; Downvote button &lt;em&gt;/}&lt;br&gt;
      
        className="py-10 px-15 danger"&lt;br&gt;
        data-testid={`downvote-btn-${id}`}&lt;br&gt;
        onClick={() =&amp;gt; onDownvote(id)}&lt;br&gt;
      &amp;gt;&lt;br&gt;
        👎 Downvote&lt;br&gt;
      &lt;br&gt;
    &lt;/em&gt;&lt;br&gt;
    {/ Display counts */}&lt;br&gt;
    &lt;p&gt;&lt;br&gt;
      Upvotes: &lt;strong&gt;{upvotes}&lt;/strong&gt;&lt;br&gt;
    &lt;/p&gt;
&lt;br&gt;
    &lt;p&gt;&lt;br&gt;
      Downvotes: &lt;strong&gt;{downvotes}&lt;/strong&gt;&lt;br&gt;
    &lt;/p&gt;
&lt;br&gt;
  &lt;br&gt;
);

&lt;p&gt;const FeedbackSystem = () =&amp;gt; {&lt;br&gt;
  const [votes, setVotes] = useState(&lt;br&gt;
    categories.reduce(&lt;br&gt;
      (acc, category) =&amp;gt; ({&lt;br&gt;
        ...acc,&lt;br&gt;
        [category.id]: { upvotes: 0, downvotes: 0 },&lt;br&gt;
      }),&lt;br&gt;
      {}&lt;br&gt;
    )&lt;br&gt;
  );&lt;/p&gt;

&lt;p&gt;const handleUpvote = (id) =&amp;gt; {&lt;br&gt;
    setVotes((prevVotes) =&amp;gt; ({&lt;br&gt;
      ...prevVotes,&lt;br&gt;
      [id]: { ...prevVotes[id], upvotes: prevVotes[id].upvotes + 1 },&lt;br&gt;
    }));&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;const handleDownvote = (id) =&amp;gt; {&lt;br&gt;
    setVotes((prevVotes) =&amp;gt; ({&lt;br&gt;
      ...prevVotes,&lt;br&gt;
      [id]: { ...prevVotes[id], downvotes: prevVotes[id].downvotes + 1 },&lt;br&gt;
    }));&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;return (&lt;br&gt;
    &lt;/p&gt;
&lt;br&gt;
      &lt;br&gt;
        {categories.map(({ id, name }) =&amp;gt; (&lt;br&gt;
          
            key={id}&lt;br&gt;
            id={id}&lt;br&gt;
            name={name}&lt;br&gt;
            upvotes={votes[id].upvotes}&lt;br&gt;
            downvotes={votes[id].downvotes}&lt;br&gt;
            onUpvote={handleUpvote}&lt;br&gt;
            onDownvote={handleDownvote}&lt;br&gt;
          /&amp;gt;&lt;br&gt;
        ))}&lt;br&gt;
      &lt;br&gt;
    &lt;br&gt;
  );&lt;br&gt;
};

&lt;p&gt;export default FeedbackSystem;`&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Data Transfer Object la gi khai niem nay tu dau ma ra</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Tue, 19 Nov 2024 06:25:54 +0000</pubDate>
      <link>https://dev.to/timthoi/data-transfer-object-la-gi-khai-niem-nay-tu-dau-ma-ra-19mk</link>
      <guid>https://dev.to/timthoi/data-transfer-object-la-gi-khai-niem-nay-tu-dau-ma-ra-19mk</guid>
      <description>&lt;p&gt;Data Transfer Object (DTO)&lt;br&gt;
Data Transfer Object (DTO) là một mẫu thiết kế (design pattern) được sử dụng để đóng gói dữ liệu và truyền tải nó giữa các lớp hoặc tầng trong một ứng dụng mà không chứa bất kỳ logic kinh doanh nào. DTO giúp cô lập dữ liệu cần thiết cho một yêu cầu cụ thể, giảm sự phụ thuộc không cần thiết giữa các tầng và tối ưu hóa luồng dữ liệu.&lt;/p&gt;

&lt;p&gt;Nguồn gốc&lt;br&gt;
DTO lần đầu tiên được giới thiệu trong cuốn sách "Patterns of Enterprise Application Architecture" (2002) của Martin Fowler. Đây là một phần của các mẫu thiết kế nhằm giải quyết vấn đề giao tiếp giữa các tầng trong kiến trúc phần mềm, đặc biệt là trong các ứng dụng sử dụng mô hình Client-Server hoặc Service-Oriented Architecture (SOA).&lt;/p&gt;

&lt;p&gt;Tại sao cần DTO?&lt;br&gt;
Tách biệt logic và dữ liệu:&lt;/p&gt;

&lt;p&gt;DTO chỉ dùng để mang dữ liệu, không chứa logic kinh doanh, đảm bảo rằng mỗi tầng chỉ nhận dữ liệu cần thiết.&lt;br&gt;
Giảm thiểu sự rò rỉ của mô hình dữ liệu tầng backend lên tầng giao diện (frontend).&lt;br&gt;
Tối ưu hiệu năng:&lt;/p&gt;

&lt;p&gt;DTO có thể chỉ chứa các thuộc tính cần thiết, giúp giảm tải dữ liệu không cần thiết khi truyền qua mạng hoặc giữa các lớp.&lt;br&gt;
Tăng tính bảo mật:&lt;/p&gt;

&lt;p&gt;DTO có thể giới hạn thông tin được truyền ra ngoài, tránh việc lộ dữ liệu nhạy cảm từ database.&lt;br&gt;
Dễ dàng bảo trì:&lt;/p&gt;

&lt;p&gt;Khi thay đổi cấu trúc database hoặc logic backend, DTO có thể được điều chỉnh mà không làm ảnh hưởng đến các tầng khác.&lt;br&gt;
Ví dụ về DTO&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Không sử dụng DTO:
Nếu bạn trực tiếp truyền mô hình Eloquent từ Laravel (hoặc ORM khác) ra API, bạn có thể truyền cả dữ liệu nhạy cảm:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;php&lt;br&gt;
Copy code&lt;br&gt;
public function show(User $user)&lt;br&gt;
{&lt;br&gt;
    return response()-&amp;gt;json($user);&lt;br&gt;
}&lt;br&gt;
Kết quả JSON có thể bao gồm các trường không mong muốn như password, api_token, v.v.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sử dụng DTO:
php
Copy code
namespace App\DTO;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;class UserDTO&lt;br&gt;
{&lt;br&gt;
    public string $id;&lt;br&gt;
    public string $name;&lt;br&gt;
    public string $email;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function __construct(string $id, string $name, string $email)
{
    $this-&amp;gt;id = $id;
    $this-&amp;gt;name = $name;
    $this-&amp;gt;email = $email;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Trong Controller:&lt;/p&gt;

&lt;p&gt;php&lt;br&gt;
Copy code&lt;br&gt;
use App\DTO\UserDTO;&lt;/p&gt;

&lt;p&gt;public function show(User $user)&lt;br&gt;
{&lt;br&gt;
    $userDTO = new UserDTO(&lt;br&gt;
        $user-&amp;gt;id,&lt;br&gt;
        $user-&amp;gt;name,&lt;br&gt;
        $user-&amp;gt;email&lt;br&gt;
    );&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return response()-&amp;gt;json($userDTO);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Kết quả JSON chỉ chứa các trường cần thiết:&lt;/p&gt;

&lt;p&gt;json&lt;br&gt;
Copy code&lt;br&gt;
{&lt;br&gt;
    "id": "123",&lt;br&gt;
    "name": "John Doe",&lt;br&gt;
    "email": "&lt;a href="mailto:john.doe@example.com"&gt;john.doe@example.com&lt;/a&gt;"&lt;br&gt;
}&lt;br&gt;
Ưu điểm của DTO&lt;br&gt;
Cô lập dữ liệu:&lt;/p&gt;

&lt;p&gt;Giúp phân tách dữ liệu từ tầng dữ liệu (Database) với tầng giao tiếp (API).&lt;br&gt;
Tương thích dễ dàng với các thay đổi:&lt;/p&gt;

&lt;p&gt;Nếu dữ liệu nguồn (database) thay đổi, DTO có thể được cập nhật mà không ảnh hưởng đến các tầng khác.&lt;br&gt;
Giảm phụ thuộc giữa các tầng:&lt;/p&gt;

&lt;p&gt;DTO là một cấu trúc trung gian, giảm sự liên kết chặt chẽ giữa tầng giao diện (UI) và tầng dữ liệu.&lt;br&gt;
Nhược điểm của DTO&lt;br&gt;
Tăng thêm lớp trừu tượng:&lt;/p&gt;

&lt;p&gt;Việc triển khai DTO có thể làm tăng độ phức tạp, nhất là trong các ứng dụng nhỏ.&lt;br&gt;
Yêu cầu thêm mã nguồn:&lt;/p&gt;

&lt;p&gt;Bạn cần viết thêm các lớp DTO và các logic chuyển đổi (mapping), tăng thời gian phát triển.&lt;/p&gt;

&lt;p&gt;Khi nào nên sử dụng DTO?&lt;br&gt;
Ứng dụng lớn: Khi ứng dụng có nhiều tầng (frontend, backend, service) hoặc sử dụng các giao tiếp mạng (API, microservices).&lt;br&gt;
Bảo mật dữ liệu: Khi muốn kiểm soát chặt chẽ dữ liệu nào được phép gửi ra ngoài.&lt;br&gt;
Hiệu năng: Khi cần tối ưu hóa dữ liệu truyền qua mạng, chỉ gửi thông tin cần thiết.&lt;/p&gt;

&lt;p&gt;Data Transfer Object (DTO)&lt;br&gt;
Data Transfer Object (DTO) là một mẫu thiết kế (design pattern) được sử dụng để đóng gói dữ liệu và truyền tải nó giữa các lớp hoặc tầng trong một ứng dụng mà không chứa bất kỳ logic kinh doanh nào. DTO giúp cô lập dữ liệu cần thiết cho một yêu cầu cụ thể, giảm sự phụ thuộc không cần thiết giữa các tầng và tối ưu hóa luồng dữ liệu.&lt;/p&gt;

&lt;p&gt;Nguồn gốc&lt;br&gt;
DTO lần đầu tiên được giới thiệu trong cuốn sách "Patterns of Enterprise Application Architecture" (2002) của Martin Fowler. Đây là một phần của các mẫu thiết kế nhằm giải quyết vấn đề giao tiếp giữa các tầng trong kiến trúc phần mềm, đặc biệt là trong các ứng dụng sử dụng mô hình Client-Server hoặc Service-Oriented Architecture (SOA).&lt;/p&gt;

&lt;p&gt;Tại sao cần DTO?&lt;br&gt;
Tách biệt logic và dữ liệu:&lt;/p&gt;

&lt;p&gt;DTO chỉ dùng để mang dữ liệu, không chứa logic kinh doanh, đảm bảo rằng mỗi tầng chỉ nhận dữ liệu cần thiết.&lt;br&gt;
Giảm thiểu sự rò rỉ của mô hình dữ liệu tầng backend lên tầng giao diện (frontend).&lt;br&gt;
Tối ưu hiệu năng:&lt;/p&gt;

&lt;p&gt;DTO có thể chỉ chứa các thuộc tính cần thiết, giúp giảm tải dữ liệu không cần thiết khi truyền qua mạng hoặc giữa các lớp.&lt;br&gt;
Tăng tính bảo mật:&lt;/p&gt;

&lt;p&gt;DTO có thể giới hạn thông tin được truyền ra ngoài, tránh việc lộ dữ liệu nhạy cảm từ database.&lt;br&gt;
Dễ dàng bảo trì:&lt;/p&gt;

&lt;p&gt;Khi thay đổi cấu trúc database hoặc logic backend, DTO có thể được điều chỉnh mà không làm ảnh hưởng đến các tầng khác.&lt;br&gt;
Ví dụ về DTO&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Không sử dụng DTO:
Nếu bạn trực tiếp truyền mô hình Eloquent từ Laravel (hoặc ORM khác) ra API, bạn có thể truyền cả dữ liệu nhạy cảm:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;php&lt;br&gt;
Copy code&lt;br&gt;
public function show(User $user)&lt;br&gt;
{&lt;br&gt;
    return response()-&amp;gt;json($user);&lt;br&gt;
}&lt;br&gt;
Kết quả JSON có thể bao gồm các trường không mong muốn như password, api_token, v.v.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sử dụng DTO:
php
Copy code
namespace App\DTO;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;class UserDTO&lt;br&gt;
{&lt;br&gt;
    public string $id;&lt;br&gt;
    public string $name;&lt;br&gt;
    public string $email;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function __construct(string $id, string $name, string $email)
{
    $this-&amp;gt;id = $id;
    $this-&amp;gt;name = $name;
    $this-&amp;gt;email = $email;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Trong Controller:&lt;/p&gt;

&lt;p&gt;php&lt;br&gt;
Copy code&lt;br&gt;
use App\DTO\UserDTO;&lt;/p&gt;

&lt;p&gt;public function show(User $user)&lt;br&gt;
{&lt;br&gt;
    $userDTO = new UserDTO(&lt;br&gt;
        $user-&amp;gt;id,&lt;br&gt;
        $user-&amp;gt;name,&lt;br&gt;
        $user-&amp;gt;email&lt;br&gt;
    );&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return response()-&amp;gt;json($userDTO);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Kết quả JSON chỉ chứa các trường cần thiết:&lt;/p&gt;

&lt;p&gt;json&lt;br&gt;
Copy code&lt;br&gt;
{&lt;br&gt;
    "id": "123",&lt;br&gt;
    "name": "John Doe",&lt;br&gt;
    "email": "&lt;a href="mailto:john.doe@example.com"&gt;john.doe@example.com&lt;/a&gt;"&lt;br&gt;
}&lt;br&gt;
Ưu điểm của DTO&lt;br&gt;
Cô lập dữ liệu:&lt;/p&gt;

&lt;p&gt;Giúp phân tách dữ liệu từ tầng dữ liệu (Database) với tầng giao tiếp (API).&lt;br&gt;
Tương thích dễ dàng với các thay đổi:&lt;/p&gt;

&lt;p&gt;Nếu dữ liệu nguồn (database) thay đổi, DTO có thể được cập nhật mà không ảnh hưởng đến các tầng khác.&lt;br&gt;
Giảm phụ thuộc giữa các tầng:&lt;/p&gt;

&lt;p&gt;DTO là một cấu trúc trung gian, giảm sự liên kết chặt chẽ giữa tầng giao diện (UI) và tầng dữ liệu.&lt;br&gt;
Nhược điểm của DTO&lt;br&gt;
Tăng thêm lớp trừu tượng:&lt;/p&gt;

&lt;p&gt;Việc triển khai DTO có thể làm tăng độ phức tạp, nhất là trong các ứng dụng nhỏ.&lt;br&gt;
Yêu cầu thêm mã nguồn:&lt;/p&gt;

&lt;p&gt;Bạn cần viết thêm các lớp DTO và các logic chuyển đổi (mapping), tăng thời gian phát triển.&lt;br&gt;
Khi nào nên sử dụng DTO?&lt;br&gt;
Ứng dụng lớn: Khi ứng dụng có nhiều tầng (frontend, backend, service) hoặc sử dụng các giao tiếp mạng (API, microservices).&lt;br&gt;
Bảo mật dữ liệu: Khi muốn kiểm soát chặt chẽ dữ liệu nào được phép gửi ra ngoài.&lt;br&gt;
Hiệu năng: Khi cần tối ưu hóa dữ liệu truyền qua mạng, chỉ gửi thông tin cần thiết.&lt;br&gt;
Các công cụ hỗ trợ DTO&lt;br&gt;
Một số framework và thư viện hỗ trợ việc tạo và xử lý DTO dễ dàng hơn:&lt;/p&gt;

&lt;p&gt;Laravel: Dễ dàng tự định nghĩa DTO trong các lớp PHP đơn giản.&lt;br&gt;
MapStruct (Java): Thư viện tự động tạo các lớp mapping giữa DTO và entity.&lt;br&gt;
AutoMapper (.NET): Tự động ánh xạ entity sang DTO và ngược lại.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>trong mo hinh ddd cac domain lien ket voi anhu the nao</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Tue, 19 Nov 2024 04:31:38 +0000</pubDate>
      <link>https://dev.to/timthoi/trong-mo-hinh-ddd-cac-domain-lien-ket-voi-anhu-the-nao-91o</link>
      <guid>https://dev.to/timthoi/trong-mo-hinh-ddd-cac-domain-lien-ket-voi-anhu-the-nao-91o</guid>
      <description>&lt;p&gt;Trong mô hình DDD (Domain-Driven Design), các domain được thiết kế để phản ánh logic nghiệp vụ của hệ thống một cách rõ ràng và được phân tách dựa trên ngữ cảnh (Bounded Context). Việc liên kết giữa các domain (Bounded Contexts) được thực hiện thông qua các phương pháp sau:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Phân cách domain qua Bounded Context
Bounded Context đại diện cho một vùng trong hệ thống nơi một domain có các quy tắc và mô hình riêng.
Các Bounded Contexts không nên phụ thuộc chặt chẽ vào nhau và chỉ tương tác khi cần thiết, thông qua các mối quan hệ rõ ràng.&lt;/li&gt;
&lt;li&gt;Các phương pháp liên kết domain
a. Context Mapping
Là kỹ thuật mô tả và định nghĩa cách các Bounded Contexts giao tiếp với nhau.
Một số kiểu liên kết phổ biến:
Shared Kernel: Chia sẻ một phần nhỏ của mô hình (ví dụ: một số lớp hoặc module chung).
Customer-Supplier: Một context đóng vai trò cung cấp dữ liệu, context khác tiêu thụ dữ liệu đó.
Published Language: Giao tiếp thông qua các định dạng tiêu chuẩn (VD: JSON, XML) hoặc ngôn ngữ chung.
Anti-Corruption Layer (ACL): Lớp chống nhiễu, giúp dịch dữ liệu từ context này sang context khác để tránh làm hỏng logic của domain.
b. Domain Events
Domain Events được sử dụng để giao tiếp giữa các domain một cách lỏng lẻo.
Ví dụ:
Khi Domain A thực hiện một hành động, nó tạo ra một event như "OrderPlaced".
Domain B lắng nghe sự kiện này và xử lý (ví dụ: cập nhật trạng thái kho).
Ưu điểm:
Tách biệt rõ ràng giữa domain phát sự kiện và domain xử lý sự kiện.
Hỗ trợ hệ thống phân tán hoặc kiến trúc microservices.
c. Application Services
Application Services (dịch vụ ứng dụng) nằm ngoài domain và chịu trách nhiệm phối hợp các domain.
Application Services thường:
Gửi lệnh tới domain khác.
Lấy kết quả từ domain và trả lại cho người dùng hoặc hệ thống khác.
d. Repositories
Các domain có thể giao tiếp gián tiếp thông qua repositories.
Repository cho phép truy xuất và lưu trữ dữ liệu mà không cần phụ thuộc vào chi tiết cụ thể của database.
e. Shared Database (hạn chế sử dụng)
Các domain sử dụng chung cơ sở dữ liệu.
Hạn chế:
Có thể gây xung đột giữa các domain.
Khó khăn trong việc bảo trì và mở rộng.&lt;/li&gt;
&lt;li&gt;Ví dụ thực tế
Bối cảnh
Giả sử bạn có một hệ thống thương mại điện tử với các domain sau:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Order Management: Quản lý đơn hàng.&lt;br&gt;
Inventory Management: Quản lý kho.&lt;br&gt;
Customer Management: Quản lý khách hàng.&lt;br&gt;
Liên kết giữa các domain&lt;br&gt;
Khi một đơn hàng được đặt:&lt;/p&gt;

&lt;p&gt;Order Management tạo một Domain Event: OrderPlaced.&lt;br&gt;
Inventory Management nhận sự kiện này, kiểm tra kho, và giảm số lượng tồn kho.&lt;br&gt;
Customer Management:&lt;/p&gt;

&lt;p&gt;Khi khách hàng tạo đơn hàng, Order Management có thể gọi một Application Service để:&lt;br&gt;
Lấy thông tin khách hàng từ Customer Management.&lt;br&gt;
Kiểm tra điều kiện hợp lệ của khách hàng trước khi xử lý đơn hàng.&lt;br&gt;
Sử dụng ACL:&lt;/p&gt;

&lt;p&gt;Nếu Inventory Management sử dụng hệ thống bên ngoài (ERP), lớp Anti-Corruption Layer chuyển đổi dữ liệu từ hệ thống ERP sang định dạng mà Inventory Management hiểu được.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Các điểm cần lưu ý
Cố gắng giảm phụ thuộc trực tiếp giữa các domain:
Sử dụng sự kiện (Domain Events).
Giao tiếp qua Application Services hoặc ACL.
Phân định rạch ròi giữa các Bounded Contexts:
Mỗi context chỉ quan tâm đến nghiệp vụ của mình.
Sử dụng Context Mapping để xác định rõ ràng cách các domain liên kết với nhau.
Tóm tắt
Domain liên kết thông qua: Context Mapping, Domain Events, Application Services, ACL, hoặc Repositories.
Cách tiếp cận khuyên dùng:
Ưu tiên giao tiếp lỏng lẻo (Domain Events).
Hạn chế chia sẻ trực tiếp dữ liệu hoặc phụ thuộc chặt chẽ.
Mục tiêu là giữ mỗi domain độc lập và dễ dàng mở rộng khi cần.&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>System-Design-Preparation</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Wed, 23 Oct 2024 03:30:48 +0000</pubDate>
      <link>https://dev.to/timthoi/system-design-preparation-58l2</link>
      <guid>https://dev.to/timthoi/system-design-preparation-58l2</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/arkapg211002/System-Design-Preparation" rel="noopener noreferrer"&gt;https://github.com/arkapg211002/System-Design-Preparation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.geeksforgeeks.org/complete-roadmap-to-learn-system-design/" rel="noopener noreferrer"&gt;https://www.geeksforgeeks.org/complete-roadmap-to-learn-system-design/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://coursehunters.online/t/educative-io-design-gurus-grokking-the-system-design-interview-part-5/584" rel="noopener noreferrer"&gt;https://coursehunters.online/t/educative-io-design-gurus-grokking-the-system-design-interview-part-5/584&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>𝐭𝐡𝐞 𝐝𝐢𝐟𝐟𝐞𝐫𝐞𝐧𝐜𝐞𝐬 between 𝐆𝐢𝐭 𝐌𝐞𝐫𝐠𝐞 and 𝐆𝐢𝐭 𝐑𝐞𝐛𝐚𝐬𝐞.</title>
      <dc:creator>Nguyen Hoang</dc:creator>
      <pubDate>Wed, 23 Oct 2024 03:24:54 +0000</pubDate>
      <link>https://dev.to/timthoi/between-and--i1</link>
      <guid>https://dev.to/timthoi/between-and--i1</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yloucsnuxhu7r1bx0nn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yloucsnuxhu7r1bx0nn.png" alt="Image description" width="800" height="993"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me tell you 𝐭𝐡𝐞 𝐝𝐢𝐟𝐟𝐞𝐫𝐞𝐧𝐜𝐞𝐬 between 𝐆𝐢𝐭 𝐌𝐞𝐫𝐠𝐞 and 𝐆𝐢𝐭 𝐑𝐞𝐛𝐚𝐬𝐞.&lt;br&gt;
𝘞𝘩𝘦𝘯 𝘸𝘦 𝐦𝐞𝐫𝐠𝐞 𝐜𝐡𝐚𝐧𝐠𝐞𝐬 𝘧𝘳𝘰𝘮 𝘰𝘯𝘦 𝘎𝘪𝘵 𝘣𝘳𝘢𝘯𝘤𝘩 𝘵𝘰 𝘢𝘯𝘰𝘵𝘩𝘦𝘳, 𝘸𝘦 𝘤𝘢𝘯 𝘶𝘴𝘦 ‘𝘨𝘪𝘵 𝘮𝘦𝘳𝘨𝘦’ 𝘰𝘳 ‘𝘨𝘪𝘵 𝘳𝘦𝘣𝘢𝘴𝘦’. &lt;/p&gt;

&lt;p&gt;𝘛𝘩𝘦 𝘥𝘪𝘢𝘨𝘳𝘢𝘮 𝘣𝘦𝘭𝘰𝘸 𝘴𝘩𝘰𝘸𝘴 𝘩𝘰𝘸 𝘵𝘩𝘦 𝘵𝘸𝘰 𝘤𝘰𝘮𝘮𝘢𝘯𝘥𝘴 𝘸𝘰𝘳𝘬.&lt;/p&gt;

&lt;p&gt;𝐆𝐢𝐭 𝐌𝐞𝐫𝐠𝐞&lt;br&gt;
This creates a new commit G’ in the main branch. G’ ties the histories of both main and feature branches.&lt;/p&gt;

&lt;p&gt;Git merge is 𝐧𝐨𝐧-𝐝𝐞𝐬𝐭𝐫𝐮𝐜𝐭𝐢𝐯𝐞. Neither the main nor the feature branch is changed.&lt;/p&gt;

&lt;p&gt;𝐆𝐢𝐭 𝐑𝐞𝐛𝐚𝐬𝐞&lt;br&gt;
Git rebase moves the feature branch histories to the head of the main branch. It creates new commits E’, F’, and G’ for each commit in the feature branch.&lt;/p&gt;

&lt;p&gt;The benefit of rebase is that it has 𝐥𝐢𝐧𝐞𝐚𝐫 𝐜𝐨𝐦𝐦𝐢𝐭 𝐡𝐢𝐬𝐭𝐨𝐫𝐲.&lt;/p&gt;

&lt;p&gt;Rebase can be dangerous if “the golden rule of git rebase” is not followed.&lt;/p&gt;

&lt;p&gt;𝐓𝐡𝐞 𝐆𝐨𝐥𝐝𝐞𝐧 𝐑𝐮𝐥𝐞 𝐨𝐟 𝐆𝐢𝐭 𝐑𝐞𝐛𝐚𝐬𝐞&lt;br&gt;
Never use it on public branches!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
