Những Lớp Trừu Tượng Của Tôi Đã Che Đi Những Thứ Tôi Cần Thấy
Tôi yêu một lớp trừu tượng gọn gàng. Có một khoái cảm thẩm mỹ thật sự khi lấy một thứ gì đó lộn xộn và phức tạp rồi gói nó vào trong một giao diện ngăn nắp che giấu mớ bòng bong ấy, để bạn có thể tư duy ở một tầng cao hơn và quên đi những chi tiết bên dưới. Vậy nên tôi liên tục với tay tới các lớp trừu tượng — sớm, hăm hở, và quá thường xuyên. Và một số lần đáng ngạc nhiên trong đó, lớp trừu tượng mà tôi với tới chẳng hề quản lý độ phức tạp chút nào. Nó che đi đúng những thứ mà tôi cần thấy nhất, và bắt tôi trả thêm một tầng rối rắm mới cho cái đặc quyền ấy.
Đây là một bài học khó nuốt chính bởi vì trừu tượng thực sự tốt và thực sự mạnh mẽ. Sai lầm không nằm ở việc sử dụng nó. Sai lầm nằm ở việc sử dụng nó sai cách, và nhầm lẫn tình yêu của tôi dành cho bề mặt gọn gàng với phán đoán kỹ thuật đúng đắn.
Một lớp trừu tượng tốt được kỳ vọng làm gì
Đáng để nói rõ trừu tượng dùng để làm gì, bởi vì toàn bộ thất bại chỉ là một sự bóp méo của một điều gì đó có thật. Một lớp trừu tượng tốt che đi những chi tiết bạn không cần phải nghĩ tới ngay lúc này, để bạn có thể suy luận ở một tầng cao hơn mà không phải ôm cả mớ hỗn độn trong đầu cùng một lúc. Đó là một trong những công cụ mạnh mẽ nhất trong toàn bộ ngành kỹ thuật — có thể nói là cái công cụ, thứ cho phép bạn xây dựng những hệ thống quá phức tạp để có thể thấu hiểu hết cùng một lúc.
Khi một lớp trừu tượng vận hành tốt, nó gần như vô hình. Bạn dùng nó mà không nghĩ về thứ nằm bên dưới, giống như bạn lái xe mà không nghĩ về sự đốt cháy nhiên liệu. Nó giải phóng sự chú ý hữu hạn của bạn cho tầng mà bạn thực sự quan tâm. Đó là giấc mơ, và là một giấc mơ đẹp, và nó có thật. Đó cũng chính là điều khiến cho chế độ thất bại trở nên quyến rũ đến vậy: mọi lớp trừu tượng đều hứa hẹn điều này, và chỉ một số ít thực sự làm được.
Lớp trừu tượng sai làm gì thay vào đó
Một lớp trừu tượng tồi làm điều ngược lại với lớp tốt, và nó làm điều đó trong khi trông gần như y hệt từ bên ngoài. Thay vì che đi chi tiết bạn không cần, nó che đi chi tiết bạn cần. Nó vạch ranh giới của mình ở sai chỗ, để rồi chính những thứ bạn cần suy luận lại nằm ở phía bên kia một bức tường mà tự tay bạn dựng lên, bỗng dưng trở nên ngoài tầm với.
Và nó phạm thêm một tội lỗi thứ hai chồng lên tội thứ nhất. Nó không thực sự loại bỏ độ phức tạp nền tảng — độ phức tạp đó vẫn còn nguyên ở đó, không hề bị động đến, vẫn đang làm việc của nó bên dưới bề mặt. Lớp trừu tượng chỉ đơn thuần thêm một tầng mới lên trên nó. Vậy nên giờ đây, thay vì một thứ phức tạp phải hiểu, bạn có hai: cái hiện thực lộn xộn bên dưới, và lớp trừu tượng không-hoàn-toàn-đúng mà bạn phủ lên nó, cộng thêm mối quan hệ luôn-gây-rối giữa hai thứ đó. Bạn xuất phát với mục tiêu giảm bớt thứ phải nghĩ tới, mà rốt cuộc lại làm tăng nó lên.
Trừu tượng vội vàng: cam kết trước khi bạn hiểu
Hình thức phổ biến nhất của sai lầm này ở tôi là trừu tượng quá sớm. Tôi xây dựng cấu trúc gọn gàng, tổng quát, tao nhã trước khi tôi thực sự hiểu vấn đề đủ rõ để biết được cấu trúc đúng đắn rốt cuộc là gì. Nó cảm giác như một thiết kế tốt, có tầm nhìn xa. Nhưng nó thường là điều ngược lại.
Một lớp trừu tượng, về cơ bản, là một cam kết với một hình dạng cụ thể — một quyết định về việc đặt ranh giới ở đâu, cái gì được giấu và cái gì được phơi bày, các mảnh ghép liên hệ với nhau ra sao. Và việc cam kết với một hình dạng trước khi bạn hiểu được thứ mình đang định hình là một cách chắc chắn để khóa chặt vào hình dạng sai. Tệ hơn nữa, một khi nó đã được đặt vào chỗ, bạn bắt đầu xây dựng lên trên nó, và mỗi thứ mới mà bạn xây lại làm sâu thêm khoản đầu tư của bạn vào một cấu trúc được đoán mò hơn là được học ra. Lớp trừu tượng vội vàng không chỉ có nguy cơ bị sai; nó còn chủ động cố thủ cho cái sai của chính nó.
Lớp trừu tượng rò rỉ bắt bạn gỡ lỗi hai thứ
Có một sự hành hạ đặc biệt dành riêng cho những lớp trừu tượng che giấu không trọn vẹn — những lớp phần lớn vận hành tốt, cho đến khi chúng không còn vậy. Khi một thứ gì đó trục trặc ở dưới cái hiện thực mà lớp trừu tượng đáng lẽ phải che giấu, chỗ rò rỉ buộc bạn phải hiểu cả hai tầng cùng một lúc: cái bề mặt gọn gàng mà bạn được hứa là có thể tư duy bên trong nó, và mớ lộn xộn bên dưới mà nó đã không che giấu hết được.
Điều này mệt mỏi một cách độc nhất. Toàn bộ mục đích của lớp trừu tượng là để cho phép bạn nghĩ về một thứ. Giờ đây một sự cố đã lôi bạn vào việc nghĩ về hai thứ, cộng thêm sự ánh xạ giữa chúng, cộng thêm câu hỏi rằng con lỗi thực ra nằm ở tầng nào. Bạn đang gỡ lỗi cho lớp trừu tượng và cho cái thứ mà nó trừu tượng hóa cùng một lúc, và lớp trừu tượng, vốn đáng lẽ phải đang giúp đỡ, giờ lại là một chướng ngại vật phụ thêm chen giữa bạn và vấn đề. Một lớp trừu tượng rò rỉ có thể tệ hơn cả việc không có lớp trừu tượng nào, bởi vì ít nhất với không có lớp trừu tượng nào thì bạn chỉ có một tầng làm bạn rối trí.
Cái giá của một tầng mà bạn không cần
Điều mà tôi đã không tính đến cho đúng là mỗi tầng trừu tượng cũng là một tầng gián tiếp — thêm một thứ nữa đứng chen giữa bạn và những gì thực sự đang diễn ra. Khi mọi thứ đang vận hành tốt, khoảng cách đó là lợi ích; chính nó cho phép bạn không phải nghĩ về tầng thấp hơn. Nhưng vào khoảnh khắc bạn cần hiểu hay gỡ lỗi, cũng chính khoảng cách đó trở thành cái giá thuần túy. Mỗi tầng là thêm một chỗ mà bạn phải nhìn vào, thêm một phép dịch mà bạn phải thực hiện trong đầu, thêm một vị trí ứng viên cho nơi mà vấn đề có thể đang ẩn náu.
Vậy nên một lớp trừu tượng không thực sự tự trả giá được cho chính nó thì không phải là trung tính. Nó là một khoản thuế thường trực, bị thu mỗi lần bạn phải suy luận về hệ thống, đánh lên để đổi lấy một sự tiện lợi mà hóa ra bạn không cần. Tôi đã hăm hở thêm vào những khoản thuế này, bị mê hoặc bởi những bề mặt gọn gàng, mà không nhận ra rằng tôi đang trả cho hầu hết chúng và chỉ hưởng lợi từ một số ít.
Hãy giành lấy các lớp trừu tượng từ cái cụ thể
Kỷ luật cuối cùng đã giúp được tôi gần như là sự đảo ngược bản năng của mình. Đừng áp đặt các lớp trừu tượng ngay từ đầu, từ một sự phỏng đoán về thứ mà rốt cuộc bạn sẽ cần. Hãy giành lấy chúng, từ kinh nghiệm cụ thể và lặp đi lặp lại. Hãy xây dựng cái thứ cụ thể, xấu xí, riêng biệt ấy vài lần trước đã. Hãy cảm nhận xem những đường nối thật sự nằm ở đâu — nơi mà những ranh giới tự nhiên thực sự rơi vào, những chi tiết nào thực sự túm tụm lại với nhau và những chi tiết nào thì không. Và chỉ khi đó, một khi hiện thực đã cho bạn thấy các khớp nối của nó, hãy trừu tượng hóa dọc theo những đường mà nó đã thực sự vạch ra.
Lớp trừu tượng tốt, tôi dần dần hiểu ra, được khám phá ra từ cái cụ thể, chứ không phải được áp đặt lên nó. Nó là một sự nén lại của những thứ mà bạn đã hiểu sâu sắc rồi, chứ không phải một lối tắt vòng qua việc hiểu chúng. Những lớp mà tôi xây theo cách đó — muộn màng, miễn cưỡng, sau khi cái cụ thể đã dạy cho tôi biết chúng thuộc về đâu — lại là những lớp thực sự đứng vững. Những lớp mà tôi xây sớm, từ sự thông minh và tính thẩm mỹ, lại là những lớp mà tôi mất nhiều tháng sau đó để vật lộn.
Bài học sâu xa hơn: trừu tượng quản lý độ phức tạp, nó không thay thế sự thấu hiểu
Tất cả rút lại thành một sự nhầm lẫn về việc trừu tượng dùng để làm gì. Tôi đã với tay tới nó như một thứ thay thế cho việc hiểu vấn đề — như thể một giao diện gọn gàng có thể cho phép tôi bỏ qua công sức khó nhọc của việc thực sự thấu hiểu cái thứ lộn xộn nằm bên dưới. Nó không thể. Trừu tượng là một công cụ để quản lý độ phức tạp mà bạn đã hiểu rồi, chứ không phải để né tránh công sức của việc hiểu nó.
Bạn không thể trừu tượng hóa để thoát khỏi việc không hiểu một thứ gì đó. Bạn chỉ có thể giấu đi sự rối rắm của chính mình bên dưới một bề mặt trông ngăn nắp hơn, nơi nó sẽ kiên nhẫn chờ đợi để phục kích bạn sau này, giờ đây khoác lên một giao diện gọn gàng. Hãy hiểu cái thứ đó trước đã. Trừu tượng hóa sau. Và khi bạn làm vậy, hãy vạch ranh giới dọc theo những đường nối mà sự thấu hiểu đã hé lộ, chứ không phải những đường chỉ trông tao nhã trước khi bạn biết được bất cứ thứ gì thực sự nằm ở đâu.
— Không tín hiệu, không lợi nhuận, không phải lời khuyên đầu tư.