Menu
CoddyTech

Tổng kết: Két an toàn

Thuộc phần Lập trình hướng đối tượng trong hành trình Lua của Coddy. Bài học 48 trên 70.

challenge icon

Thử thách

Dễ

Hãy xây dựng một lớp Vault sử dụng tính riêng tư dựa trên closure để tạo ra một hệ thống lưu trữ thực sự an toàn! Vault sẽ giữ nội dung bí mật, chỉ có thể truy cập khi cung cấp đúng mật khẩu.

Bạn sẽ tổ chức code trong hai tệp:

  • Vault.lua: Tạo một lớp, trong đó cả nội dung lẫn mật khẩu đều được lưu trong các biến cục bộ bên trong hàm khởi tạo, hoàn toàn ẩn khỏi các truy cập bên ngoài. Hàm khởi tạo :new(contents, password) sẽ lưu các giá trị này vào biến cục bộ, sau đó định nghĩa một phương thức trực tiếp trên instance của đối tượng:
    • :open(attemptedPassword): kiểm tra xem mật khẩu được nhập có khớp với mật khẩu đã lưu hay không. Nếu đúng, hàm trả về nội dung bí mật. Nếu sai, hàm trả về "Access Denied".
  • main.lua: Nạp module Vault và đọc ba đầu vào: nội dung bí mật cần lưu, mật khẩu cần đặt và mật khẩu được thử. Tạo một vault với nội dung và mật khẩu đó, sau đó thử mở vault bằng mật khẩu được nhập và in ra kết quả. Đồng thời, chứng minh rằng nội dung thực sự riêng tư bằng cách thử truy cập trực tiếp vào vault.contents và in ra giá trị nhận được.

Bạn sẽ nhận ba đầu vào:

  1. Nội dung bí mật cần lưu trong vault
  2. Mật khẩu dùng để bảo vệ vault
  3. Mật khẩu được thử để mở vault

Đầu ra gồm hai dòng:

Result: {resultFromOpen}
Direct access: {whatYouGetFromVaultContents}

Ví dụ, nếu các đầu vào là Gold Coins, secret123 và secret123, đầu ra sẽ là:

Result: Gold Coins
Direct access: nil

Nếu các đầu vào là Diamond, mypass và wrongpass, đầu ra sẽ là:

Result: Access Denied
Direct access: nil

Điểm mấu chốt ở đây là cả contents lẫn password chỉ tồn tại dưới dạng biến cục bộ bên trong hàm khởi tạo. Phương thức :open() có thể truy cập chúng thông qua closure, nhưng không có gì khác có thể truy cập, kể cả vault.contents, vault._contents hay vault.password. Đây chính là tính đóng gói thực sự!

Tự làm thử

-- Nạp module Vault
local Vault = require('Vault')

-- Đọc các đầu vào
local contents = io.read()
local password = io.read()
local attemptedPassword = io.read()

-- TODO: Tạo két sắt với contents và password

-- TODO: Thử mở két sắt bằng mật khẩu đã nhập thử

-- TODO: In kết quả theo định dạng: "Result: {resultFromOpen}"

-- TODO: Thử truy cập trực tiếp vault.contents và in ra giá trị nhận được
-- In theo định dạng: "Direct access: {whatYouGetFromVaultContents}"

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Lua online