Gần đây, các hệ thống sinh code tự động (Automatic Code Generation) đang trở nên phổ biến nhờ sự hỗ trợ của các công nghệ như Low code, No code, AI, … Tuy nhiên, trên thực tế, các hệ thống sinh code đã có từ rất lâu, được tích hợp vào các thư viện, framework phổ biến và được các lập trình viên sử dụng ở các mức độ khác nhau.
Vì sao nên sử dụng hệ thống sinh code tự động?
Khi phát triển ứng dụng, lập trình viên thường gặp những bài toán tương tự nhau, một số tác vụ có tính chất giống nhau & lặp đi lặp lại. Nếu tự viết code thủ công, thời gian cần cho phát triển ứng dụng sẽ tăng lên nhiều, đồng thời gây nhàm chán cho công việc lập trình.
Nguyên lý sinh code tự động
Các hệ thống sinh code tự động hoạt động dựa trên nguyên lý biến thiết kế ở mức cao (Database Design, UI mockup) thành source code. Lập trình viên (hoặc cả những người không chuyên về lập trình) thực hiện vẽ các giản đồ database, màn hình ứng dụng, tương tác dữ liệu giữa các thành phần ứng dụng. Việc này hay được thực hiện bằng cách “kéo thả”, có nghĩa được tiến hành một cách trực quan trên các phần mềm thiết kế chuyên dụng. Các phần mềm thiết kế này sau đó sẽ sinh ra mã nguồn cho ứng dụng chương trình.
Trong một số trường hợp, việc thể hiện ý tưởng thiết kế qua cách kéo thả có thể không thuận lợi, lập trình viên thường dùng các file cấu hình dưới dạng json/xml để mô tả về ứng dụng, sau đó phần mềm sinh code sẽ chuyển file cấu hình thành mã nguồn.
Code được sinh ra theo một trong các cách sau:
- Mã nguồn sinh ra một lần
Phần mềm sinh code tạo ra mã nguồn của khung dự án ban đầu, sau đó lập trình viên sử dụng để tiếp tục phát triển thêm. Cách này có ưu điểm là dễ thực hiện (đối với phần mềm sinh code), nhưng có nhược điểm là chỉ giúp tiết kiệm công sức ở giai đoạn đầu dự án. Ở các giai đoạn sau, khi cần update, nâng cấp phần mềm, lập trình viên có thể sẽ không còn sử dụng được các tính năng sinh code tự động, do mã nguồn mới sinh ra sẽ có xung đột với mã nguồn dự án đã bị thay đổi trong quá trình phát triển.
Ví dụ về các hệ thống sinh code loại này là các phần mềm chuyển từ thiết kế ERD sang các script SQL hay các class của ngôn ngữ lập trình, phần mềm chuyển từ thiết kế mockup sang html, css, javascript.
- Mã nguồn sinh ra nhiều lần
Phần code sinh ra được bổ sung liên tục trong quá trình phát triển dự án. Cách này có ưu điểm là có thể tiếp tục sinh thêm code trong quá trình dự án diễn ra về sau. Nhược điểm là sẽ yêu cầu phần mềm sinh code phải phân biệt được 2 vùng code tự động & code do lập trình viên viết, IDE đòi hỏi phải có tính năng lock (không cho sửa) phần code tự động sinh ra.
Ví dụ về các hệ thống sinh code loại này bao gồm các hệ thống thiết kế form theo dạng kéo thả, bắt đầu từ Visual Basic trong thế kỷ trước, tiếp đến là Java Swing hay Winform của dotnet.
- Mã nguồn nhúng
Phần code sinh ra không nằm source code dự án mà được nhúng vào mã nguồn ứng dụng khi chạy. Cách này còn được gọi là sinh code động (dynamic, on-the-fly) vì mã nguồn chỉ được sinh ra khi ứng dụng chạy lên (lập trình viên sẽ không nhìn thấy mã nguồn sinh ra).
Ví dụ về các hệ thống sinh code theo cách này bao gồm cách sử dụng các file cấu hình json, xml (java bean) hay sử dụng các annotation trong khai báo class.
Việc sử dụng sinh code theo cách này thường rất phổ biến, tuy nhiên lập trình viên có thể không để ý rằng có nhiều mã nguồn đã được sinh ra & dịch ngay trong quá trình ứng dụng chạy.
Ví dụ với các repository của Spring, khi khai báo, lập trình viên chỉ cần chỉ định Entity class & kiểu dữ liệu của Primary Key, còn Spring sẽ sinh ra toàn bộ các phương thức CRUD (findAll, findById, save, deleteById, …) trong quá trình chạy:
public interface ProductRepository extends JpaRepository<Product, Long> {} Khi lập trình viên khai báo và sử dụng repository: @Autowired private final ProductRepository repository; |
Thực chất class của đối tượng repository không phải là interface đã khai báo ở phía trên (interface không thể khởi tạo do không có các phương thức thực thi), mà là một class ẩn danh (thường được gọi là Proxy class). Class này được Spring sinh ra khi ứng dụng bắt đầu chạy, chứa mã nguồn để thực hiện các thao tác CRUD mà interface quy định.
Ưu/Nhược điểm của việc dùng hệ thống sinh code tự động
Ưu điểm:
- Giảm nhẹ bớt công sức của lập trình viên
- Giảm bớt các bug cơ bản
Nhược điểm:
- Code sinh ra không phải bao giờ cũng đồng nhất với style, quy định của từng dự án cụ thể
- Code sinh ra thường không sửa được, hoặc nếu sửa thì cũng tiềm tàng nhiều bug phát sinh (do không phải code của lập trình viên viết ra, lúc sửa lập trình viên sẽ không lường hết được các thay đổi sẽ tác động đến các phần khác trong dự án)
- Một số phần mềm sinh code tự động có giá thành cao
Giới thiệu phần mềm sinh code Jhipster
Jhipster là phần mềm sinh code cho các dự án Java Web – giúp tạo ra code cho các entity, repository, service, controller của Spring từ thiết kế ERD. Ngoài ra, Jhipster có thể sinh code giao diện cho các framework frontend phổ biến như Angular, React, Vue… Bài viết này chỉ đề cập đến chức năng sinh code cho phần Spring API.
Về lý thuyết, Jhipster là phần mềm sinh mã nhiều lần (có thể bổ sung các Entity vào ERD và yêu cầu Jhipster sinh thêm mã nguồn cho các Entity mới). Tuy nhiên trên thực tế, đa phần Jhipster được sử dụng để sinh code khi mới bắt đầu dự án (dựng skeleton), còn khi dự án đã hoạt động, việc sinh thêm mã nguồn bằng Jhipster thường gây ra xung đột với code dự án, nếu muốn tránh xung đột, phải tuân theo quy định code của Jhipster (việc này đôi khi còn gây mất nhiều thời gian hơn so với tự code từ đầu)
Cài đặt Jhipster
Để cài đặt Jhipster, cần cài đặt nodejs (do jhipster dùng npm để cài đặt), sau đó cài Jhipster với lệnh:
npm install -g generator-jhipster
- Tạo mới ứng dụng
Để tạo mới ứng dụng, tạo một folder trống, mở cửa sổ command trong thư mục vừa tạo và gõ lệnh:
jhipster
- Thiết kế ERD
Jhipster dụng phần mềm JDL studio để thiết kế ERD. Sau khi thiết kế xong, ERD được export thành một file jdl, file này được jhipster sử dụng để sinh ra mã nguồn ban đầu cho dự án
- Sinh mã nguồn dự án
Để tạo ra mã nguồn dự án từ ERD, copy file jdl vào trong thư mục dự án và chạy lệnh:
jhipster jdl my-jdl.jdl
jhipster import-jdl my-jdl.jdl
Jhipster sẽ sinh ra mã nguồn dự án với đủ các tầng:
- Domain (Entity)
- Repository
- Service
- Web.rest (Controller)
- Chạy ứng dụng
Ứng dụng do Jhipster tạo ra có đầy đủ các CRUD API cho các Entity trong ERD. Ngoài ra Jhipster tích hợp Spring security với cơ chế xác thực JWT/Oauth2. Tài khoản demo được tạo ra khi chạy ứng dụng lần đầu là user/user và admin/admin
Các CRUD API đều được gắn xác thực, do đó muốn gọi CRUD API, ban đầu cần gọi API xác thực để lấy token:
Sau khi có token, sử dụng token để gọi các API CRUD trên các Entity của dự án:
Mong rằng, những thông tin của bài đã giúp các bạn nắm được những kiến thức về hệ thống sinh code tự động! Chúc các bạn học tốt và thực hiện thành công!
Bộ môn Ứng dụng phần mềm
Trường Cao đẳng FPT Mạng cá cược bóng đá
cơ sở Hà Nội