THẢO LUẬN

đúng r, cảm ơn b nhé, code mà k chạy là bug ngày 😄

0
thg 2 20, 2024 3:19 SA

diffusion là Khuếch tán, Khuyến tán chắc sai chính tả rồi

0

// initiate new ram and replace the current one var newRam = new Ram("Kingston", "64GB"); iPhone.printSpecification(); Đoạn này đang thiếu phần set lại ram mới cho smartPhone phải không chủ thớt

0

cám ơn a đã theo dõi ❤️

0

chúc e năm mới nhiều bình an và thành công ❤️

0

Chúc mừng anh ạ!! Chúc anh thật nhiều sức khỏe, thuận lợi trong công việc và luôn yêu đời. Đọc bài viết của anh giúp em có thêm động lực để phấn đấu hơn!! Cảm ơn anh đã chia sẻ♥️

+1

Oh nice catch e ơi 😃

Trước giờ a toàn chạy trên VPS Ubuntu nên chỉ cài docker engine, và khi deploy cũng vậy, lên k8s cũng thế

Nên behaviour nó khá là ổn định

Giờ thì a đã hiểu tại sao trên Mac (Docker desktop) của a nó cũng xêm xêm như trên ubuntu rồi 😃

0

Cảm ơn bạn nhé. Cảm ơn bạn đã đặt câu hỏi. Mình xin giải thích bằng 2 ví dụ khác như sau:

DIP và OCP

Cả Nguyên Lý Đảo Ngược Phụ Thuộc (DIP) và Nguyên Lý Đóng/Mở (OCP) đều đóng vai trò quan trọng trong việc tạo ra mã nguồn linh hoạt và dễ bảo trì. Tuy nhiên, mỗi nguyên lý lại có điểm nhấn riêng biệt và cách thức áp dụng khác nhau.

Nguyên Lý Định Nghĩa Mục Tiêu
OCP Các module phải mở cho việc mở rộng nhưng đóng cho việc sửa đổi. Tạo ra ứng dụng có thể dễ dàng mở rộng mà không cần sửa đổi code hiện tại.
DIP Các module cấp cao không nên phụ thuộc vào các module cấp thấp, cả hai nên phụ thuộc vào abstraction. Giảm sự phụ thuộc giữa các module, làm cho hệ thống dễ dàng thay đổi và bảo trì.

Để làm rõ hơn sự khác biệt giữa Nguyên Lý Đóng/Mở (OCP) và Nguyên Lý Đảo Ngược Phụ Thuộc (DIP), chúng ta cùng xem xét kỹ hơn thông qua hai ví dụ cụ thể, mỗi nguyên lý một, trong bối cảnh phát triển ứng dụng với React.

1. Nguyên Lý Đóng/Mở (OCP)

OCP nhấn mạnh việc thiết kế components và modules sao cho chúng có thể dễ dàng mở rộng mà không cần sửa đổi code hiện tại.

Ví dụ về OCP:

Xét component Button ban đầu:

const Button = ({ type, onClick }) => {
  if (type === "save") {
    return <button className="save" onClick={onClick}>Save</button>;
  }
  if (type === "cancel") {
    return <button className="cancel" onClick={onClick}>Cancel</button>;
  }
  // Thêm nhiều điều kiện cho các loại button khác...
};

Component này không tuân thủ OCP vì mỗi khi bạn cần một loại nút mới, bạn phải sửa đổi Button để thêm một điều kiện mới.

Để tuân thủ OCP, bạn có thể tái cấu trúc như sau:

const Button = ({ className, onClick, children }) => (
  <button className={className} onClick={onClick}>
    {children}
  </button>
);

Sau đó, sử dụng Button để tạo các nút mở rộng mà không cần sửa đổi Button gốc:

const SaveButton = ({ onClick }) => <Button className="save" onClick={onClick}>Save</Button>;
const CancelButton = ({ onClick }) => <Button className="cancel" onClick={onClick}>Cancel</Button>;

Ở đây, Button được thiết kế để dễ dàng mở rộng (thêm SaveButton, CancelButton), mà không cần sửa đổi code của chính nó.

2. Nguyên Lý Đảo Ngược Phụ Thuộc (DIP)

DIP nhấn mạnh việc thiết kế các module sao cho module cấp cao không phụ thuộc trực tiếp vào module cấp thấp, mà cả hai đều phụ thuộc vào abstractions.

Ví dụ về DIP:

Giả sử bạn có một component form đơn giản:

// Component form không tuân thủ DIP
const UserForm = ({ saveUser }) => {
  const handleSubmit = (event) => {
    event.preventDefault();
    // Xử lý và gọi saveUser
  };

  return <form onSubmit={handleSubmit}>...</form>;
};

Ở đây, UserForm phụ thuộc trực tiếp vào hàm saveUser, một logic cụ thể. Điều này khiến UserForm khó tái sử dụng với các hành động khác.

Để áp dụng DIP, bạn có thể thiết kế lại như sau:

// Component form tuân thủ DIP
const UserForm = ({ onSubmit }) => {
  return <form onSubmit={onSubmit}>...</form>;
};

UserForm giờ đây chỉ phụ thuộc vào một abstraction (onSubmit), không còn phụ thuộc trực tiếp vào hành động cụ thể nào, giúp nó dễ dàng tái sử dụng với các hành động khác nhau:

<UserForm onSubmit={handleSaveUser} />
<UserForm onSubmit={handleUpdateUser} />

Chốt lại:

Nguyên Lý Điểm Nhấn Ví dụ
OCP Mở rộng chức năng mà không sửa đổi code hiện tại. Tái cấu trúc Button để dễ dàng tạo SaveButton, CancelButton mà không cần sửa đổi Button.
DIP Giảm sự phụ thuộc trực tiếp giữa các module. Thiết kế UserForm sao cho nó chỉ phụ thuộc vào onSubmit, một abstraction, thay vì một hành động cụ thể.

Hy vọng qua sự so sánh này, bạn có thể rõ ràng phân biệt được hai nguyên lý này và áp dụng chúng một cách hiệu quả trong dự án React của mình.

0

Chào a, chắc a cũng thấy avt e quen quen :V. Bài này trước đó thực ra e đã đọc rồi và có thực hành theo a nên cũng hiểu kha khá (vì lúc đó e cũng hơi non nên chưa ngấm được hết kiến thức của a viết ra :V). Nhung vì thời gian dài vừa rồi ko có động đến docker nên cũng ko có nhớ được chuẩn. Đợt này e có quay lại docker và như đã nói thì e đã chuyển sang docker-desktop để cho tiện việc học và thực hành hơn. Nhưng cuối cùng sau khá nhiều lần chạy thử thì e đã nhận ra là behaviour của docker engine và docker desktop đổi với owner của file hay directory là khác nhau. Cụ thể: Nếu như những ngày trước e có sử dụng docker engine hay vừa rồi e có switch docker context từ docker desktop về docker engine thì tất cả những điều a viết trong bài đều dúng. Còn nếu sử dụng docker desktop (đã tích hợp sẵn docker engine của nó và các service cần thiết khác nữa ) thì rất nhiều thứ khác như là:

  • nếu sử dụng bind mount thì tất cả các file hoặc directory thuộc user hiện tại của host sau khi mount vào container đều có owner là root (dù cho user trong container hiện tại có là root hay www-data hay là ai đi nữa)
  • nếu tạo file từ bên trong container (ví dự user trong container là root) thì file được tạo nếu xem từ trong container thì của root, nhưng nếu cùng thời điểm đó xem ở ngoài host thì lại là của user hiện tại
  • nếu bên ngoài có 1 file thuộc root thì sau khi bind mount thì xem trong container thì owner lại chuyển thành nobody

Toàn bộ những gạch đầu dòng trên đều là do e tự thử nghiệm ko dưới 10 lần rồi tổng kết lại được vây Qua đây thì thấy được nhược điểm của docker desktop là không những sử dụng vm chứ ko được tối ưu như docker engine thì vấn đề với owner + permission cũng là thứ cần được đẵn đo để đánh đổi lấy ưu điểm là tiện lợi, dễ thao tác. Nhân đây cũng cảm ơn a về series docker này và vì đã trả lời nhiệt tình các thắc mắc của m.n

0
thg 2 19, 2024 11:59 SA

@just-pthai-it e đọc đến bài non root của a nhé, nhưng mà cứ thong thả đi từng bài đừng nhảy cóc , dần dần e sẽ thấy 😃

0
thg 2 19, 2024 11:18 SA

Thanks

0

Hay quá, tuổi trẻ tài cao, hâm mộ

+1
thg 2 19, 2024 10:30 SA

@maitrungduc1410 nhân tiện cho e hỏi ở docs có phần nào đề cập đến phần owner + permission của bind mount ko nhỉ a. Như là file sau khi mount vào container thì owner sẽ là của user nào ấy ạ. Hoặc nếu a có thể chia sẻ về phần này thêm thì rất tuyệt với ạ. Em cảm ơn

0

ad ơi, cho mình hỏi khi mình đã build xong cụm k8s bằng RKE này, nếu mình muốn scale cụm k8s thêm node worker hay master thì làm thế nào ạ

0
Avatar
đã bình luận cho bài viết
thg 2 19, 2024 9:41 SA

đợt này codesandbox thay đổi tính năng hơi khác tí, em bị lỗi ở link nào mục nào để anh kiểm tra lại

0

cảm ơn tác giả vì bài viết , ví dụ thực tế dễ hiểu . Mình có thắc mắc về ví dụ DIP và OCP , mình thấy 2 phần này ví dụ như nhau . mong bạn giải thích chi tiết hơn . Chúc bạn sức khỏe

+1

Chúc mừng năm mới anh ạ😀. Lâu lắm rồi mới thấy anh viết lại bài, vẫn ấn tượng a từ bài giảng Docker của anh cùng với thầy William Cường

0

chúc e năm mới thật nhiều thành công nhé 😉

0

cố lên e ơi, rụng làm lại 😄

0
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí