paint-brush
Gradle có thực sự tốt hơn Maven không? - Bản án cuối cùng của tôiby@nfrankel
5,481
5,481

Gradle có thực sự tốt hơn Maven không? - Bản án cuối cùng của tôi

Nicolas Fränkel8m2023/08/09
Read on Terminal Reader

Trong bài đăng này, tôi muốn làm sáng tỏ một chút về Gradle, vì vậy tôi có thể hướng mọi người đến nó thay vì lặp đi lặp lại cùng một "lý do".
featured image - Gradle có thực sự tốt hơn Maven không? - Bản án cuối cùng của tôi
Nicolas Fränkel HackerNoon profile picture
0-item

Tôi tweet nội dung kỹ thuật mà tôi cho là thú vị, nhưng những tweet hài hước mới là những nội dung thu hút nhiều sự tương tác nhất. Tôi đã tham dự hội nghị JavaLand vào tháng 3, tình cờ thấy gian hàng Gradle và tìm thấy viên ngọc quý này:

https://twitter.com/nicolas_frankel/status/1638549568957861889


Tất nhiên, tại một thời điểm nào đó, một fanboy đã chiếm đoạt chủ đề và tuyên bố cái gọi là ưu thế của Gradle. Trong bài đăng này, tôi muốn làm sáng tỏ lập trường của mình, để tôi có thể hướng mọi người đến đó thay vì lặp đi lặp lại cùng một "lý do".


Để quản lý việc này, tôi cần quay ngược thời gian. Phát triển phần mềm là một lĩnh vực thay đổi nhanh chóng và phần lớn sự hiểu biết của chúng tôi dựa trên kinh nghiệm cá nhân. Vì vậy, đây là của tôi.

Công cụ xây dựng đầu tiên của tôi: Ant


Tôi bắt đầu phát triển bằng Java vào năm 2002. Vào thời điểm đó, không có công cụ xây dựng nào: chúng tôi đã biên dịch và xây dựng thông qua IDE. Để ghi lại, lần đầu tiên tôi sử dụng Visual Age cho Java; sau đó, tôi chuyển sang Borland JBuilder.


Xây dựng bằng IDE có một vấn đề lớn: mỗi nhà phát triển có các cài đặt chuyên dụng, do đó, việc tạo phần mềm tùy thuộc vào sự kết hợp giữa nhà phát triển và máy.


Các bản dựng không thể lặp lại là một vấn đề lâu đời. Trải nghiệm đầu tiên của tôi với các bản dựng lặp lại là Apache Ant:


Apache Ant là một thư viện Java và công cụ dòng lệnh có nhiệm vụ điều khiển các quy trình được mô tả trong các tệp xây dựng dưới dạng các mục tiêu và điểm mở rộng phụ thuộc lẫn nhau. Cách sử dụng chính được biết đến của Ant là xây dựng các ứng dụng Java. Ant cung cấp một số tác vụ tích hợp cho phép biên dịch, lắp ráp, kiểm tra và chạy các ứng dụng Java. Ant cũng có thể được sử dụng hiệu quả để xây dựng các ứng dụng không phải Java, chẳng hạn như các ứng dụng C hoặc C++. Tổng quát hơn, Ant có thể được sử dụng để điều khiển bất kỳ loại quy trình nào có thể được mô tả dưới dạng mục tiêu và nhiệm vụ.


--https: //ant.apache.org/


Ant dựa trên ba khái niệm trừu tượng chính:


  • Một tác vụ là một đơn vị công việc nguyên tử, ví dụ : javac để biên dịch các tệp Java, war để lắp ráp một Lưu trữ Web, v.v. Ant cung cấp nhiều tác vụ có sẵn nhưng cho phép thêm các tác vụ tùy chỉnh.
  • Một mục tiêu là một danh sách các nhiệm vụ.
  • Bạn có thể xác định các phụ thuộc giữa các tác vụ, chẳng hạn như gói tùy thuộc vào biên dịch . Về vấn đề này, bạn có thể xem Ant như một cỗ máy thực thi quy trình công việc.


Tôi nhanh chóng trở nên "thông thạo" Ant. Là một nhà tư vấn, tôi đã đi từ công ty này sang công ty khác, dự án này sang dự án khác. Ban đầu, tôi chủ yếu thiết lập Ant, nhưng Ant trở nên phổ biến hơn khi thời gian trôi qua và tôi gặp phải các thiết lập Ant hiện có. Tôi nhất quán trong các dự án của mình, nhưng các dự án khác lại rất khác nhau.


Mỗi khi đến một dự án mới, bạn phải đọc kỹ phần thiết lập Ant để hiểu cách xây dựng tùy chỉnh. Hơn nữa, cấu trúc của mỗi dự án là khác nhau. Một số đặt nguồn của chúng trong src , một số đặt trong sources , một số đặt trong cấu trúc lồng nhau, v.v.


Tôi nhớ có lần một tệp xây dựng chung đã thử đáp ứng toàn bộ nhu cầu dự án của một tổ chức. Nó đã xác định hơn 80 mục tiêu trong hơn 2.000 dòng XML. Tôi đã mất một khoảng thời gian không hề nhỏ để hiểu cách sử dụng nó với sự trợ giúp và thậm chí nhiều thời gian hơn để có thể điều chỉnh nó mà không làm hỏng dự án.

Công cụ xây dựng thứ hai của tôi: Maven

Dự án trên đã khiến tôi suy nghĩ rất nhiều. Tôi muốn cải thiện tình hình vì những người bảo trì đã vượt quá giới hạn của Ant. Vào thời điểm đó, tôi đang làm việc với người bạn Freddy Mallet (của Sonar nổi tiếng). Chúng tôi đã nói chuyện, và anh ấy chỉ tôi đến Maven. Tôi đã từng xây dựng một dự án với Maven nhưng không có kinh nghiệm nào khác trước đó. Tôi đã nghiên cứu tài liệu trong nhiều giờ và thông qua các lần thử và sai, dưới sự hướng dẫn của Freddy, đã di chuyển toàn bộ tệp xây dựng Ant sang một POM gốc đơn giản.


Trong Ant, bạn cần xác định mọi thứ trong từng dự án. Ví dụ: Ant yêu cầu định cấu hình vị trí tệp Java để biên dịch; Maven cho rằng chúng nằm dưới src/main/java , mặc dù có thể ghi đè lên nó. Maven đã cách mạng hóa lĩnh vực xây dựng Java với cách tiếp cận Quy ước về Cấu hình . Ngày nay, rất nhiều phần mềm cung cấp cấu hình hợp lý theo mặc định.


Đối với các nhà phát triển đi từ dự án này sang dự án khác, như tôi đã làm, điều đó có nghĩa là tải trọng nhận thức sẽ ít hơn nhiều khi tham gia một dự án mới. Tôi hy vọng các nguồn Java sẽ được đặt bên dưới src/main/java . Các quy ước Maven tiếp tục vượt ra ngoài cấu trúc của dự án. Họ cũng xác định vòng đời của dự án, từ biên dịch đến tải lên phần mềm tạo tác trong sổ đăng ký từ xa, thông qua thử nghiệm đơn vị và tích hợp.


Cuối cùng, các nhà phát triển cơ sở có xu hướng không để ý đến nó, nhưng Maven đã định nghĩa thuật ngữ quản lý phụ thuộc . Nó đưa ra ý tưởng về các cơ quan đăng ký tạo tác, nơi người ta có thể tải xuống các phần phụ thuộc bất biến từ đó và đẩy các tạo tác vào. Trước đó, mỗi dự án phải lưu trữ các phụ thuộc trong kho lưu trữ chuyên dụng của nó.


Đối với bản ghi, có một số phụ thuộc được lưu trữ trong dự án nói trên. Khi tôi chuyển từ Ant sang Maven, tôi phải tìm phiên bản phụ thuộc chính xác. Đối với hầu hết, nó rất đơn giản, vì nó có trong tên tệp hoặc tệp kê khai của JAR. Tuy nhiên, một chiếc đã được cập nhật với các lớp bổ sung.


Quá nhiều cho sự bất biến.


Maven có ảnh hưởng sâu sắc đến tất cả các công cụ xây dựng sau này: chúng tự xác định dựa trên Maven.

Không có công cụ xây dựng nào của tôi: Gradle


Yêu cầu chính của Gradle là sửa chữa những thiếu sót của Maven, hoặc ít nhất là những gì nó cho là như vậy. Mặc dù Maven không được miễn trừ trách nhiệm, nhưng Gradle cho rằng vấn đề quan trọng nhất là sự thiếu linh hoạt của nó. Đó là một giả định đáng ngạc nhiên vì đó chính xác là điều mà Maven đã cải thiện so với Ant. Các dự án Maven có cấu trúc tương tự và sử dụng cùng một vòng đời: nguyên tắc ít bất ngờ nhất có hiệu lực. Ngược lại, Gradle cho phép tùy chỉnh gần như mọi khía cạnh xây dựng, bao gồm cả vòng đời.


Trước khi đối đầu với tranh luận về tính linh hoạt, hãy để tôi thừa nhận hai tính năng gốc tuyệt vời của Gradle mà Maven đã triển khai sau đó: trình nền Gradle và trình bao bọc Gradle.


Maven và Gradle đều là các ứng dụng Java chạy trên JVM. Bắt đầu một JVM rất tốn kém về thời gian và tài nguyên. Lợi ích là JVM chạy dài sẽ tối ưu hóa mã JIT-ed theo thời gian. Đối với các tác vụ ngắn hạn, lợi ích bằng không và thậm chí có hại nếu bạn tính đến thời gian khởi động JVM. Gradle đã đưa ra trình nền Gradle. Khi bạn chạy Gradle, nó sẽ tìm một daemon đang chạy. Nếu không, nó sẽ bắt đầu một cái mới. Ứng dụng dòng lệnh sẽ ủy thác mọi thứ cho daemon. Đúng như tên gọi của nó, trình nền không dừng lại khi dòng lệnh kết thúc. Trình nền tận dụng các lợi ích của JVM.


Rất có thể ứng dụng của bạn sẽ tồn tại lâu hơn các công cụ xây dựng hiện tại của bạn. Điều gì xảy ra khi bạn cần sửa một lỗi trong 5 năm kể từ bây giờ, chỉ để nhận thấy rằng công cụ xây dựng của dự án không có sẵn trực tuyến? Ý tưởng đằng sau trình bao bọc của Gradle là giữ phiên bản Gradle chính xác cùng với dự án và chỉ đủ mã để tải xuống phiên bản đầy đủ qua Internet. Là một tác dụng phụ, các nhà phát triển không cần cài đặt Gradle cục bộ; tất cả đều sử dụng cùng một phiên bản, tránh bất kỳ sự khác biệt nào.

Ra mắt tính linh hoạt của Gradle

Gradle mang hai tính năng tuyệt vời trên mà Maven tích hợp, chứng tỏ rằng cạnh tranh là tốt. Mặc dù vậy, tôi vẫn không thấy lợi ích của Gradle.


Tôi sẽ cố gắng đẩy khía cạnh cảm xúc sang một bên. Khi mới thành lập, hoạt động tiếp thị của Gradle đã cố gắng hạ bệ Maven trong mọi trường hợp có thể, công bố các biểu đồ so sánh điên rồ và nói chung là rất tích cực trong hoạt động truyền thông. Giả sử giai đoạn này kéo dài quá mức có thể chấp nhận được đối với một công ty trẻ đang cố gắng tìm kiếm vị trí của mình trên thị trường. Bạn có thể nói rằng Gradle rất Oedipian trong cách tiếp cận của nó: cố gắng giết "cha đẻ" Maven của nó. Cuối cùng, sau ngần ấy năm, có vẻ như nó đã khôn ngoan và giờ "yêu Maven."


Hãy nhớ rằng trước khi Maven tiếp quản, mọi dự án Ant đều là đặc biệt. Maven đã chấm dứt điều đó. Nó mang luật đến World Wild West của các dự án tùy chỉnh. Bạn có thể không đồng ý với luật, nhưng dù sao đó cũng là luật và mọi người cần phải tuân theo luật. Các tiêu chuẩn của Maven cố thủ đến mức mặc dù có thể ghi đè một số tham số, ví dụ : vị trí nguồn, nhưng không ai từng làm điều đó.


Tôi đã trải nghiệm hai triệu chứng về tính linh hoạt của Gradle. Tôi nghi ngờ tồn tại nhiều hơn nữa.

Các giai đoạn vòng đời tùy chỉnh

Maven quản lý thử nghiệm tích hợp theo bốn giai đoạn, chạy theo thứ tự:


  1. pre-integration-test : thiết lập bất cứ thứ gì mà bài kiểm tra cần
  2. integration-test : thực hiện các bài kiểm tra
  3. post-integration-test : dọn dẹp tài nguyên, nếu có
  4. verify : hành động dựa trên kết quả của các bài kiểm tra


Tôi chưa bao giờ sử dụng các giai đoạn trước và sau, vì mỗi thử nghiệm đều có logic thiết lập và phân tích riêng.


Mặt khác, Gradle không có khái niệm về các bài kiểm tra tích hợp . Tuy nhiên, những người hâm mộ Gradle sẽ vui vẻ giải thích rằng bạn có thể thêm các giai đoạn mà bạn muốn. Thật vậy, Gradle cho phép "tùy chỉnh" vòng đời: bạn có thể thêm bao nhiêu giai đoạn bổ sung vào vòng đời thông thường tùy thích.


Đó là một mớ hỗn độn, vì mỗi dự án sẽ cần phải đưa ra cả số giai đoạn cần thiết và tên của chúng: integration-test , integration-tests , integration-testing , it (dành cho người lười biếng), v.v. Các tùy chọn là vô tận.

Hội chứng bông tuyết

Maven coi mọi dự án là một dự án tiêu chuẩn thông thường. Và nếu bạn có nhu cầu cụ thể, bạn có thể viết plugin cho điều đó. Viết một plugin Maven chắc chắn không thú vị; do đó, bạn chỉ viết một khi cần thiết, không phải chỉ vì bạn đã quyết định rằng luật không áp dụng cho bạn.


Gradle tuyên bố rằng sự thiếu linh hoạt là một vấn đề; do đó, nó muốn sửa chữa nó. Tôi thì ngược lại: công cụ xây dựng của tôi thiếu linh hoạt là một tính năng, không phải lỗi. Gradle giúp dễ dàng hack bản dựng. Do đó, bất kỳ ai nghĩ rằng dự án của họ là một bông tuyết đặc biệt và xứng đáng được tùy chỉnh sẽ vui vẻ làm như vậy. Kiểm tra thực tế: hiếm khi như vậy; khi có, nó dành cho các khuôn khổ, không phải các dự án thông thường. Những người ủng hộ Gradle nói rằng nó vẫn cung cấp các tiêu chuẩn trong khi cho phép cấu hình dễ dàng. Trọng tâm của vấn đề là nó không phải là một tiêu chuẩn nếu nó có thể được thay đổi theo ý muốn của bất kỳ ai.


Gradle là công cụ xây dựng trên thực tế cho các dự án Android . Tại một trong những công ty mà tôi làm việc, ai đó đã viết mã Groovy tùy chỉnh trong bản dựng Gradle để chạy Sonar và gửi số liệu đến phiên bản Sonar nội bộ. Vào thời điểm đó, không có plugin Sonar nào có sẵn, hoặc tôi cho rằng nó không hiệu quả. Càng xa càng tốt.


Khi một nhóm khác tạo dự án Android thứ hai của công ty, họ đã sao chép cấu trúc của dự án đầu tiên và tệp bản dựng. Tại thời điểm này, điều thông minh cần làm là tạo một plugin Gradle bên trong từ mã dành riêng cho Sonar. Nhưng họ đã không làm điều đó vì Gradle khiến việc hack bản dựng trở nên quá dễ dàng. Và tôi, người ghét Gradle, đã tự mình tạo plugin. Ít nhất, nó có thể là một trải nghiệm dành cho nhà phát triển tốt hơn. Thiếu tài liệu chất lượng và sử dụng ngôn ngữ chưa nhập (Groovy), tôi đã sử dụng bảng điều khiển để in ra cấu trúc của đối tượng để tiến hành.

Phần kết luận

Cạnh tranh là tốt và Gradle đã mang đến những ý tưởng mới mà Maven đã tích hợp, trình bao bọc và daemon. Tuy nhiên, Gradle được xây dựng dựa trên tiền đề rằng tính linh hoạt là tốt, trong khi kinh nghiệm của tôi cho tôi thấy điều ngược lại. Ant rất linh hoạt và tải trọng nhận thức để chuyển từ dự án này sang dự án tiếp theo rất cao.


Chúng tôi, các nhà phát triển, là con người: chúng tôi muốn nghĩ rằng các dự án của mình khác với các dự án khác. Hầu hết thời gian, họ không. Tùy chỉnh chỉ là một cách để thỏa mãn cái tôi của chúng tôi. Các công cụ xây dựng linh hoạt cho phép chúng tôi triển khai tùy chỉnh như vậy, cho dù có được bảo hành hay không.


Các tùy chỉnh không liên quan không mang lại lợi ích gì và dễ phát triển nhưng tốn kém để duy trì. Nếu việc quản lý nội dung phần mềm là một phần trách nhiệm của tôi, thì tôi sẽ luôn chọn tính ổn định thay vì tính linh hoạt cho công cụ xây dựng của mình.


Được xuất bản lần đầu tại A Java Geek vào ngày 6 tháng 8 năm 2023