2011-01-15 6 views
8

우리는 자바 청취자를 사용하는 가장 좋은 방법이 무엇인지에 대한 직장에서 토론을했다 : 리스너 로직은 익명의 클래스를 유지해야한다, 또는 예를 들어, 별도의 방법에 있어야 여부 :Java : 익명 수신기 로직 코드는 어디에 넣어야합니까?

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

또는

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

private void buttonPressed() { 
    // code here 
} 

가독성 및 유지 관리 측면에서 권장되는 방법입니까? 나는 리스너 내부에 코드를 유지하는 것을 선호하며 너무 커지면 내부 클래스로 만든다. 여기서 코드는 다른 곳에서는 중복되지 않는다고 가정합니다.

감사합니다.

답변

4

내 스스로 부과 규칙은 : 리스너가 2 개 이상의 방법을 가지고

  1. 경우 명명 된 클래스를 만들 수 있습니다.
  2. 리스너가 10 줄을 넘는 경우 이름이 지정된 클래스를 만듭니다.

아주 간단하고 쉽게 따라 할 수 있으며 읽을 수있는 코드가 많거나 적습니다. 그러나 그 때 나는 당신의 본보기가 보여주는 것을 생각조차하지 못했다는 것을 인정해야합니다.

+0

엄지 손가락 좋은 법칙. 1 + –

+1

이름있는 내부 클래스를 사용하는 경향이 있으며, 등록하는 동안 코드 난독 화를 막을 수있는 많은 사람들이있는 경우 작은 리스너를 위해 이러한 클래스를 만드는 경향이 있습니다. 그래서 저에게는 제 3의 기준이 될 것입니다. – extraneon

1

개인적인 견해로는 "의존적"입니다. 리스너가 단일 구성 요소에만 추가되고 매우 간단하며 GUI의 필수 부분 인 경우 익명의 내부 클래스가 잘 작동합니다. 청취자가 복잡하고 여러 구성 요소에 추가되고 별도의 독립 상태가있는 경우 별도의 독립 실행 형 클래스가 더 좋습니다. 그 사이에는 사적인 내부 클래스가 있습니다. HTH.

편집 : 내 잘못입니다. 다른 질문에 대답하고있었습니다. 리스너에게 별도의 독립 실행 형 클래스를 사용할지 여부입니다. anon 내부 클래스 코드를 메소드와 비교하여 인라인으로 유지할지, 메소드에서 유지할지에 관해서는 다른 포스터에 동의합니다. 리스너 코드의 크기와 복잡성에 따라 다릅니다.

2

이 질문은 부분적으로 여기에 대한 답변 :
1) 당신이 찾을 수 있도록 쉽게 코드를 다시 사용할 수 없습니다

Is there a better practice for listeners

가 나는 또한 두 가지 이유로 익명 방법을 좋아하지 않는다 당신은 잠시 후 코드 중복이 생겼습니다. 2) 코드의 읽기가 깨졌습니다 (다른 사람들은 동의하지 않습니다 ... 개인적인 취향). 제 생각에 모든 사람이 익숙한 내부 클래스가 좋은 생각이 아니라는 5 ~ 10 행을 넘는 경우 (2 개 이상은 너무 많다고 말합니다) 동의 할 것입니다.

+0

+1 - 익명의 방법으로 코드를 재사용 할 수 없습니다. – jmort253

+0

물론 가능합니다. 버튼에서 청취자를 가져 와서 다른 청취자로 감싸 십시 오 :) 완벽한 재사용 (유지 관리는 불가능합니다 :) – extraneon

+1

물론 인스턴스를 다시 사용할 수 있습니다. 액션 액션 = 새 액션 ("이동") {...}, 버튼, 메뉴 또는 액션 맵에 지정할 수 있습니다. 인스턴스 재사용으로 재사용에 문제 없습니다. 청취자 에게서도 삭제할 수 있습니다. – chubbsondubs

1

buttonPressed() 메소드가 익명의 내부 클래스 외의 다른 곳에서 액세스해야하는 경우에는 메소드를 사용하십시오. 그렇지 않으면 코드를 actionPerformed() 내에두기 만하면됩니다.

+0

동의합니다. IDE에서 리팩터링을 통해 멋지고 쉽게 구현할 수 있습니다. – Xorty

1

내 개인적인 경험에 따르면 MVC 패턴을 따르는 것이 가장 좋습니다. 이 방법은 모든 관련 액션, 액션 리스너 등을 생성하는 모델을 나타내는 별도의 클래스가 있습니다. 액션은 생성자에서 인스턴스화되는 최종 클래스 필드로 표현되는 것이 바람직합니다.예를 들어

:보기 역시 실제 버튼 인스턴스화 발생 생성자 파라미터로 모델을 얻어 별도의 클래스로 표시되고

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; 
    } 
} 

. 예를 들어 :

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

이 방법으로 재사용 할 거의 가지고 있기 때문에 익명 클래스의 한 부분으로의 actionPerformed의 논리를 구현하기 매우 편리합니다. 모든 로직은 컨트롤러에 캡슐화되어 있으므로 액션은 컨트롤러 호출을 둘러싼 래퍼 역할을하므로 버튼의 모델로 사용됩니다.

0

예 당신이하려는 일에 크게 의존합니다. 내 생각에 익명의 내부 수업은 두 가지 신화로 인해 나쁜 랩을 얻었습니다. 하나는 익명 코드를 재사용 할 수 없습니다. 둘째, 메모리 누출. 그러나 이것들은 간단한 접근으로 쉽게 해결됩니다. 인스턴스에 대한 참조를 저장하십시오. 코드를 공유하기 위해서는 익명의 내부 클래스에 대한 참조를 작성하면됩니다.

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

이제 여러 구성 요소에서 해당 작업을 재사용 할 수 있습니다. 나중에 메모리 누수 문제가 발생할 경우 해당 참조를 사용하여 등록을 취소하거나 두 번째 및 더 간단한 옵션 인 WeakListeners를 사용할 수 있습니다. 약한 청취자는 창작 후 관리 할 필요가 없다는 장점이 있습니다.

스타일에 관해서는 Anonymous 리스너가 매우 편리하고 어떤 경우에는 코드를 하나의 메서드 (invokeLater, executeInBackground 등)로 유지하기 때문에 Swing에서 스레딩을 처리 할 때 읽기가 더 쉽습니다. anon 리스너가 인스턴스 메소드에 위임 할 때, 리스너 이전에 발생한 일을 읽을 수없는 코드와 리스너와 관련된 로직을 한 화면에서 구분한다고 생각합니다. 그들은 분리되는 경향이 있으며 따르기가 더 어렵습니다.

주의해야 할 점은 ActionMaps를 사용하면 키보드 누출과 관련된 대부분의 메모리 누수가 사라집니다. 불행히도 중앙 시스템에 등록 된 포커스 리스너 또는 리스너와 같은 것들은 여전히 ​​문제입니다. (Weak Listener는 여기에서도 훌륭합니다.) 그리고 이미 모든 구성 요소에 대한 조치를 유지할 수있는 곳이 있으므로 인스턴스 변수를 추가로 작성할 필요가 없습니다. 두 개의 구성 요소 (메뉴 막대 및 컨트롤에서 말하기)를 통해 다시 사용해야하는 경우 별도의 클래스를 만듭니다.

관련 문제