Bài trước tôi đã đưa ra bàn luận về Interfact Segregration và cũng có nói bài này sẽ bàn luận việc kiến trúc phần mềm hiện tại mài mòn kĩ năng OOP của chúng ta ra sao. Thực ra điều này cũng không có gì xấu. Cái gì có ích thì tồn tại và các kiến trúc phần mềm hiện đại tỏ ra hiệu quả hơn việc đi sâu vào thiết kế OOP. Điều này không phải chúng ta không cần các thiết kế OOP nữa, mà là chúng ta không phải quan tâm nhiều đến OOP nữa. Việc chuyển dịch các ngôn ngữ lập trình, đặc biệt sự lên ngôi của các ngôn ngữ lập trình tổng quát như Go, Ruby hay gần đây là Rust, cũng như sự phát triển của javascript là minh chứng cho việc OOP giảm thiểu vai trò đáng kể trong giới lập trình. Không phải tại OOP dở, mà các ngôn ngữ lập trình mới sinh ra để giải quyết cái bài toán mới hơn. Thời đại mà OOP ra đời là thời đại của chuyển đổi số, các bài toán chủ yếu là các hệ thống thông tin quản lý và OOP là công cụ tuyệt vời để mô tả, xử lý sự rắc rối của các quan hệ trong bài toán quản lý thông tin. Trong khi đó, hiện tại là các bài toán tính toán hiệu năng cao, tốc độ phát triển nhanh. learning curve thẳng. Hãy hiểu rõ rằng không phải các hệ thống quản lý thông tin ít đi. Các hệ thống quản lý thông tin vẫn là phải có trong các sản phẩm, nhưng nó đã được giải quyết nhiều năm và không còn là thách thức lớn. Các ngôn ngữ mới, công nghệ mới sinh ra để chúng ta xử lý các thách thức hiện tại tốt hơn, là các hệ thống tính toán hiệu năng cao. Các hệ thống quản lý thông tin ngày trước phục vụ số ít người là các nhân viên văn phòng, còn hiện tại, các hệ thống thông tin phục vụ ngoài các nhân viên văn phòng chuyên nghiệp còn phục vụ toàn bộ con người, từ lớn đến bé, từ già đến trẻ. Một ví dụ đơn giản là về C# mà tôi làm việc nhiều năm. Ban đầu, nó được giới thiệu là ngôn ngữ lập trình hướng đối tượng, còn hiện tại nó được giới thiệu là ngôn ngữ lập trình tổng quát General purpose. Hay như ReactJs, cách viết class component được thay thế bằng các hook và functional component.
Bỏ qua các ngôn ngữ mới thì ngay trong chính OOP cũng có sự chuyển dịch, hay chính xác hơn là sự tiến hóa. Chúng ta đã quá quen với n-tiers, MVC, MVVC. Những thiết kế này là sự chắt lọc của giới lập trình sau nhiều năm và chúng thực sự hiệu quả. Bạn cần gì phải đau đầu nghĩ về thiết kế khi đã có sẵn những cái bánh mì này? Các dòng code chúng ta viết hầu như chỉ còn là các đoạn nghiệp vụ tính toán cốt lõi. Còn rất ít các bài toán để bạn phải vắt óc suy nghĩ nên thiết kế nó như thế nào. Thậm chí các bài toán lớn như e-Commerce cũng có sẵn nhiều thiết kế cho bạn lựa chọn. Điều đó là thỏa đáng thôi. Tái sử dụng là tôn chỉ của lập trình viên. Các thiết kế có sẵn đôi lúc không khớp 100% với vấn đề của bạn nhưng nó có là gì so với việc dễ dàng tiếp cận, phát triển, và chuyển giao?
Tôi đã đề cập trong bài viết trước về việc các kiến trúc có sẵn này thường phân tách các lớp theo chức năng kĩ thuật lập trình, đó là thứ ít khi thay đổi, không phụ thuộc vào các bài toán riêng lẻ. Ví dụ một nghiệp vụ kế toán, là sự tương tác giữa các tài khoản và hóa đơn. Việc thiết kế các lớp tài khoản hay hóa đơn với hành vi của riêng nó (những gì sách vở thường đề cập) không hữu ích cho lắm khi chúng ta đã có các lớp service xử lý tính toán. Việc này tăng độ phức tạp cũng như khiến lớp service dư thừa, tăng tài nguyên tiêu tốn cho việc phát triển và cũng khiến việc chuyển giao rắc rối hơn. Trong thực tế, ít trường hợp cần chúng ta thiết kế thêm các module độc lập nên cơ hội mãi dũa của lập trình viên cũng ít đi (các module Core, Base, Common hay Entities chỉ để định nghĩa những thứ cơ bản không chứa nhiều business logic).
Về mặt nghề nghiệp, một lý do mà các lập trình viên trong các công ty sản phẩm sẽ được đánh giá cao hơn so với các công ty outsourcing chính là việc họ phải đối mặt với những bài toán đặc thù và thường phải tự thân vận động trong việc giải toán. Các kinh nghiệm này không phải phổ biến trong các công ty outsourcing, và kể cả khi có những vấn đề hóc búa, các lập trình viên vẫn cần được “cho phép” để sáng tạo.
Sự khó lường của OOP là một nhược điểm. Cần nhiều tài nguyên để đánh giá một thiết kế OOP là tốt, trong khi các mô hình lập trình khác tuyến tính hơn, và các best practices có thể xử lý đa số các vấn đề của thiết kế. Trong OOP, trừu tượng hóa vừa giúp chương trình linh hoạt nhưng nó cũng có thể là một tảng đá chắn đường khi cần refactor. Một thiết kế có thể rất tốt hiện tại nhưng lại khiến chúng ta bật ngửa về sau. Thường các dự án nhỏ cũng ko đặt nặng OOP. Các ngôn ngữ và tiêu chuẩn hiện tại đề cao sự nhỏ gọn và thích chia nhỏ mọi thứ, đại loại có 100 đôi giầy rẻ tiền hơn là có 10 đôi giầy đắt tiền, đôi nào không vừa chân thì mua đôi mới vừa dễ, vừa nhanh. Hiện tại chúng ta còn có thể chia nhỏ một dự án đến mức một function. Nếu function này lạc hậu thì viết cái mới hoặc bỏ quách đi.
Tóm lại, OOP không còn giữ vai trò ngôi sao trung tâm như trước kia, cũng như việc các thiết kế có sẵn quá tốt, kĩ năng OOP của lập trình viên đang thui chột. Một thực tế khác là AI, có thể không lâu nữa, chúng ta không phải hì hụi code cả ngày, và OOP sẽ không tìm lại được hào quang. Thiết kế tồi sao? Gen lại cả hệ thống vậy. Có thể sau này công việc của chúng ta không phải là spiral của agile mà là spiral của promt, gen, test, eval, promt.
Dù thế nào thì lập trình viên hiện tại phải trang bị một núi kiến thức và kĩ năng. Bạn vẫn cần kĩ năng OOP tốt để ít nhất không push code lởm.