Diễn Đàn Tin Học » Tutorial Room » Lập trình » Software Engineering » Craftsman-Truyện dài nhiều tập Craftsman 17 - Call the Guards Còn nhớ bài "Quên đi hàm main" - bài 11 trong series craftsman? Chuyện gì sẽ xảy ra với Alphonse sau khi cậu ta làm Jasmine nổi cáu. Hãy theo dõi tiếp cuộc hành trình này.
Gọi bảo kê
Dự kiến chuyện tệ hại nhất sau khi "đụng" với Jasmine, Alphonse học được cách dùng mới cho điều kiện cách if - và khám phá bên trong ngoại diện bình thường của người hướng dẫn mới hàm chứa một cái đầu tỉ mỉ
Còn nhớ bài "Quên đi hàm main" - bài 11 trong series craftsman? Chuyện gì sẽ
xảy ra với Alphonse sau khi cậu ta làm Jasmine nổi cáu. Hãy theo dõi tiếp cuộc
hành trình này.
Gọi bảo kê
Dự kiến chuyện tệ hại nhất sau khi "đụng" với Jasmine, Alphonse học được cách
dùng mới cho điều kiện cách if - và khám phá bên trong ngoại diện bình
thường của người hướng dẫn mới hàm chứa một cái đầu tỉ mỉ - chương 17
Robert C. Martin
Nhật ký thân mến: Tuần học việc đầu tiên của tôi với ông C đã hoàn tất. Tôi học
được thật nhiều nhưng tôi cũng đã làm rối lung tung cả lên. Hồi thứ Hai, Jerry
yêu cầu tôi viết một chương trình để tạo số nguyên. Đến thứ Ba, gã lại yêu cầu
tôi viết chương trình tạo số nguyên tố. Trọn ngày thứ Tư dành cho việc làm
SocketServer có thể chạy được. Thứ Năm chúng tôi bắt
đầu làm việc với SMCRemoteClient và tôi đã Micahed -1-
Jerry. Tôi gặp Jasmine chiều hôm ấy trong phòng khách của các tay du mục -2-.
Nhưng đến thứ Sáu lại là một ngày tôi xấu hổ nhất trong đời. Tôi không gặp lại
Jasmine (Ms. J) từ khi chúng tôi hoàn tất công việc chiều thứ Sáu. Quả là một
tuần "lên voi xuống ngựa" -3-
Tôi trải qua mấy ngày cuối tuần bệ rạc, chắc mẩm thế nào cũng bị chuyển sang bộ
phận vệ sinh và tái dụng, dọn rửa lò phản ứng hoặc kỳ cọ mớ rêu mốc. Tôi chẳng
màng mặc quần áo hay ăn uống.
Dù gì đi chăng nữa, bây giờ là tối thứ Hai và tôi đang viết để kể cậu nghe sự
thể của ngày đầu trong tuần thứ nhì. Nó cũng không quá tệ. Thật ra tôi bắt đầu
cảm thấy phấn chấn trở lại.
Sáng hôm nay, tôi thức dậy trong lòng nặng trĩu. Sau khi dùng xong điểm tâm, tôi
lết thếch lê đến phòng làm việc, phỏng chừng cô J đang đợi tôi ở bàn máy nhưng
thay vào đó là một phụ nữ trung tuần đẫy đà với mớ tóc điểm sương ngang vai và
nụ cười hiền từ, nụ cười ít nhiều còn phảng phất dấu ấn của những năm tươi trẻ
ngày trước. Lúc nhìn tôi, mắt bà nhấp nháy và bà cười khẽ. "Cậu hẳn là
Alphonse," bà nói, đưa tay ra. "Tôi tên là Jean. Tôi nghe khá nhiều về cậu. Cậu
đói bụng không? Tôi có một ít bánh mì sandwich ngon lắm trong giỏ nếu cậu muốn,
hay cậu thích một quả táo hay một trái chuối."
Quả thật có chiếc giỏ to trên sàn cạnh nơi bà ngồi. Trông chừng như nó không chỉ
chứa sandwich và chuối. Bối rối, tôi bắt tay bà và nói, "dạ vâng, thưa bà - ý
tôi, không thưa bà - ý tôi - vâng, tôi đúng là Alphonse, và không, cám ơn bà đã
mời tôi sandwich và tôi - ườm... ờ.... rất vui khi được gặp bà."
Bà nhìn tôi một cách nghiêm khắc nhưng cái nhếch mép phảng phất nét hiền từ của
một người mẹ. "Này, chúng ta không lần khân với cái mớ "Bà" ngớ ngẩn đó nghe
chưa. Tôi nhất định không phải là "Bà" của ai cả. Cậu gọi tôi là Jean thôi, cậu
bé thân mến."
Ườm, cám ơn Jean," tôi trả lời. "Vậy cô J đâu nhỉ?"
"Ai thế cậu bé?"
"Èm... Jasmine đó," Tôi trả lời một cách miễn cưỡng. "Lẽ ra cô ta và tôi làm
việc chung với nhau."
"Ôi giời, trước giờ tôi chưa hề nghe ai gọi cô ta là cô J cả. Chắc cô nàng buộc
cậu gọi như thế phải không? Tôi không nghĩ có ai gọi cô ta gì khác ngoài cái tên
Jasmine. Con bé thật đáng yêu, phải không nhỉ? Mà thôi, cậu bé thân mến, hiện
tại ông C muốn cô ta lo công việc khác, cho nên từ rày về sau tôi sẽ làm việc
với cậu."
"Bà?" tôi đớ người ra. "Ô," tôi lặp bặp. "Ôi..."
"Nào, cậu ngồi đây đi cậu bé thân mến và để tôi nói cho cậu nghe tôi đang nghĩ
gì," Jean nói, trong khi khi vỗ nhẹ trên chiếc ghế cạnh bà.
"Đang nghĩ gì?"
"Tôi xem xét chương trình này trong suốt nửa giờ qua - tôi thích làm việc sớm,
cậu biết không -- nhưng chẳng phải sớm hơn thường lệ gì đâu -- tôi biết một cậu
con trai đang lớn thì cần ngủ và điểm tâm. Mà thôi, tôi rất hài lòng với chương
trình này. Cậu có một chuỗi test rất lý thú và phần mã nguồn rất dễ đọc, cấu
trúc lại gọn gàng. Nhưng có một điều làm tôi thắc mắc, cậu bé thân mến."
"Ùm -- thắc mắc?"
"Đúng thế cậu bé! Tôi xem xét khắp nơi trong chương trình này và không hề thấy
hàm main. Khi nào cậu sẽ viết phần này vậy hở cậu?"
"Ùm, à, Jerry nói là -" tôi lập bặp.
"Ồ, để tôi đoán thử Jerry nói gì. Jerry là một thằng bé đáng yêu," Jean ngắt
ngang, đôi mắt bà nhấp nháy. "Nhưng tôi nghĩ đôi khi cậu ta nên cần thêm manh
mối để lý giải vấn đề. Nhưng thôi, tôi không nên có ý kiến không tốt về người
khác. Jerry là một lập trình viên giỏi, cậu bé thân mến, cậu đừng để ý đến những
điều tôi nói nhá. Nào, hãy viết hàm main. Cậu muốn bắt
đầu không? Sáng nay mấy ngón tay tôi hơi bị cứng. Hãy nghe tôi khuyên này," bà
cười khúc khích "đừng bị lão hoá."
Đớ người ra từ một chuỗi ngôn từ thằng tuồn tuột của bà, tôi nhón lấy bàn phím
và bắt đầu gõ:
public void main(
"Ô, nào nào, cậu bé thân mến!" Jean ngưng tôi lại. "Cậu làm việc ở đây được bao
lâu rồi nhỉ? cậu phải viết một cái test trước - cậu không thể cắm đầu vào viết
hàm main ngay như vậy được! Chúng ta sẽ đi về đâu nếu
ai cũng viết mấy cái hàm mà không viết tests trước? Tôi có thể cho cậu biết:
(chúng ta sẽ ở) trong một quả dưa chua! -4-
Không, cậu bé, xoá nó đi và viết cái test trước."
Bà lấy ra từ trong giỏ một đôi que đan và bắt đầu làm việc với một mảnh y phục
nhiều màu có hình dáng na ná như một mảnh khăn choàng -5-,
khe khẽ ngâm nga một giai điệu đơn tẻ trong khi tôi xoá mớ chữ vừa viết xong và
bắt đầu lại.
Làm cách nào để test hàm main? cách tốt nhất là gọi nó
và bảo đảm nó làm những gì nó nên làm. Hàm main giải dịch các thông số trên dòng
lệnh, bởi thế, gọi nó chỉ đơn thuần là việc chuyển các thông số cho đúng. Thế
nên tôi bắt đầu gõ lại:
|
|
public void testMain() throws
Exception {
SMCRemoteClient.main(new
String[]{"myFile.sm"}); |
|
Jean ghé mắt nhìn và bảo, "tốt đó, nhưng ở đâu ra cái
myFile.sm vậy? Mình không thể để nó nằm ngổn ngang như thế được, phải
không nào? Không, mình sẽ tạo nó ở ngay đây, phải không? và đừng quên xoá nó khi
mình đã xong nhá cậu bé thân mến. Không gì tệ hại bằng một mớ hồ sơ cũ nằm chổng
chơ, lúc nào tôi cũng bảo thế."
Thế rồi tôi tiếp tục gõ:
|
|
public void testMain() throws Exception {
File f =
createTestFile("myFile.sm", "the content");
SMCRemoteClient.main(new String[]{"myFile.sm"});
f.delete();
File resultFile = new
File("resultFile.java");
assertTrue(resultFile.exists());
resultFile.delete();
} |
|
Jean hoàn tất thêm một dòng (đan) trên mảnh khăn choàng trong khi tôi gõ mã. Bà
ngước lên nhìn khi tôi hoàn tất và nói: "Nào, cậu bé, êm rồi đó, nhưng thật tình
tôi nghĩ main có thể không đủ thời gian để hoàn thành
trách nhiệm trước khi phân đoạn xoá đó có tác dụng. Nên nhớ cậu bé, cậu có hàng
lô các socket threads đang chạy và dễ thấy trong mớ thread này có một thread vẫn
đang chạy ngay khi main trả về. Không, cậu bé, khoan
hẵn làm gì cả ngay lúc này; chỉ ghi nhớ trong đầu thôi. Bây giờ cậu nên viết
main, phải không?"
Tôi tự nhủ bà già này khá sắc sảo và bắt đầu viết phần hàm main.
|
|
public static void main(String[] args)
{
SMCRemoteClient client = new
SMCRemoteClient();
client.setFilename(args[0]);
if (client.prepareFile())
if (client.connect())
if
(client.compileFile())
client.close();
else { //
compileFile
System.out.println("failed to compile");
}
else { // connect
System.out.println("failed to connect");
}
else { // prepareFile
System.out.println("failed to
prepare");
}
} |
|
"Ôi chao ơi, xem có thật sướng mắt không! Tôi nghĩ cách cậu chú thích những đoạn
điều kiện cách else rất mẫn đạt. Dẫu vậy, tôi không
biết nếu cậu thử đảo ngược ý của các đoạn điều kiện cách và dùng chúng như những
phần bảo kê thì có dễ đọc hơn không. Đừng, cậu bé thân mến, hẵng khoan đổi nó.
Hãy xem nó có chạy được hay không cái đã. Không đáng để thay đổi quá nhiều thứ
cho đến khi mình biết chắc chương trình có làm việc hay không, cậu đồng ý không
nào? Đầu tiên làm cho nó chạy trước, rồi mới làm cho nó chỉnh sau."
Thế rồi tôi chạy thử cái test, và nó làm việc ngon lành ngay lần đầu.
"Ồ, đúng là ngoạn mục!" Bà ta nói trong khi ghé mắt nhìn. "Bây giờ chúng ta thử
thay đổi phần điều kiện cách if."
Thế rồi tôi đổi hàm cho phần điều kiện cách if được
bảo vệ.
|
|
public static void main(String[] args) {
SMCRemoteClient client = new
SMCRemoteClient();
client.setFilename(args[0]);
if (!client.prepareFile())
{
System.out.println("failed
to prepare");
return;
}
if (!client.connect())
{
System.out.println("failed
to connect");
return;
}
if (!client.compileFile())
{
System.out.println("failed
to compile");
client.close();
return;
}
client.close();
} |
|
Jean đặt mớ đồ đan vào giỏ và xem xét kỹ lưỡng đoạn mã. "Rồi, tôi xem nó được
hơn một chút rồi đó, tôi không có ý càm ràm phần lặp ở đoạn
close. Và tính chất vi phạm trong lối nhập đơn, xuất đơn, mấy cái này hơi
bị vướng víu một chút. Dẫu vậy, nó còn bảnh hơn mớ dòng mã nguồn được đẩy vào
(từ lề bên trái) -6-, cậu đồng ý không nào?
Tất nhiên chúng ta có thể thay đổi ba hàm đó cho phép chúng throw exceptions -7-,
nhưng rồi chúng ta phải catch -7- chúng, và thế cũng
khá phiền. Thôi, bây giờ cứ để yên như vậy. Nào, tôi nghĩ đã đến lúc giải lao,
phải không cậu bé? Cậu thích mang dùm tôi chiếc giỏ xách này vào phòng ăn không?
Tôi luôn có thói nhồi nhét vào giỏ nhiều hơn cần thiết và sau ít lâu cái của khỉ
này trở nên nặng trình trịch."
Chú thích
-1- Từ này đã được giải thích một lần trong phần 13 - "Một giải
pháp tốt hơn". "Micah" ở đây, trong bài này, có lẽ là một loại đặc quyền hoặc
một vinh dự lớn lao. Theo tự điển Merriam-Webster thì Micah là tên của một nhà
tiên tri người Do Thái ở thế kỷ thứ 8 sau Công nguyên. "Micah" phát triển từ
nguyên thủy MIkhAyAh (tiếng Hebrew).[Back]
-2- journeymen đã được chú thích ở bài 14 - Transaction
Actions. Journeymen có nghĩa bóng chỉ cho những tay lão luyện trong nghề và
thích "lang thang" đi tìm những chân trời mới.[Back]
-3- "roller-coaster week": roller-coaster là một loại xe trược
chạy vòng vèo theo cấu trúc dựng sẵn của một giàn giáo. Xe lướt trên
roller-coaster với vận tốc nhanh và lên xuống theo cấu trúc dựng sẵn. Ở đây, tác
giả hình tượng hoá một tuần làm việc của Alphonse như đi roller-coaster chỉ cho
một tuần đi qua rất nhanh và ở trạng thái "khi lên, khi xuống". Tôi tạm dịch là
một tuần lên voi, xuống ngựa cho gần với tiếng Việt.[Back]
-4- in a pickle, một ngạn ngữ chỉ cho tình trạng hoặc môi
trường không hay và không dễ thoát ra. "Pickle" là một loại dưa chua trong dấm
ví dụ như trái dưa leo ủ chua (người châu Âu, châu Mỹ và châu Úc rất thích ăn
loại này). Ăn thì thích nhưng thử tưởng tượng bị ủ trong một trái dưa chua thì
sao?[Back]
-5- shawl, một loại khăn choàng đầu và vai dành cho mùa lạnh.
Có lẽ từ "khăn sô" đi từ chữ shawl này chăng? Từ đồng nghĩa tiếng Pháp là
"châle", cũng đọc nôm na là "sô". Chữ shawl tiếng Anh có nguồn gốc từ chữ "shAl"
tiếng Persian (người Iran cổ đại). Tôi chưa tìm ra được chính xác nguồn gốc chữ
"khăn sô" của tiếng Việt. Có nguồn cho rằng "khăn sô" đi từ gốc vải sô chuyên
dùng làm khăn choàng, cũng có nguồn cho rằng "khăn sô" là một dạng từ vay mượn
từ tiếng nước ngoài. Ai có hứng thú (và thời gian) khảo cứu (về ngôn ngữ học),
xin đóng góp kết quả và ý kiến.[Back]
-6- indentation, lối đẩy dòng chữ thụt vào từ lề trang giấy (từ
bên trái hoặc bên phải).[Back]
-7- throw exceptions và catch exceptions, có lẽ dân lập trình
nhón nhén chút đỉnh đến Java hẳn biết các thuật ngữ này. Tôi để nguyên thuật ngữ
này mà không cố gắng dịch vì có thể làm sai lạc khi cố gắng chuyển ngữ. [Back]
|