Diễn Đàn Tin Học
 Trang chủ      Tutorial Room      Diễn đàn      Liên hệ - Góp ý
Diễn Đàn Tin Học
Thông tin
Download
Tutorial Room
Sản phẩm
Thống kê
Hiện có 10 người đang trực tuyến.
Google


Diễn Đàn Tin Học » Tutorial Room » Lập trình » Software Engineering » Craftsman-Truyện dài nhiều tập

Craftsman 13 - A Better Solution
Trong khi làm việc với bài tập SocketServer, Alphonse khám phá ra việc chuyển tải objects đơn giản và hiệu xuất hơn chuyển tải strings - phải chăng anh ta đã "Micahed" kẻ du hành của chàng?

  Thông tin      
  Chuyên đề   Lập trình - Software Engineering  
  Dịch giả   hnd  
  Bài gốc   http://www.vninformatics.com/forum/?action=msg&msg=1023492790#1023492790  
  Tựa gốc   Craftsman 13 - A Better Solution  
 

Xin được thay mặt diễn đàn cảm ơn bạn về bài viết này.

 

 

Một giải pháp tốt hơn

Trong khi làm việc với bài tập SocketServer, Alphonse khám phá ra việc chuyển tải objects đơn giản và hiệu xuất hơn chuyển tải strings - phải chăng anh ta đã "Micahed" -1- kẻ du hành -3- của chàng?

Robert C. Martin

Ở mức .045 hiện tại, Cái đích vẫn là những phần đời của tương lai. Mỗi thế hệ từ lúc khởi hành cảm như những phần đời kéo dài vô tận trước khi chúng xảy ra. Ðôi khi cảm giác này đầy tuyệt vọng - nhưng hôm nay không phải thế. Hôm nay, tôi dùng một ít thời gian vô tận ấy để chế diễu Jerry.

Tôi duỗi tay ra phía trước bàn phím và bẻ mấy khớp tay. Tôi lắc lư cái đầu, giả vờ chỉnh xương cổ. Tôi dừng lại, nhìn lơ láo, tỏ vẻ trầm ngâm. "Ô!" tôi nói, "tôi nghĩ là tôi biết một cách hay hơn!" Jerry đảo mắt và thở dài, đợi tôi bắt tay vào làm. Tôi quyết định không đi quá trớn, thế rồi tôi bắt đầu làm việc.

Ðể viết một hồ sơ xuyên qua socket, Jerry đã phải gởi ba dòng chữ trước. Một dòng có string "Sending", dòng kế tiếp chứa tên hồ sơ và dòng cuối chỉ định chiều dài của hồ sơ. Rồi sau đó Jerry mới gởi chính hồ sơ ấy như một chuỗi từ. Ðoạn mã như sau:
 

   private void writeSendFileCommand() throws IOException {
      os.println("Sending");
      os.println(itsFilename);
      os.println(itsFileLength);
     char buffer[] = new char[(int) itsFileLength];
      fileReader.read(buffer);
      os.write(buffer);
      os.flush();
   }
 


Khi đọc hồ sơ ngược lại từ socket, gã gọi readLine ba lần, mỗi lần cho mỗi ba dòng gã gởi đi. Gã dùng "Sending" string như một phương thức nhận diện của một chuyển xuất và lưu giữ cái thứ nhì như tên của hồ sơ; cái thứ ba là chiều dài của hồ sơ. Gã dùng nó để chỉ định chuỗi từ được dùng như một tầng đệm. Rồi sau đó gã dùng chiều dài để đọc số lượng từ thích ứng từ socket.
 

   private void parse(String cmd) throws Exception {
      if (cmd != null) {
          if (cmd.equals("Sending")) {
              filename = is.readLine();
              fileLength = Long.parseLong (is.readLine());
              content = new char[(int)fileLength];
              is.read(content,0, (int)fileLength);
              fileReceived = true;
        }
      }
  }
 


Mọi thứ làm việc ngon lành, nhưng tôi biết cách hay hơn. Ðầu tiên, tôi đổi đoạn test để đọc objects thay vì những dòng:
 

   public void serve(Socket socket) {
      try {
             os = new PrintStream(socket.getOutputStream());
             is = new ObjectInputStream(socket.getInputStream());
             os.println("SMCR Test Server");
             os.flush();
             parse((String)is.readObject());
             } catch (Exception e) {
        }
  }
 
  private void parse(String cmd) throws Exception {
      if (cmd != null) {
          if (cmd.equals("Sending")) {
          filename = (String)is.readObject();
          fileLength = is.readLong();
          content = (char[]) is.readObject();
          fileReceived = true;
        }
      }
  }
 


Kế tiếp tôi thay đổi phần SMCRemoteClient để viết objects thay vì strings.
 

   public boolean connect() {
      ...
      os = new ObjectOutputStream(smcrSocket.getOutputStream());
      ...
  }
 
  private void writeSendFileCommand() throws IOException {
          os.writeObject("Sending");
          os.writeObject(itsFilename);
          os.writeLong(itsFileLength);
          char buffer[] = new char[(int) itsFileLength];
          fileReader.read(buffer);
          os.writeObject(buffer);
          os.flush();
  }
 


Tôi chạy trọn bộ các tests và chúng làm việc ngon lành. "Thấy chưa?" tôi gáy. "Tôi nghiệm ra viết objects thay vì strings thì tốt hơn."

Eureka!
Tôi nhìn Jerry, nhưng có gì đó thay đổi - đôi mắt gã không tập trung. Gã đứng dậy và bắt đầu rảo quanh. Thỉnh thoảng gã dừng lại, nhìn vào màn hình, nhìn tôi, lắc đầu và lại tiếp tục rảo bước. Gã lẩm nhẩm gì đó về năm tháng, kinh nghiệm và sự ngu xuẩn. Tôi hơi hãi.

Sau rốt, gã dừng lại, nhìn tôi thẳng vào mắt và nói: "À, Alphonse, mày xong rồi đó."

"Tôi làm gì sai vậy Jerry?" tôi thì thầm.

Gã nhìn tôi chằm chặp vài giây. Thế rồi gã xoay người hướng về thang máy và ra lệnh, "đi theo tao."

Chuyến đi trên thang máy yên lặng như nhà mồ. Trạng thái của Jerry khó mà đoán nổi: gã không hẳn là giận dữ nhưng chắc chắn là gã bực dọc, và lẽ gì đó tôi đã dính vào sự bực dọc này. Trong thang máy, chúng tôi lặng lẽ thay đổi vị trí để giảm mức lệch coriolis -2- tôi cố nghiệm ra lý do tại sao phần mã nguồn đơn giản tôi thay đổi có thể tạo ảnh hưởng ghê gớm đến gã như thế.

Tôi theo Jerry vào một phòng khách ở một trong những tầng thuộc "low-g". Các tay học việc không thường được phép vào các tầng trên .49g. Trên đường đi lên, tôi không dõi các bảng hiệu của các tầng lầu nhưng tầng này có vẻ thấp hơn .4g. Bên trong phòng khách có năm gã "du hành" lập trình viên khác. Jerry giới thiệu tôi với nhóm này. Tôi gắng nhớ hết tên của mọi người: Johnson, Jasmine, Jason, Jasper và Jennifer. Jerry bảo tôi đứng giữa phòng khách trong khi gã và mọi người ngồi trên salon xung quanh tôi. Sau đó Jerry xoay về phía nhóm lập trình viên và với vẻ kiểu cách, gã tuyên bố, "À, có chuyện đã xảy ra. Tôi tin rằng Alphonse là tay học việc đầu tiên trong năm vào "Micah his Journeyman."

Tôi cảm thấy ngực tôi ngừng đập một nhịp và mắt tôi mở rộng ra. Ðây là điều hết sức đơn giản! tôi không dự tưởng điều này!

"Có ai làm Micahed năm nay chưa nhỉ?" Jerry hỏi. Tiếng xì xầm lan ra khắp phòng nhưng mọi người đều lắc đầu - hiển nhiên là chưa có ai.

Jasmine nhìn tôi chằm chặp hồi lâu. Trong khi cô ta dán mắt vào tôi, nàng bảo Jerry: "OK, Jer, cho bọn tôi nghe câu chuyện ấy đi."

Jerry thở dài, gã cố gắng một cách rõ rệt để lấy lại tư thế và bắt đầu nói.

"Như các bạn biết, ông C yêu cầu tôi làm cái SMCRemote cho nó chạy." Ðám lập trình viên đều gật đầu; hiển nhiên họ biết chuyện này. "Alphonse và tôi bỏ ra cả ngày cho bài tập SocketServer; và nó làm việc rất tốt."

Thêm một cú sốc: SocketServer chỉ là một bài tập?

"Từ lúc làm cho nó chạy được, chúng tôi bắt đầu đặt phần client của SMCRemote lại với nhau. Một trong những test cases là chuyển tải một hồ sơ từ client đến server qua socket." Lại thêm những cái gật đầu trong phòng.

Jerry càng bối rối thấy rõ. Gã trăn trở trên ghế và tránh những ánh mắt, gã nhìn chằm chặp xuống sàn nhà. "Tôi chỉnh định việc chuyển xuất hồ sơ bằng cách gởi ba dòng chữ theo sau bằng một chuỗi từ. Dòng đầu tiên là danh tính của việc chuyển xuất, dòng thứ hai là tên hồ sơ và dòng thứ ba là chiều dài hồ sơ." Lại thêm gật đầu - điều này chẳng làm họ ngạc nhiên tí nào.

"Rõ ràng, đây chỉ là một cách đơn giản cho mấy cái test có thể đạt để chúng tôi có thể refactor thành một dạng tốt hơn." Lại thêm gật đầu; thêm những tiếng xầm xì đồng ý. "Và rồi..." Jerry ngừng lại. "Alphonse nói là hắn nghĩ là hắn có à... ờ.... một ý kiến hay hơn."

Căn phòng trở nên yên tĩnh. Ðôi mắt của Jasmine vẫn dán chặt vào tôi, nhưng cái nhìn của nàng chuyển từ trạng thái đánh giá sang suy đoán. Từng người một, tôi cảm thấy những tia nhìn của các tay "du hành" ngừng lại ở tôi. Làm gì mà lớn chuyện vậy? Tại sao họ đang đòi cái Micah cho tôi nhỉ?

Johnson là người phá tan không khí u ám.

"Không phải bồ muốn cho bọn tôi biết --" gã buộc miệng nói, rồi ghìm lại bằng một cú hít vào nặng nề.

Liếc nhìn, tôi thấy Jerry đang gật đầu. Gật đầu cho chuyện gì nhỉ?

Ðề nghị ngây thơ
Tôi không chịu nổi nữa. Tôi rời khỏi cái nhìn của Jasmine, nhìn thẳng vào mắt của từng tay "du hành" trong phút chốc rồi nói: "Tất cả những gì tôi đề nghị chỉ là việc chuyển tải objects thay vì strings! tôi chẳng thấy việc ấy lại là một Micah!"

Jennifer bước về phía tôi và nói, "Vâng, bồ chỉ làm ngần ấy. Và, không, tôi không giả định là bồ nghĩ ngợi gì nhiều về nó - nhưng với bọn tôi, đây là chuyện lớn."

"Tại sao?" tôi rít lên, thật sự hoảng sợ.

"Bởi," Jerremy giải thích, "đặc điểm quan trọng nhất của một lập trình viên giỏi là khả năng suy nghĩ một cách trừu tượng. Thật ra rất ít người có thể làm như thế. Mày mới vừa chứng tỏ là mày có thể làm điều này."

Tôi đâm nghi ngờ. "Nó chỉ là một object thôi mà," tôi lặp bắp.

"Chính xác," Jennifer nói. Bọn họ đều gật đầu một cách nghiêm chỉnh.

Tôi lắc đầu. "Ôi, thì, nếu đây là điều hay - một Micah gì đó - tại sao Jerry có vẻ cáu kỉnh vậy?"

"Ô, chuyện ấy!" Jasmine cười to. "Jerry xuống đây vào giờ nghỉ lần trước và kể cho bọn mình về vấn đề chiều dài hồ sơ của cậu. Anh ấy chắc rằng cậu sẽ rất có ấn tượng khi thấy chiều dài của hồ sơ sẽ khớp khít vào chuyển xuất hồ sơ. Anh ấy dự phỏng cậu sẽ ngạc nhiên biết chừng nào."

"Ừa," Jasper cười điệu đàng, "và cậu lại đi mà chỉ cho gã chiều dài này trở nên lạc đề."

Tôi nuốt nước bọt, cố chịu đựng. "Tôi đã làm thế sao?"

Jerry đứng dậy và nói, "ngẫm lại chuyện đó đi Alphonse. Nếu mày gởi một chuỗi từ như một object, tại sao mày còn phải gởi chiều dài của hồ sơ riêng ra nữa? Trong sáu tháng tới đây, mấy tay này thế nào cũng sẽ nạo sườn tao về chuyện này" gã nói thêm một cách thiểu não.

"Bọn tớ chắc chắn sẽ làm thế!" Jennifer cười toe toét. "Mỗi khi xét duyệt mã nguồn của anh ấy, bọn tớ sẽ hỏi anh tham số chiều dài hồ sơ ở đâu!" Cô ta cười rúc rích trong khi Jerry nhăn nhó và cứng đờ khuôn mặt.

"Cậu phải biết, Alphonse," Jasmine giải thích, "không những cậu đã tạo nên một bước trừu tượng đáng kể, giải pháp của cậu còn đơn giản hơn giải pháp của Jerry. Hơn nữa, nó là một cách đơn thuần phế bỏ dự tính của Jerry với nhu cầu chiều dài của hồ sơ. Cậu đã Micahed anh ấy!"

Tôi bắt đầu hiểu ra sự thể. Ít ra tôi không bị dính vào một phiền toái nào...

"Tôi nghĩ là," Jasmine nói, "một biến cố như thế này cần đổi cặp (làm việc). Jerry, tôi đổi người học việc với anh. Anh nhận Andy và tôi sẽ làm việc với Alphonse vài ngày."

... hay là tôi?

------


-1- "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" xuất xứ từ nguyên thủy chữ MIkhAyAh (tiếng Hebrew).[Back]

-2- Coriolis: tên của nhà toán học, kỹ sư công chánh người Pháp Gaspard G. Coriolis. Xem thêm tiểu sử và công nghiệp của Coriolis ở: http://www-gap.dcs.st-and.ac.uk/~history/Mathematicians/Coriolis.html [Back]

-3- Journeyman: là một người đã hoàn thành bước học việc hoặc, đôi khi có nghĩa là một cá nhân nào đó rất kinh nghiệm hoặc rất xuất sắc trong lãnh vực nào đó. Trong bài craftsman 13 này, các tay "du hành" trong bài là các tay lập trình viên đã hoàn thành giai đoạn học việc (thuộc dạng đã có.... đai). [Back]
 
Các bài viết mới nhất
Bạn không được phép truy cập vào địa chỉ này!
[Download] - NT Password Recovery Bootdisk
Craftsman 18 - Slow and Steady
Quản lý MySQL Server sử dụng lệnh trên console
Memory-RAM - Một số thuật ngữ và kỹ thuật
Đưa chương trình vào đường dẫn hệ thống
Thay thế BIND với djbdns - phần 1
Phương pháp khôi phục lại password trong hệ thống Win2k/XP/2K3 (Support NTFS)
Cài đặt ActivePython 2.4 trên IIS
Sử Dụng Tiếng Việt Với LaTeX
Cài đặt 1 SMTP server tại nhà với Microsoft IIS
Linux - Vì sao sáng trên bầu trời CNTT
Biên dịch Linux kernel - phần 4
Tự học lập trình Borland Delphi
Thiết kế và Lập trình Web bằng ASP
Cài đặt PHP 4 trên IIS
Giới thiệu về XML-RPC
Sử dụng CSDL MySQL
Một chương trình download manager đơn giản
Giới thiệu - Sơ lược về ngôn ngữ PHP
Các bài viết liên quan
Craftsman 18 - Slow and Steady
Craftsman 17 - Call the Guards
Craftsman 16 - Excess Politesse
Craftsman 15 - Ess Are Pee
Craftsman 14 - Transaction Actions
Craftsman 13 - A Better Solution
Craftsman 12 - Three Ugly Lines
Craftsman 11 - Forget the Main()
Craftsman 10 - Iterations Unbound
Craftsman 9 - Dangerous Threads
Craftsman - 8 : Testing in Synch
Craftsman 7 - Socket Service2
Craftsman 6 - Socket Service
Craftsman 05 - Baby Steps
Craftsman 04 - A Test of Patience
Craftsman 03 - Clarity and Collaboration
Craftsman 02 - Crash Diet
Craftsman 01 - Opening Disaster
Quảng cáo
HOME | TUTORIAL ROOM | FORUM | CONTACT