2009-07-15 2 views
2

get 메서드를 호출 할 때마다 호출되는 메서드를 정의하는 방법이 있습니까?Java Getters : 항상 특정 메서드 실행

개체 접촉이 있고 updateLastUsed()를 설정하지 않으려합니다. 내 회원을위한 약 30 명의 Getters.

+2

개체의 필드를 업데이트하여 게터에 부작용을 도입 할 때이 기능은 약간 꺼져 보입니다. – akf

+0

죄송합니다, 나는 영어가 모국어가 아닙니다. "부작용 도입"이란 무엇을 의미하는지 설명해 주시겠습니까? –

+1

정말 게터가 30 대 필요합니까? 이것은 클래스처럼 들리지는 않지만 데이터 묶음처럼 들립니다. 연락처 데이터를 연락처 조작하는 모든 물건을 포함하는 클래스 안에 래핑 된 해시 있어야합니다 내 생각 엔. getter 클래스를 사용하면 데이터를 복사하고 복사하는 모든 컨트롤에 대한 코드를 작성해야합니다 (반향을 사용하는 경우가 아니라면 여전히 해시보다 우수합니다). 해시는 동적 바인딩을보다 쉽게 ​​사용할 수 있으므로 데이터베이스 또는 GUI 컨트롤에 필드를 복사하는 코드를 작성할 필요가 없습니다. 이렇게하는 것이 더 좋습니다. –

답변

2

나는 AOP를 제안했을하지만 J2ME 인 경우에 우리는 당신이있어 대해 얘기하고 대부분 수동으로 삽입 더 나을 30 개의 각 액세서에서 "onGetCalled()"를 호출 한 다음 해당 메서드 내에서 필요한 모든 것을 코딩합니다. 나중에 필요할 때를 대비하여 호출되는 메소드 (또는 액세스 된 속성)의 이름을 전달할 수 있습니다.

2

모든 메소드에 호출을 추가하거나 (지루한) AOP의 일부 양식 (예 : 아래 AspectJ)을 사용하여 유형의 getter를 일치시키고 updateLastUsed() 메소드를 호출 할 수 있습니다.

편집 : 여러 사람들이 30 명의 게터가 코드 냄새라고 지적하고 다른 방법을 호출하는 것이 부작용입니다. 첫 번째 진술은 공정한 지표이지만 규칙은 아닙니다. 이러한 종류의 유형을 사용하는 데는 여러 가지 이유가있을 수 있습니다. 추가 정보없이 책임을 둘 이상의 유형으로 구분할 수 있는지 확인하는 조언을 남깁니다.

부작용에 대한 다른 요점은 관련성이 있거나 다를 수 있습니다. getter 메소드에 적용 할 수있는 센스를 만드는 것은 많은 cross-cutting 관심사가 있습니다. 예를 들어 로깅, 인증 및 캐싱. 예제 메서드 updateLastUsed()는 캐싱 전략의 일부일 수 있으므로 내 의견으로는 적합하지 않은 질문에 대한 비판은 부적절합니다.

다음과 같이 AspectJ의에서 포인트 컷과 조언을 구현하는 방법의 예는 다음과 같습니다

package test; 

public aspect TestAspect { 
    /** 
    * Match all getters of test.Contact and bind the target. 
    */ 
    protected pointcut contactGetters(Contact contact) : 
     execution(* test.Contact.get*()) && target(contact); 

    /** 
    * Before execution of each getter, invoke the updateLastUsed() method 
    * of the bound target. 
    */ 
    before(Contact contact): contactGetters(contact) { 
     contact.updateLastUsed(); 
    }  
} 
+0

30 명의 게터가 이미 (지루한) 표시를 통과하고 있습니다! 당신이이 수업으로 무엇을 할지라도 악몽이 될 것입니다. 비즈니스 논리가 없으면 수업이 없어야합니다. 비즈니스 논리가 있다면 getter가 필요하지 않습니다. –

1

이것은 AOP (Aspect Oriented Programming)에서 사용되는 것처럼 보입니다. 측면을 정의

포인트 컷 @Before이를 실행 전화를 가지고 당신이 당신의 게터에 주석을 할 수 있도록 "새로운"AspectJ를 5 물건 측면의 포인트 컷을 정의하는 주석의 사용을 지원 get*

시작 아무것도 실행되는 메서드의 본문입니다.

1

이렇게하려면 AOP와 같은 것이 필요합니다. 내가 얼마나 잘 지원 J2ME에 this 이외의 지원 모르겠어요.

1

AOP 게다가, 당신은 java.lang.reflect.Proxy, 또는 바이트 코드 조작 ...

하지만 J2ME

내가 updateLastUsed를 호출하는 것이 좋습니다() 30 회 사용할 수 있습니다.

3

속성에 대해 getter에 액세스하는 대신 속성 이름을 입력으로 사용하는 하나의 일반 getter를 만들 수 있습니다. 속성이 다른 유형 인 경우 반환 유형은 Object 여야합니다.

이 일반 getter에서는 getter 및 updateLastUsed() 메서드를 호출합니다. 안전하려면 모든 재산 취득자를 비공개로 만듭니다.

1

여기가 방법입니다. 그것은 꽤 아니지만, 당신은 반복에 선호 있습니다

public class GetterTest extends TestCase { 
    private static class Thing { 
     public int accessCount; 
     private String name; 
     private int age; 

     private <T> T get(T t) { 
      accessCount++; 
      return t; 
     } 

     public String getName() { 
      return get(name); 
     } 

     public int getAge() { 
      return get(age); 
     } 
    } 

    public void testGetIncrementsAccessCount() throws Exception { 
     Thing t = new Thing(); 
     assertEquals(0, t.accessCount); 
     t.getName(); 
     assertEquals(1, t.accessCount); 
     t.getAge(); 
     assertEquals(2, t.accessCount); 
    } 
} 

물론, 내 GET()는 단지 accessCount를 증가, 당신은 다른 행동을 할 것입니다,하지만 아이디어가있다.

+0

Blackberry는 Java 1.4 만 지원하므로 일반적인 지원이 없습니다. 그러나 당신의 견본을 좋아하십시오. +1 –

+0

T를 object로 대체하고 모든 getX 메소드에서 형변환을 추가하면 제네릭없이이를 수행 할 수 있습니다. –

+0

프리미티브 (1.4에서는 오토 박싱 없음)를 제외하고. –

1

정규 표현식을 사용하여 getter 헤더에 메서드 호출을 추가합니다.

찾기 :

\0updateLastUsed();\1

이 표현은 사용하는 이클립스 3.5 (갈릴레오)를 사용하여 테스트 하였다 "교체를 모든"

\w+ get\w+\s*\(\)\s*\{(\s*)

가 교체 나는 n "찾기/바꾸기"대화 상자.

사용하는 편집기가 여러 줄 일치를 지원해야합니다 (또는 사용하도록 설정해야 함). 엠 에디터 8.05, 나는로 검색 문자열을 수정했다 :

\w+ get\w+\s*\(\)\s*\{\s*(\n\s*)

새로운 라인이 명시 적으로 일치 그래서. 대체 문자열은 그대로 유지됩니다.

1

당신은 뭔가 환상적으로 할 수 있지만 정직하게 말하면 편집자에게 매크로가 추가되어 지루한 코드를 빠르게 반복 할 수 있습니다.

나는 모든 getter가 호출 할 메서드를 만든 다음 매크로를 사용하여 메서드를 다르게해야하는 경우 호출을 만듭니다. 이 모든 작업은 한 번만 수행하면됩니다.

0

원하는 메소드를 호출하도록 객체를 프록시 처리한다고 말합니다.