Lễ tân điện tử
Năm 1983, công ty của chúng tôi nằm ở vị trí giao giữa hệ thống máy tính, hệ thống viễn thông và hệ thống thoại. Giám đốc điều hành của chúng tôi cho rằng đây có thể là một vị trí béo bở để phát triển các sản phẩm mới. Để đạt được mục tiêu này, anh ấy đã giao cho một nhóm ba người (trong đó có tôi) lên ý tưởng, thiết kế và triển khai một sản phẩm mới cho công ty.
Chúng tôi không mất nhiều thời gian để tìm ra Nhân Viên Lễ Tân Điện Tử (Electronic Receptionist – ER).
Ý tưởng này rất đơn giản. Khi bạn gọi cho một công ty, ER sẽ trả lời và hỏi bạn muốn nói chuyện với ai. Bạn sẽ sử dụng âm-chạm (touch-tone) để đánh vần tên của người đó và ER sau đó sẽ kết nối bạn. Người dùng ER có thể quay số và bằng cách sử dụng các lệnh âm-chạm đơn giản, cho nó biết số điện thoại mà người mong muốn có thể liên lạc, ở bất kỳ đâu trên thế giới. Trên thực tế, hệ thống này có thể liệt kê ra vài số thay thế.
Khi bạn gọi cho ER và quay số RMART (mã của tôi), ER sẽ gọi đến số đầu tiên trong danh sách của tôi. Nếu tôi không trả lời và xác minh bản thân, nó sẽ gọi đến số tiếp theo và số tiếp theo nữa. Nếu tôi vẫn không liên lạc được, ER sẽ ghi lại một tin nhắn từ người gọi.
Sau đó, theo định kỳ, ER sẽ cố gắng tìm tôi để gửi tin nhắn đó hay bất kỳ tin nhắn nào khác mà ai đó để lại cho tôi.
Đây là hệ thống thư thoại đầu tiên từ trước đến nay và chúng tôi[1] đã nắm giữ bằng sáng chế cho hệ thống này.
Chúng tôi đã xây dựng tất cả phần cứng cho hệ thống này – bo mạch máy tính, bo mạch bộ nhớ, bo mạch thoại/viễn thông, mọi thứ. Bo mạch chính của máy tính này là Deep Thought, bộ xử lý Intel 80286 mà tôi đã đề cập trước đó.
Mỗi bảng mạch thoại hỗ trợ một đường dây điện thoại. Chúng bao gồm một giao diện điện thoại, một bộ mã hóa/giải mã giọng nói, bộ nhớ và một máy vi tính Intel 80186.
Phần mềm cho bo mạch máy tính chính được viết bằng C. Hệ điều hành là MP/M-86, một hệ điều hành chạy bằng dòng lệnh, hỗ trợ đa tiến trình. MP/M là UNIX của người nghèo.
Phần mềm cho bảng mạch giọng nói được viết bằng trình biên dịch hợp ngữ và không có hệ điều hành. Giao tiếp giữa Deep Thought và bảng mạch giọng nói xảy ra thông qua bộ nhớ được chia sẻ.
Kiến trúc của hệ thống này ngày nay sẽ được gọi là hướng dịch vụ (service oriented). Mỗi đường dây điện thoại được giám sát bởi một listener process (tiến trình lắng nghe) chạy bên dưới MP/M. Khi một cuộc gọi đến, một process xử lý khởi tạo được bắt đầu và cuộc gọi được chuyển đến nó. Khi cuộc gọi được tiếp tục từ trạng thái này sang trạng thái khác, quá trình xử lý thích hợp sẽ được bắt đầu và giành quyền kiểm soát.
Các gói tin được chuyển giữa các dịch vụ này thông qua các file trên đĩa cứng. Dịch vụ hiện đang chạy sẽ xác định dịch vụ tiếp theo sẽ là gì; nó sẽ ghi thông tin trạng thái cần thiết vào một file trên ổ đĩa; sẽ đưa ra dòng lệnh để bắt đầu dịch vụ đó; và sau đó sẽ thoát.
Đây là lần đầu tiên tôi xây dựng một hệ thống như thế này. Quả thực, đây là lần đầu tiên tôi là kiến trúc sư chính của toàn bộ sản phẩm. Mọi thứ liên quan đến phần mềm đều là của tôi – và nó hoạt động hoàn hảo.
Tôi sẽ không nói rằng kiến trúc của hệ thống này là “tinh gọn” theo nghĩa của cuốn sách này; nó không phải là một kiến trúc “plugin”. Tuy nhiên, nó chắc chắn cho thấy dấu hiệu của ranh giới thực sự. Các dịch vụ có thể triển khai độc lập và nằm trong phạm vi trách nhiệm của riêng chúng. Có các quy trình cấp cao và quy trình cấp thấp, và nhiều phần phụ thuộc chạy đúng hướng.
ER băng hà
Thật không may, việc tiếp thị sản phẩm này không diễn ra tốt đẹp. Teradyne là một công ty bán thiết bị kiểm tra. Chúng tôi không hiểu làm thế nào để thâm nhập vào thị trường thiết bị văn phòng.
Sau những nỗ lực lặp đi lặp lại trong suốt hai năm, CEO của chúng tôi đã bỏ cuộc và không may là đã từ bỏ đơn đăng ký bằng sáng chế. Bằng sáng chế đã được dành cho một công ty nộp đơn muộn hơn chúng tôi ba tháng; do đó, chúng tôi đã từ bỏ toàn bộ thị trường thư thoại và chuyển tiếp cuộc gọi điện tử.
Oạch!
Mặt khác, bạn không thể đổ lỗi cho tôi vì những cỗ máy phiền phức hiện đang ảnh hưởng đến sinh hoạt của chúng ta.
Hệ thống phân phối Thợ
ER đã không thành công với tư cách là một sản phẩm, nhưng chúng tôi vẫn có tất cả phần cứng và phần mềm này, chúng tôi có thể sử dụng nó để cải tiến các dòng sản phẩm hiện có của mình. Hơn nữa, thành công trên thị trường của chúng tôi với VRS đã thuyết phục chúng tôi rằng chúng tôi nên cung cấp một hệ thống phản hồi bằng giọng nói để tương tác với các thợ điện thoại mà không phụ thuộc vào hệ thống kiểm tra của chúng tôi.
Do đó, CDS ra đời, Craft Dispatch System (Hệ thống Điều phối Thợ). CDS về cơ bản là ER, nhưng đặc biệt tập trung vào lĩnh vực rất hẹp là quản lý việc triển khai các thợ sửa chữa điện thoại trong lĩnh vực này.
Khi một sự cố được phát hiện trong một đường dây điện thoại, một phiếu xử lý sự cố đã được tạo trong trung tâm dịch vụ. Phiếu sự cố được lưu giữ trong một hệ thống tự động. Khi một thợ sửa chữa tại hiện trường hoàn thành công việc, anh ta sẽ gọi cho trung tâm bảo hành để có nhiệm vụ tiếp theo. Người điều hành trung tâm dịch vụ sẽ đưa ra phiếu sự cố tiếp theo và đọc nó cho thợ sửa chữa.
Chúng tôi sẽ tự động hóa quy trình đó. Mục tiêu của chúng tôi là để thợ sửa chữa tại hiện trường gọi vào CDS và yêu cầu nhiệm vụ tiếp theo. CDS sẽ tham khảo ý kiến của hệ thống kiểm tra sự cố và đọc kết quả. CDS sẽ theo dõi thợ sửa chữa nào được chỉ định cho phiếu sự cố nào và sẽ thông báo cho hệ thống phiếu sự cố về tình trạng của việc sửa chữa.
Có một số tính năng khá thú vị của hệ thống này liên quan đến việc tương tác với hệ thống kiểm tra sự cố, hệ thống quản lý nhà máy và bất kỳ hệ thống kiểm tra tự động nào.
Trải nghiệm với kiến trúc hướng dịch vụ của ER khiến tôi muốn thử mạnh mẽ hơn ý tưởng tương tự. Máy trạng thái (state machine) cho một phiếu sự cố liên quan nhiều hơn máy trạng thái để xử lý một cuộc gọi với ER. Tôi chuẩn bị tạo ra cái mà ngày nay được gọi là kiến trúc micro-service.
Mọi chuyển đổi trạng thái của bất kỳ cuộc gọi nào, dù nhỏ đến mấy, cũng đều khiến hệ thống khởi động một dịch vụ mới. Thật vậy, máy trạng thái đã được ngoại hóa thành một tệp văn bản mà hệ thống đọc được. Mỗi sự kiện đi vào hệ thống từ một đường dây điện thoại sẽ biến thành một quá trình chuyển đổi trong máy trạng thái hữu hạn đó. Tiến trình hiện có sẽ bắt đầu một tiến trình mới do máy trạng thái ra lệnh để xử lý sự kiện đó; sau đó tiến trình hiện tại sẽ thoát hoặc chờ trên một hàng đợi.
Máy trạng thái bên ngoài này cho phép chúng tôi thay đổi luồng của ứng dụng mà không cần thay đổi bất kỳ mã nào (Nguyên Lý Mở-Đóng). Chúng tôi có thể dễ dàng thêm một dịch vụ mới, độc lập với bất kỳ dịch vụ nào khác và đưa nó vào quy trình bằng cách sửa đổi tệp văn bản chứa máy trạng thái. Chúng tôi thậm chí có thể làm điều này trong khi hệ thống đang chạy. Nói cách khác, chúng tôi đã có sự hoán đổi nóng và một BPEL (Business Process Excecution Language – Ngôn Ngữ Thực Thi Quy Trình Nghiệp Vụ) hiệu quả.
Cách tiếp cận ER cũ của việc sử dụng file ổ cứng để giao tiếp giữa các dịch vụ quá chậm đối với việc chuyển đổi các dịch vụ nhanh hơn nhiều này, vì vậy chúng tôi đã phát minh ra một cơ chế bộ nhớ chia sẻ mà chúng tôi gọi là 3DBB[2]. Cơ chế này cho phép dữ liệu được truy xuất bởi tên gọi: các tên gọi mà chúng tôi sử dụng được gắn với mỗi thực thể máy trạng thái.
Cơ chế 3DBB này rất tốt để lưu trữ các chuỗi ký tự và hằng số, nhưng không thể được sử dụng để lưu trữ các cấu trúc dữ liệu phức tạp. Lý do cho việc này là vấn đề kỹ thuật nhưng khá dễ hiểu. Mỗi tiến trình trong MP/M nằm trong phân vùng bộ nhớ của riêng nó. Con trỏ tới dữ liệu trong một phân vùng bộ nhớ không có ý nghĩa trong phân vùng bộ nhớ khác. Do đó, dữ liệu trong 3DBB không thể chứa con trỏ. Các chuỗi ký tự vẫn ổn, nhưng cây, danh sách được liên kết hoặc bất kỳ cấu trúc dữ liệu nào có con trỏ sẽ không hoạt động được.
Các ticket sự cố trong hệ thống ticket sự cố này đến từ nhiều nguồn khác nhau. Một số được tự động hóa và một số là thủ công. Các dữ liệu thủ công được tạo ra bởi những người điều hành đang nói chuyện với khách hàng về những rắc rối của họ. Khi khách hàng mô tả các vấn đề của họ, những người vận hành sẽ nhập các khiếu nại và hiện tượng họ gặp phải vào một dòng văn bản có cấu trúc. Nó trông giống như thế này:
/ pno 8475551212 / noise / drop-call
Bạn hiểu rồi chứ. Ký tự /
bắt đầu một chủ đề mới. Theo sau dấu gạch chéo là một mã, và theo sau mã đó là các tham số. Có hàng nghìn mã và một ticket sự cố riêng lẻ có thể có hàng chục mã trong phần mô tả. Tệ hơn, vì chúng được nhập theo cách thủ công, nên chúng thường bị sai chính tả hoặc định dạng không đúng. Chúng được dùng để con người biên dịch, không phải cho máy móc xử lý.
Vấn đề của chúng tôi là giải mã các chuỗi bán tự do này, diễn giải và sửa bất kỳ lỗi nào, sau đó chuyển chúng thành đầu ra giọng nói để chúng tôi có thể đọc chúng cho thợ sửa chữa, trên cột, nghe bằng thiết bị cầm tay. Điều này đòi hỏi một kỹ thuật phân tích cú pháp và biểu diễn dữ liệu rất linh hoạt. Việc biểu diễn dữ liệu đó phải được chuyển qua 3DBB, thứ mà chỉ có thể xử lý các chuỗi ký tự.
Và vì vậy, trên một chuyến bay, bay giữa các chuyến thăm khách hàng, tôi đã phát minh ra một lược đồ mà tôi gọi là FLD: Field Labled Data (Dữ liệu được gắn nhãn trường). Ngày nay chúng ta gọi đây là XML hoặc JSON. Định dạng thì khác nhau, nhưng ý tưởng thì giống nhau. FLD là cây nhị phân liên kết tên với dữ liệu trong một hệ thống phân cấp đệ quy. Các FLD có thể được truy vấn bằng một API đơn giản và có thể được dịch sang một định dạng chuỗi ký tự thuận tiện, lý tưởng cho 3DBB.
Vì vậy, các micro-service giao tiếp thông qua bộ nhớ chia sẻ tương tự như các socket sử dụng một XML – vào năm 1985.
Không có gì mới dưới ánh Mặt trời.
Clear Communications
Năm 1988, một nhóm nhân viên của Teradyne rời công ty để thành lập một công ty khởi nghiệp tên là Clear Communications. Tôi tham gia cùng họ một vài tháng sau đó. Nhiệm vụ của chúng tôi là xây dựng phần mềm cho một hệ thống giám sát chất lượng thông tin liên lạc của các tuyến T1 – các tuyến kỹ thuật số truyền thông tin liên lạc đường dài trên khắp đất nước. Viễn cảnh là một màn hình khổng lồ với bản đồ của Hoa Kỳ được đan chéo bởi các đường T1 nhấp nháy màu đỏ nếu chúng đang bị xuống cấp.
Hãy nhớ rằng, giao diện người dùng đồ họa vẫn còn là điều mới mẻ vào năm 1988. Apple Macintosh khi đó mới được 5 năm tuổi. Windows thì chỉ là một trò đùa hồi đó. Nhưng Sun Microsystems đang xây dựng Sparcstations có GUI X-Windows đáng tin cậy. Vì vậy, chúng tôi đã đi theo Sun – và do đó với ngôn ngữ C và UNIX.
Đây là một công ty khởi nghiệp. Chúng tôi đã làm việc tới 70 đến 80 giờ mỗi tuần. Chúng tôi đã có tầm nhìn. Chúng tôi đã có động lực. Chúng tôi đã có ý chí. Chúng tôi đã có năng lượng. Chúng tôi đã có nghiệp vụ. Chúng tôi đã có vốn chủ sở hữu. Chúng tôi đã có ước mơ trở thành triệu phú. Chúng tôi đã như một đống sh!t.
Code C tuôn ra từ mọi lỗ thông trên cơ thể của chúng tôi. Chúng tôi ném phịch nó ở đây, và quẳng nó ở kia. Chúng tôi đã xây dựng những lâu đài khổng lồ trên không. Chúng tôi đã có các tiến trình, và các hàng đợi gói tin, và các kiến trúc vĩ đại, tột bực. Chúng tôi đã viết toàn bộ stack truyền thông tin ISO bảy lớp từ đầu – cho tới lớp liên kết dữ liệu (data link layer).
Chúng tôi đã viết GUI code. GOOEY CODE! OMG! Chúng tôi đã viết GOOOOOEY code.
Riêng tôi đã viết một hàm C tên là gi()
dài 3000 dòng; tên của nó có nghĩa là Graphic Interpreter (trình dịch đồ họa). Nó là một kiệt tác của gooey. Đó không phải là code gooey duy nhất tôi viết tại Clear Communications, nhưng đó là thứ tai tiếng nhất của tôi.
Kiến trúc ư? Bạn đùa à? Đó là một startup. Chúng tôi không có thời gian cho kiến trúc. Chỉ có code thôi, khốn thật! Code vì chính cuộc sống của chúng tôi!
Vì vậy chúng tôi code. Và chúng tôi code. Và chúng tôi code. Nhưng, sau ba năm, cái chúng tôi thất bại đó là việc bán hàng. Ồ, chúng tôi có được một lượt cài đặt hoặc là hai gì đó. Nhưng thị trường không hứng thú lắm với tầm nhìn vĩ đại của chúng tôi, và những nhà tài chính đầu tư mạo hiểm cho chúng tôi đã chán ngấy.
Tôi ghét cuộc sống của bản thân vào thời điểm đó. Tôi đã nhìn thấy tất cả nỗ lực và giấc mơ của mình bị vỡ vụn. Tôi có những xung đột trong công việc, xung đột tại gia đình bởi vì công việc, và xung đột với chính bản thân.
Và sau đó tôi nhận được một cuộc điện thoại đã thay đổi mọi thứ.
Cài đặt
Hai năm trước khi có cuộc gọi đó, hai điều quan trọng đã xảy ra.
Đầu tiên, tôi đã thiết lập một kết nối uucp
tới một công ty gần đó có kết nối uucp
với một cơ sở khác được kết nối tới Internet. Tất nhiên, những kết nối này là quay số. Máy trạm chính của chúng tôi (máy trên bàn làm việc của tôi) đã sử dụng modem 1200-bps để gọi máy chủ uucp
của chúng tôi hai lần mỗi ngày. Điều này đã cho phép chúng tôi có email và Netnews (một mạng xã hội ban đầu, nơi mọi người thảo luận về các vấn đề thú vị).
Thứ hai, Sun đã phát hành một trình biên dịch C++. Tôi đã quan tâm đến C ++ và OO từ năm 1983, nhưng rất khó để tạo ra các trình biên dịch. Vì vậy, khi cơ hội đến, tôi đã thay đổi ngôn ngữ ngay lập tức. Tôi bỏ lại các hàm C 3000 dòng phía sau và bắt đầu viết mã C ++ tại Clear. Và tôi đã học được …
Tôi đã đọc nhiều cuốn sách. Dĩ nhiên, tôi đã đọc cuốn The C++ Programming Language và The Annotated C++ Reference Manual (The ARM) của Bjarne Stroustrup. Tôi đã đọc cuốn sách đáng yêu về thiết kế hướng trách nhiệm của Rebecca Wirfs Brock: Desining Object Oriented Software. Tôi đã đọc OOA và OOD và OOP của Peter Coad. Tôi đã đọc Smalltalk-80 của Adele Goldberg. Tôi đã đọc Advanced C++ Programming Styles and Idioms của James O. Coplien. Nhưng có lẽ quan trọng nhất trong tất cả, tôi đã đọc cuốn Object Oriented Design with Applications của Grady Booch.
Đúng là một cái tên! Grady Booch. Làm sao ai đó có thể quên được một cái tên như thế. Hơn thế nữa, ông ấy còn là Trưởng Khoa Nghiên Cứu (Chief Scientist) tại một công ty có tên là Rational! Làm cách nào tôi muốn trở thành một Trưởng Khoa Nghiên Cứu! Và vì vậy tôi đã đọc cuốn sách của ông ấy. Và tôi đã học, và tôi đã học, và tôi đã học được …
Khi tôi học, tôi cũng bắt đầu tranh luận trên Netnews, như cái cách mà mọi người hiện nay hay tranh luận trên Facebook. Các cuộc tranh luận của tôi là về C ++ và OO. Trong hai năm, tôi đã giải tỏa những thất vọng đang có tại nơi làm việc bằng cách tranh luận với hàng trăm người trên Usenet về các tính năng ngôn ngữ tốt nhất và các nguyên tắc thiết kế tốt nhất. Sau một thời gian, tôi thậm chí đã bắt đầu hiểu được một số điều nhất định.
Từ một trong những cuộc tranh luận đó, nền tảng của các nguyên tắc SOLID đã được đặt ra.
Và tất cả những tranh luận đó, và thậm chí có lẽ là một phần nào đó, đã khiến tôi chú ý …
Uncle Bob
Một trong những kỹ sư tại Clear là một người trẻ tuổi tên là Billy Vogel. Billy đặt biệt danh cho mọi người. Anh ấy gọi tôi là Uncle Bob (chú Bob). Tôi nghi ngờ, mặc dù tên tôi là Bob, nhưng anh ta đang ám chỉ trực tiếp đến J. R. “Bob” Dobbs (xem https://en.wikipedia.org/wiki/File:Bobdobbs.png).
Lúc đầu, tôi đã phải chịu đựng nó. Nhưng nhiều tháng trôi qua, những câu nói không ngớt của anh ta về “Chú Bob, … Chú Bob,” trong bối cảnh áp lực và thất vọng của công ty khởi nghiệp, nên tôi đã bắt đầu không để tâm tới nó nữa.
Và rồi, một ngày, chuông điện thoại reo.
Cuộc điện thoại
Đó là một nhà tuyển dụng. Anh ấy đã biết tên tôi như một người biết C ++ và thiết kế hướng đối tượng. Tôi không chắc làm thế nào mà anh ấy biết, nhưng tôi nghi là nó có liên quan đến sự hiện diện trên Netnews của tôi.
Anh ấy nói rằng anh ấy đã có một cơ hội ở Thung lũng Silicon, tại một công ty tên là Rational. Họ đang tìm kiếm sự trợ giúp để xây dựng một công cụ CASE[3].
Máu từ mặt tôi chảy ra. Tôi đã biết đó là cái gì. Tôi không biết làm thế nào tôi biết, nhưng tôi biết. Đây là công ty của Grady Booch. Tôi đã thấy trước cơ hội được hợp lực với Grady Booch!
Rose
Tôi gia nhập Rational, với tư cách là một lập trình viên theo hợp đồng, vào năm 1990. Tôi làm việc với sản phẩm ROSE. Đây là một công cụ cho phép các lập trình viên vẽ sơ đồ Booch – những sơ đồ mà Grady đã viết trong cuốn sách Object-Oriented Analysis and Design with Applications (Phân Tích Và Thiết Kế Hướng Đối Tượng Với Các Ứng Dụng) (Hình A.9 là một ví dụ).
Ký hiệu Booch rất mạnh mẽ. Nó định sẵn các ký hiệu như UML.
ROSE có một kiến trúc – một kiến trúc thực sự. Nó được xây dựng trong các lớp thực và sự phụ thuộc giữa các lớp được kiểm soát đúng cách. Kiến trúc làm cho nó có thể phát hành được, có thể phát triển được và có thể triển khai được độc lập.
Ồ, nhưng nó không hoàn hảo. Có rất nhiều điều mà chúng tôi vẫn chưa hiểu về các nguyên tắc kiến trúc. Ví dụ, chúng tôi đã không tạo một cấu trúc plugin thực sự.
Chúng tôi cũng rơi vào một trong những xu hướng đáng tiếc nhất trong thời đó – chúng tôi sử dụng cái gọi là cơ sở dữ liệu hướng đối tượng.
Nhưng nhìn chung, trải nghiệm là một trải nghiệm tuyệt vời. Tôi đã dành một năm rưỡi đáng yêu để làm việc với nhóm Rational trên ROSE. Đây là một trong những trải nghiệm kích thích trí tuệ nhất trong cuộc đời làm nghề của tôi.
Cuộc tranh luận tiếp tục
Dĩ nhiên, tôi đã không dừng tranh luận trên Netnews. Trên thực tế, tôi đã tăng đáng kể sự hiện diện mạng của mình. Tôi bắt đầu viết bài cho C++ Report. Và, với sự trợ giúp của Grady, tôi bắt đầu làm cuốn sách đầu tiên của mình: Designing Object-Oriented C++ Applications Using the Booch Method (Thiết Kế Ứng Dụng C ++ Hướng Đối Tượng Bằng Phương Pháp Booch).
Một điều khiến tôi bận tâm. Điều này thật buồn cười, nhưng đó là sự thật. Không ai gọi tôi là “Uncle Bob” cả. Tôi cảm thấy rằng tôi nhớ cách gọi đó. Vì vậy, tôi đã mắc sai lầm khi đặt “Uncle Bob” trong email và chữ ký của Netnews. Và cái tên đó đã dính với tôi. Cuối cùng tôi nhận ra rằng đó là một thương hiệu khá tốt.
…Bởi bất kỳ cái tên nào khác
ROSE là một ứng dụng C++ khổng lồ. Nó bao gồm các lớp, với một quy tắc phụ thuộc được thực thi nghiêm ngặt. Quy tắc đó không phải là quy tắc mà tôi đã mô tả trong cuốn sách này. Chúng tôi không hướng sự phụ thuộc của mình vào các chính sách cấp cao. Thay vào đó, chúng tôi đã hướng sự phụ thuộc của mình theo hướng kiểm soát luồng truyền thống hơn. GUI hướng vào biểu diễn, hướng vào các quy tắc thao tác, hướng vào cơ sở dữ liệu. Cuối cùng, nó đã thất bại trong việc hướng các phụ thuộc của chúng tôi vào chính sách mà điều này góp phần dẫn tới sự ra đi cuối cùng của sản phẩm.
Kiến trúc của ROSE tương tự như kiến trúc của một trình biên dịch tốt. Ký hiệu đồ họa đã được “phân tích cú pháp” thành một biểu diễn nội bộ; biểu diễn đó sau đó được thao tác bởi các quy tắc và được lưu trữ trong cơ sở dữ liệu hướng đối tượng.
Cơ sở dữ liệu hướng đối tượng là một ý tưởng tương đối mới, và thế giới OO đều rất ngạc nhiên với những tác động của nó. Mọi lập trình viên hướng đối tượng đều muốn có một cơ sở dữ liệu hướng đối tượng trong hệ thống của mình. Ý tưởng này tương đối đơn giản và mang tính lý tưởng sâu sắc. Cơ sở dữ liệu lưu trữ các đối tượng, không phải bảng. Cơ sở dữ liệu được cho là trông giống như RAM. Khi bạn truy cập một đối tượng, nó chỉ xuất hiện trong bộ nhớ. Nếu đối tượng đó trỏ đến một đối tượng khác, đối tượng kia sẽ xuất hiện trong bộ nhớ ngay khi bạn truy cập vào nó. Nó giống như một phép thuật.
Cơ sở dữ liệu đó có lẽ là sai lầm thực tế lớn nhất của chúng tôi. Chúng tôi muốn điều kỳ diệu, nhưng những gì chúng tôi nhận được là một framework bên thứ ba cồng kềnh, chậm chạp, dễ xâm nhập, đắt đỏ khiến cho cuộc sống của chúng tôi trở thành địa ngục bằng cách cản trở tiến độ của chúng tôi ở mọi cấp bậc.
Cơ sở dữ liệu đó không phải là sai lầm duy nhất mà chúng tôi mắc phải. Trên thực tế, sai lầm lớn nhất là kiến trúc quá mức (over-architecture). Có nhiều lớp hơn những gì tôi đã mô tả ở đây, và mỗi lớp có một mác truyền thông riêng của nó. Điều này làm giảm đáng kể năng suất của đội phát triển.
Thật vậy, sau nhiều năm làm việc, đấu tranh cực khổ và hai lần phát hành tẻ nhạt, toàn bộ công cụ đã bị loại bỏ và thay thế bằng một ứng dụng nhỏ dễ thương được viết bởi một nhóm nhỏ ở Wisconsin.
Và vì vậy tôi học được rằng những kiến trúc vĩ đại đôi khi dẫn đến những thất bại lớn. Kiến trúc phải đủ linh hoạt để thích ứng với quy mô của vấn đề. Khi tất cả những gì bạn thực sự cần là một công cụ desktop nhỏ xinh, thì kiến trúc dành cho enterprise là một công thức dẫn đến thất bại.
Bài kiểm tra đăng ký kiến trúc sư
Vào đầu những năm 1990, tôi đã trở thành một nhà tư vấn thực thụ. Tôi đã đi khắp thế giới để dạy mọi người về thứ OO mới mẻ này. Công việc tư vấn của tôi tập trung mạnh vào thiết kế và kiến trúc của các hệ thống hướng đối tượng.
Một trong những khách hàng tư vấn đầu tiên của tôi là Dịch vụ Khảo thí Giáo dục (Educational Testing Service – ETS). Theo hợp đồng với Hội Đồng Đăng Ký Kiến Trúc Sư Quốc gia (National Council of Architects Registry Board – NCARB) để tiến hành các kỳ thi đăng ký cho các ứng viên kiến trúc sư mới.
Bất kỳ ai muốn trở thành một kiến trúc sư bảo đảm (kiểu kiến trúc sư thiết kế các tòa nhà) ở Hoa Kỳ hoặc Canada đều phải vượt qua kỳ thi đăng ký này. Kỳ thi này liên quan đến việc ứng viên giải quyết một số vấn đề kiến trúc liên quan đến thiết kế tòa nhà. Ứng viên có thể được đưa ra một tập hợp các yêu cầu đối với thư viện công cộng, nhà hàng hoặc nhà thờ, sau đó được yêu cầu vẽ các sơ đồ kiến trúc thích hợp.
Các kết quả sẽ được thu thập và lưu lại cho đến khi một nhóm kiến trúc sư cao cấp có thể được tập hợp lại với nhau với tư cách là bồi thẩm viên, để chấm điểm các bài nộp. Những cuộc họp này là những sự kiện lớn, tốn kém và là nguồn gốc của nhiều sự không rõ ràng và chậm trễ.
NCARB muốn tự động hóa quy trình bằng cách để các ứng viên làm bài thi bằng máy tính, sau đó nhờ máy tính khác đánh giá và cho điểm. NCARB yêu cầu ETS phát triển phần mềm đó và ETS đã thuê tôi tập hợp một nhóm các nhà phát triển để sản xuất sản phẩm.
ETS đã chia nhỏ vấn đề thành 18 mô hình thử nghiệm riêng lẻ. Mỗi ứng dụng sẽ yêu cầu một ứng dụng GUI giống như CAD mà ứng viên sẽ sử dụng để thể hiện giải pháp của mình. Một ứng dụng chấm điểm riêng biệt sẽ tiếp nhận các giải pháp và tạo ra điểm số.
Đối tác của tôi, Jim Newkirk, và tôi đã nhận ra rằng 36 ứng dụng này có rất nhiều điểm giống nhau. 18 ứng dụng GUI đều sử dụng các hành vi và cơ chế tương tự. 18 ứng dụng cho điểm đều sử dụng các kỹ thuật toán học giống nhau. Với những yếu tố được chia sẻ này, Jim và tôi đã quyết tâm phát triển một framework có thể tái sử dụng cho tất cả 36 ứng dụng. Thật vậy, chúng tôi đã bán ý tưởng này cho ETS bằng cách nói rằng chúng tôi sẽ dành nhiều thời gian làm việc trên ứng dụng đầu tiên, nhưng sau đó phần còn lại sẽ chỉ xuất hiện vài tuần một lần.
Tại thời điểm này, bạn có lẽ đã tái mặt hoặc đập đầu vào cuốn sách này. Những người trong số các bạn đủ lớn để có thể nhớ lời hứa “tái sử dụng” của OO. Khi đó, tất cả chúng tôi đều bị thuyết phục rằng nếu bạn chỉ cần viết mã C++ hướng đối tượng sạch đẹp thì bạn sẽ tự nhiên tạo ra rất nhiều mã có thể tái sử dụng.
Vì vậy, chúng tôi chuẩn bị viết ứng dụng đầu tiên – ứng dụng phức tạp nhất trong gói đó. Nó được gọi là Vignette Grande.
Hai chúng tôi đã làm việc toàn thời gian trên Vignette Grande với mục tiêu tạo ra một framework có thể tái sử dụng. Chúng tôi đã mất một năm. Vào cuối năm đó, chúng tôi có 45.000 dòng mã framework và 6.000 dòng mã ứng dụng. Chúng tôi đã giao sản phẩm này cho ETS và họ đã ký hợp đồng với chúng tôi để viết tiếp 17 ứng dụng còn lại một cách vội vã.
Vì vậy, Jim và tôi đã tuyển dụng một nhóm gồm ba lập trình viên khác và chúng tôi bắt đầu làm việc trên một vài ứng dụng tiếp theo.
Nhưng có gì đó không ổn. Chúng tôi nhận thấy rằng framework có thể tái sử dụng mà chúng tôi đã tạo ra không thể thực sự tái sử dụng được. Nó không phù hợp với các ứng dụng mới đang được viết. Có những trở ngại nhỏ khiến cho nó không thể hoạt động.
Điều này gây nản lòng vô cùng, nhưng chúng tôi tin rằng chúng tôi biết phải làm gì với nó. Chúng tôi đã đến ETS và nói với họ rằng sẽ có sự chậm trễ – rằng framework 45.000 dòng cần được viết lại, hoặc ít nhất là điều chỉnh lại. Chúng tôi đã nói với họ rằng sẽ mất một thời gian nữa để hoàn thành việc đó.
Tôi không cần phải nói bạn cũng biết rằng ETS không hề vui với tin tức này.
Vì vậy, chúng tôi đã bắt đầu lại. Chúng tôi đặt framework cũ sang một bên và bắt đầu viết bốn ứng dụng mới cùng một lúc. Chúng tôi sẽ mượn các ý tưởng và mã từ framework cũ nhưng làm lại chúng để chúng phù hợp với cả bốn ứng dụng mà không cần sửa đổi. Nỗ lực này mất thêm một năm. Nó tạo ra một framework 45.000 dòng khác, cộng với bốn ứng dụng theo thứ tự từ 3000 đến 6000 dòng mỗi ứng dụng.
Không cần phải nói, mối quan hệ giữa các ứng dụng GUI và framework tuân theo Quy Tắc Phụ Thuộc. Các ứng dụng là plugin cho framework. Tất cả chính sách GUI cấp cao đều nằm trong framework. Mã ứng dụng chỉ là lớp kết dính.
Mối quan hệ giữa các ứng dụng tính điểm và framework phức tạp hơn một chút. Chính sách chấm điểm ở cấp độ cao nằm trong ứng dụng. Framework chấm điểm được gắn vào ứng dụng chấm điểm.
Tất nhiên, cả hai ứng dụng này đều là ứng dụng C++ được liên kết tĩnh, vì vậy khái niệm plugin không xuất hiện trong tâm trí chúng tôi. Tuy nhiên, cách mà các phụ thuộc chạy đều nhất quán với Quy Tắc Phụ Thuộc.
Sau khi gửi bốn ứng dụng đó, chúng tôi bắt đầu với bốn ứng dụng tiếp theo. Và lần này họ bắt đầu phản hồi sau vài tuần một lần, giống như những gì chúng tôi đã dự đoán. Sự chậm trễ đã khiến chúng tôi mất gần một năm trong lịch trình của mình, vì vậy chúng tôi đã thuê một lập trình viên khác để đẩy nhanh quá trình.
Chúng tôi đã đáp ứng được thời hạn và các cam kết của chúng tôi. Khách hàng của chúng tôi đã rất vui. Chúng tôi đã rất hạnh phúc. Cuộc sống thật tuyệt vời.
Nhưng chúng tôi đã học được một bài học hay: Bạn không thể tạo một framework có thể tái sử dụng cho đến khi bạn lần đầu tiên tạo ra một framework có thể tái sử dụng. Các framework có thể tái sử dụng đó sẽ cần bạn phải xây dựng chúng cùng với một vài ứng dụng tái sử dụng nó.
Kết luận
Như tôi đã nói ở phần đầu, phần phụ lục này mang hơi hướng tự truyện. Tôi đã đạt được đỉnh cao của các dự án mà tôi cảm thấy mình có tác động đến kiến trúc. Và, tất nhiên, tôi đã đề cập đến một vài tình tiết không liên quan chính xác đến nội dung kỹ thuật của cuốn sách này, nhưng dù sao nó cũng rất quan trọng.
Tất nhiên, đây chỉ là một phần lịch sử. Có rất nhiều dự án khác mà tôi đã thực hiện trong nhiều thập kỷ. Tôi cũng cố ý dừng dòng lịch sử này tại thời điểm đầu những năm 1990 – bởi vì tôi có một cuốn sách khác để viết về các sự kiện của cuối những năm 1990.
Tôi hy vọng rằng bạn thích chuyến đi nhỏ này trong ký ức của tôi; và rằng bạn có thể học một số điều trong suốt hành trình này.
[1] Công ty của chúng tôi đã giữ bằng sáng chế. Hợp đồng lao động của chúng tôi nói rõ rằng bất cứ thứ gì chúng tôi phát minh ra đều thuộc về công ty của chúng tôi. Sếp của tôi nói với tôi rằng: “Anh đã bán nó cho chúng tôi với giá một đô la và chúng tôi không trả cho anh số tiền đó.”
[2] Bảng đen ba chiều. Nếu bạn sinh vào những năm 1950, bạn có thể nhận được thông tin tham khảo này: Drizzle, Drazzle, Druzzle, Drone.
[3] Computer Aided Software Engineering – Kỹ thuật Phần mềm Hỗ trợ Máy tính.