2011-01-15 28 views
8

chúng tôi đã có một cuộc tranh luận tại nơi làm việc về thực hành tốt nhất cho việc sử dụng các thính giả trong java là gì: cho dù người nghe logic nên ở lại trong lớp vô danh, hoặc nó phải ở trong một phương pháp riêng biệt, ví dụ:Java: Tôi nên đặt mã logic của người nghe ẩn danh ở đâu?

button.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     // code here 
    } 
}); 

hoặc

button.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     buttonPressed(); 
    } 
}); 

private void buttonPressed() { 
    // code here 
} 

cách được khuyến nghị về khả năng đọc và bảo trì là gì? Tôi thích giữ mã bên trong người nghe và chỉ khi quá lớn, hãy biến nó thành một lớp bên trong. Ở đây tôi giả định rằng mã không được nhân bản ở bất kỳ nơi nào khác.

Cảm ơn bạn.

Trả lời

4

quy tắc tự áp đặt của tôi là:

  1. Nếu người nghe có hơn 2 phương pháp, tạo ra một lớp được đặt tên.
  2. Nếu người nghe mở rộng hơn 10 dòng, hãy tạo một lớp có tên.

Khá đơn giản, dễ theo dõi và tạo ra nhiều hoặc ít mã dễ đọc hơn. Nhưng sau đó tôi phải thừa nhận rằng tôi thậm chí không bao giờ nghĩ về những gì ví dụ của bạn cho thấy.

+0

Một số quy tắc chung của ngón tay cái. 1+ –

+1

Tôi có xu hướng sử dụng một lớp bên trong có tên, và có xu hướng tạo ra những lớp đó cũng cho những người nghe nhỏ hơn nếu có rất nhiều người trong số họ để ngăn chặn mã obfuscation trong quá trình đăng ký. Vì vậy, đó sẽ là một tiêu chí thứ 3 cho tôi. – extraneon

1

Theo ý kiến ​​cá nhân của tôi, "nó phụ thuộc". Nếu người nghe chỉ được thêm vào một thành phần duy nhất, rất đơn giản và là một phần không thể thiếu của GUI, thì một lớp bên trong vô danh sẽ hoạt động tốt. Nếu người nghe là phức tạp, sẽ được thêm vào nhiều thành phần, sẽ có trạng thái riêng biệt riêng của nó, sau đó một lớp riêng biệt đứng một mình là tốt hơn. Ở giữa là lớp bên trong riêng tư. HTH.

Chỉnh sửa: Tệ của tôi. Tôi đã trả lời một câu hỏi khác - có hay không sử dụng một lớp độc lập riêng biệt cho một người nghe. Đối với việc để giữ anon bên trong mã lớp nội tuyến so với trong một phương pháp, tôi đồng ý với các poster khác, nó sẽ phụ thuộc vào kích thước và độ phức tạp của mã người nghe.

2

Câu hỏi này là một phần trả lời ở đây:

Is there a better practice for listeners

Tôi cũng không thích cách Anonymous vì hai lý do:
1), bạn không thể dễ dàng tái sử dụng mã, do đó bạn có thể tìm thấy rằng bạn có mã trùng lặp sau một thời gian 2) Tôi tìm thấy nó phá vỡ việc đọc mã (những người khác không đồng ý ... sở thích cá nhân). Tôi nghĩ mọi người sẽ đồng ý rằng nếu bạn đang làm hơn 5-10 dòng thì một lớp bên trong vô danh không phải là một ý tưởng hay (tôi sẽ nói nhiều hơn 2 là quá nhiều).

+0

+1 - Bạn không thể sử dụng lại mã theo một phương thức ẩn danh. – jmort253

+0

Chắc chắn bạn có thể. Chỉ cần có được người nghe từ nút và bọc nó trong một người nghe khác :) Hoàn hảo tái sử dụng (mặc dù không thể duy trì :) – extraneon

+1

Chắc chắn bạn chỉ có thể tái sử dụng dụ. Hành động action = new Action ("Go") {...}, sau đó bạn có thể gán nó cho một nút, menu, hoặc ActionMap. Không có vấn đề với tái sử dụng bằng cách tái sử dụng dụ. Bạn cũng có thể xóa nó khỏi người nghe. – chubbsondubs

1

Nếu phương pháp buttonPressed() sẽ cần phải được truy cập từ bất kỳ thứ gì ngoài lớp bên trong ẩn danh, sau đó sử dụng phương pháp. Nếu không, chỉ cần đặt mã trong vòng actionPerformed().

+0

Đồng ý. Tốt đẹp và dễ dàng để đạt được với tái cấu trúc trong IDE. – Xorty

1

Theo kinh nghiệm cá nhân của tôi, tốt nhất là hãy làm theo mẫu MVC. Bằng cách này có một lớp riêng biệt đại diện cho một mô hình, tạo ra tất cả các hành động có liên quan, các bộ lắng nghe hành động, vv Các hành động được biểu diễn như các trường lớp cuối cùng, được khởi tạo trong constructor.

Ví dụ:

public class Model { 
    private final Action buttonAction; 
    ... 

    public Model(final IController controller) { 
     buttonAction = createButtonAction(controller); 
     ... 
    } 

    private Action createButtonAction(final IController controller) { 
     Action action = new Action("Action") { 
      public void actionPerformed(final ActionEvent e) { 
       // do the required action with long running ones on a separate Thread 
       controller.run(); 
      } 
     }; 
     action.set...// other initialisation such as icon etc 
     ... 
     return action; 
    } 
    ... 

    public Action getButtonAction() { 
     return buttonAction; 
    } 
} 

Quan điểm cũng được đại diện bởi một lớp riêng biệt, trong đó có mô hình như tham số constructor của nó, nơi mà các nút instantiation thực tế diễn ra. Ví dụ:

public class View extends JPanel { 
    public View(final Model model) { 
     ... 
     JButton button = new JButton(model.getButtonAction(); 
     ... 
    } 
} 

Với cách tiếp cận này khá thuận tiện để thực hiện logic hành độngĐược tạo thành một phần của lớp ẩn danh vì nó có rất ít được sử dụng lại. Tất cả các logic được đóng gói vào bộ điều khiển, do đó, các hành động phục vụ thực sự như một wrapper xung quanh cuộc gọi điều khiển được sử dụng như một mô hình cho một nút.

0

Có điều đó phụ thuộc cao vào những gì bạn đang cố gắng làm. Tôi nghĩ rằng các lớp bên trong vô danh đã nhận được một rap xấu vì hai huyền thoại. Một người không thể sử dụng lại mã ẩn danh. Và hai, rò rỉ bộ nhớ. Nhưng đây là những cách dễ dàng cố định với một cách tiếp cận đơn giản. Lưu một tham chiếu đến cá thể. Đối với mã chia sẻ, chỉ cần tạo tham chiếu đến lớp bên trong ẩn danh.

Action action = new AbstractAction("Open") {...}; 
JButton button = new JButton(action); 
JMenuItem menuItem = new JMenuItem(action); 
panel.getActionMap().put("openFile", action); 

Bây giờ bạn có thể sử dụng lại hành động đó trên nhiều thành phần. Đối với vấn đề sau này của rò rỉ bộ nhớ, bạn có thể sử dụng tham chiếu đó để hủy đăng ký nó, hoặc tùy chọn thứ hai và đơn giản hơn là WeakListeners. WeakListeners có lợi thế là không cần phải quản lý sau khi tạo ra chúng nhiều.

Đối với phong cách, tôi thấy người nghe Ẩn danh khá tiện dụng và trong một số trường hợp dễ đọc hơn khi xử lý luồng trong Swing vì nó giữ mã của bạn theo một phương thức (invokeLater, executeInBackground, v.v.). Khi bạn lắng nghe anon đại biểu cho một phương pháp dụ tôi nghĩ rằng nó tách mã mà bạn không thể đọc những gì đã xảy ra trước khi người nghe và logic liên kết với người nghe trong một màn hình. Họ có xu hướng bị tách ra và khó theo dõi hơn.

Điều cần lưu ý là nếu bạn sử dụng ActionMaps phần lớn các rò rỉ bộ nhớ sẽ biến mất đi cùng với việc nghe bàn phím. Thật không may những thứ như người nghe tập trung hoặc người nghe được đăng ký với hệ thống trung tâm vẫn là một vấn đề. (Một lần nữa WeakListeners là tuyệt vời ở đây). Và bạn đã có một nơi để giữ hành động với mọi thành phần, do đó không cần phải tạo các biến cá thể bổ sung để giữ nó. Nếu bạn cần tái sử dụng trên hai thành phần (nói trong thanh trình đơn và trong một điều khiển), hãy tạo một lớp riêng biệt.

Các vấn đề liên quan