Thực hành tốt nhất đối với các lớp ẩn danh trong các ứng dụng UI


8

Khi làm việc với các chương trình Java dựa trên giao diện người dùng, một cách gắn hành vi với một hành động nhất định (ví dụ: nhấp vào nút) là thông qua việc sử dụng các lớp ẩn danh. Trong ví dụ dưới đây, khung GUI là SWT, tuy nhiên tôi có cùng các vấn đề với các thành phần UI hoặc Android UI. Cụ thể là cấu trúc các chương trình của tôi.

MenuItem sampleMenuItem = new MenuItem(popupMenu, SWT.NONE);
sampleMenuItem.addSelectionListener(new SelectionAdapter() {
    public void widgetSelected(SelectionEvent event) {
         doSomething();

         // handle all table entries
         for (int i=0; i<10; i++) {
             doSomething2();
         }

         doSomething3();
         doSomething4();
    }
});

Tất nhiên, một số người có thể lập luận rằng số lượng mã trong mẫu ở trên đã đảm bảo cho việc tạo ra một lớp chuyên dụng có chứa logic. Điều này cũng được đề xuất bởi quy tắc "Các lớp ẩn danh không nên có quá nhiều dòng" của Sonar .

Thật thú vị, quy tắc này cũng chỉ định rằng:

squid: S1188 - Trong khi chờ hỗ trợ đóng trong Java, các lớp ẩn danh là cách thuận tiện nhất để thực hiện một hành vi mà không phải tạo một lớp chuyên dụng. Nhưng những lớp bên trong ẩn danh đó chỉ nên được sử dụng nếu hành vi có thể được thực hiện trong một vài dòng. Với mã phức tạp hơn, một lớp được đặt tên được gọi cho.

Tuy nhiên, vì các bao đóng chưa đến Java, câu hỏi của tôi là liệu có giải pháp nào thanh lịch hơn :

  • viết một loạt mã trong các lớp ẩn danh có tất cả các loại nhược điểm (tái sử dụng hạn chế, điều hướng chậm hơn qua mã, ...)
  • tạo ra một số lượng lớn các lớp chuyên dụng mà bản thân chúng có thể có chức năng rất hạn chế (ví dụ: quá kỹ thuật, ...)

Để mở rộng câu hỏi của tôi: Tôi cũng muốn biết các thực tiễn tốt nhất đối với khía cạnh này của các ứng dụng UI dựa trên Java là gì? Có bất kỳ mô hình thành lập tốt?


Bạn sẽ sử dụng các lớp ẩn danh trong đó khả năng tái sử dụng mã là tương đối thấp và bạn cần một số triển khai giao diện. Điều này tránh cho bạn phải viết một lớp mới cho mỗi lần thực hiện. Bạn đã thấy điều này ?
Robert Harvey

@Robert, tôi biết về thực tế rằng mã được gắn vào một lớp ẩn danh thường không có ý định sử dụng lại. Tuy nhiên, tôi đã gặp một vài trường hợp mà tôi muốn có thể làm điều này. Ví dụ: Trong trường hợp Nút và MenuItem cần thực thi cùng một mã, nhưng chỉ với các điều chỉnh nhỏ và không vi phạm DRY. Vì lý do này, tôi đang tìm kiếm các kỹ thuật cho phép phân tách và cấu trúc mã tốt hơn.
Jérôme

Bạn làm điều đó bằng cách thúc đẩy lớp ẩn danh thành một lớp thực tế.
Robert Harvey

Như đã đề cập trong câu hỏi của tôi, đây là một trong những giải pháp mà tôi biết. Tuy nhiên, tôi đang tìm kiếm các kỹ thuật khác hoặc thực hành tốt nhất trong trường hợp chúng tồn tại . Tuy nhiên, nếu không có thứ đó tồn tại và chúng ta phải chọn giữa việc tạo một lớp ẩn danh hoặc một lớp thực tế, thì đây cũng có thể là một câu trả lời hợp lệ .. :-) Trước đây, tôi đã làm việc với nhiều GUI khác nhau trong một loạt các ngôn ngữ lập trình khác nhau. Và từ Delphi đến Visual Studio cho đến cả Eiffel [sic], tôi luôn xem xét cách Java bằng cách sử dụng các lớp ẩn danh khá dài dòng về mặt LỘC cần thiết để đạt được kết quả.
Jérôme

1
Đó là bởi vì Java vốn đã dài dòng. Bạn không thể sửa chữa ngu ngốc.
Robert Harvey

Câu trả lời:


2

Mẫu duy nhất tôi đã thấy, hoạt động là "Khi mã khó hiểu được chuyện gì đang xảy ra, đã đến lúc ngừng sử dụng một lớp ẩn danh."

Trong ví dụ của bạn, phần thân phương thức là lớp ẩn danh. Tôi có thể chuyển "Chương trình lựa chọn mới" lên dòng riêng của mình, để làm cho phần mở đầu rõ ràng hơn một chút, nhưng nếu không thì không sao. Nơi bạn gặp rắc rối là khi một người ngẫu nhiên không còn có thể tìm ra vị trí của lớp ẩn danh và mã phương thức.

Tôi cũng đã tạo một biến riêng hoặc phương thức để giữ lớp ẩn danh. Tôi đặt thứ đó ở cuối lớp, tránh đường. Nó sắp xếp khoảng cách giữa một lớp hoàn toàn mới và giữ nó ở giữa mã. Một số người coi đó là phong cách xấu, nhưng quy tắc chung của tôi là mã hóa để dễ đọc trước tiên.


Tôi hoàn toàn đồng ý với sự tôn trọng đoạn đầu tiên của bạn. Tuy nhiên, đôi khi có vẻ rườm rà khi tạo ra một lớp dành riêng, đặc biệt là khi một cái gì đó bắt đầu với một vài dòng phát triển theo thời gian. Cho đến nay, tôi chưa bao giờ thấy ai đó gán các lớp ẩn danh cho các biến riêng tư ở cuối lớp cha. Tuy nhiên, tôi có thể thấy lợi ích của việc cấu trúc mã mà không tạo ra nhiều lớp dành riêng nhỏ. Ngay cả khi nó có thể là phong cách xấu, nó phần nào trả lời câu hỏi của tôi đối với các kỹ thuật khác tồn tại. +1
Jérôme

1

Các lớp bên trong vô danh là một thứ hoàn toàn phong cách; chúng không tồn tại như vậy trong lớp chứa ở cấp độ của tệp. class được tạo trong quá trình biên dịch; tất cả các lớp bên trong ẩn danh DO tạo một tệp. class riêng như thể chúng được viết dưới dạng các lớp cấp cao nhất.

Bạn có thể thấy điều này nếu bạn điều hướng đến thư mục đầu ra (thường được đặt tên là "out") và tìm lớp bên trong theo tên. Bạn sẽ thấy một tệp lớp riêng cho lớp bên trong của bạn. Như tôi nhớ tên của nó là OuterClassName $ InnerClassName. Class. Hàm tạo của một lớp bên trong ẩn danh (được tạo ngay cả khi bạn không tự viết nó) được chuyển qua một tham chiếu đến "cái này", tất nhiên là lớp bên ngoài có chứa.

Vì vậy, đừng căn cứ vào quyết định của bạn về bất kỳ mối quan tâm nào của bạn về "tạo ra nhiều lớp học". Đó hoàn toàn là một thứ phong cách.

Khi tôi khởi động Java, các lớp ẩn danh trông giống như một mớ hỗn độn lớn đối với tôi chỉ vì chúng đã vi phạm nhịp điệu của lớp giống như phương thức biến đổi phương thức sau đó đột nhiên một đống mã này xuất hiện. Thật ra, họ vẫn nhẹ nhàng chọc tức tôi.

Ưu điểm được cho là của họ là họ làm cho việc hiểu mã dễ dàng hơn - bạn không cần phải đi đến một số tệp khác để xem phương thức của lớp bên trong ẩn danh sẽ làm gì. Nhưng kia là nó.

Vì vậy, quyết định là một phong cách và không có gì hơn. Nếu bạn thích nó, sử dụng nó, nếu không, không.

chỉ muốn nhanh chóng thêm điều này - bạn có thể xem lại ý tưởng của mình có chứa chức năng giới hạn, giả sử 1 phương thức ngắn, trong một lớp chuyên dụng cấu thành kỹ thuật quá mức. Lớp, ít nhất là trong Java, là đơn vị của sự gắn kết. Quá kỹ thuật không được đo lường trong các phương pháp cho mỗi lớp hoặc thậm chí số lượng lớp. OE hoàn toàn trực giao với cả hai điều này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.