2012-11-23 1 views
2

Groovy에서 @Mixin 주석을 사용하고 싶습니다.이 메소드는 내가 원하는 것만 빼고는 원하는 방식으로 처리합니다. 또한 private 메소드와 필드를 혼합합니다.Groovy @Mixin에 대한 솔루션 찾기. 캡슐화를 중단하지 마십시오.

class A { 
def private fooA() { 
     println("A") 
    } 
} 

@Mixin(A) 
class B { 
    def fooB() { 
     println("B") 
    } 
} 

지금이 코드

static main(args) 
{ 
    def b = new B() 
    println(b.fooA()) 
    B.metaClass.fooA = {throw new MissingMethodException()}; 
    println(b.fooA()) 
} 

그것은 먼저 개인 방법 A.fooA 및 인쇄 "A"를 호출을 실행합니다. 그런 다음 private 메소드가 제거되고 클래스 A에서 혼합 된 클라이언트 클래스 B가 호출 할 수 없습니다. 처음부터 일을하고 싶습니다.

지금 제 질문은 일반적인 방법으로 어떻게 할 수 있습니까? @Mixin 주석을 확장 할 수 있습니다. 문제는 Groovy에 익숙하지 않아 AST 변환을 작성하는 방법을 찾는 데 많은 정보가 없다는 것입니다. 그것에 대한 전체 장을 가진 새로운 Groovy in Action 서적은 아직 나오지 않았습니다.

대신 @Delegate를 사용할 수 있지만 위임 된 클래스의 변수를 선언해야합니다. 이것은 내가 원하는 것이 아닙니다. 나는 단지 내 물건을 사용하여 개발자에게 @Mixin을 사용하여 자신의 수업에 주석을 달아서 내 재료에 혼합 할 수 있다고 말하면 좋을 것입니다. 그리고 내 클래스의 private 메소드와 필드는 클래스의 내부 코드를 깨뜨린 사용자가 호출 할 수 없다는 것을 확신 할 수 있습니다.

누구에게 어떤 방향으로 시도해야합니까? 고마워, 올리버

답변

2

나는 Groovy의 강력한 초점이 아닌 것을 생각해 보았다. 비공개 회원을 숨기기위한 지원은 일반적으로 issues입니다.

구체적인 경우 새 버그 (?)가 발생할 수 있습니다. 주위를 두드리는 것은 @Mixin에 대한 AST 변환이 MixinInMetaClass.mixinClassesToMetaClass()에 도달하는 코드를 호출하는 것처럼 보입니다. 이것은 비공개 메소드를 대상 메타 클래스 (클래스 B의 메타 클래스)로 복사하지 않으려 고합니다. 그들은 당신의 b.metaClass에있는 방법의 목록에 나타나지 않습니다.

존재하지 않는 속성을 사용하거나 b에 존재하지 않는 방법을 호출하려고 시도 할 때까지 b.fooA()으로 전화를 걸면 (어떤 식 으로든) 작동합니다. (또는 전화 b.metaClass.initialize()). 그러면 불만이 누락 될 것입니다. fooA().

Groovy로 작업하기 위해 액세스 수정자를 얻으려고 너무 많은 에너지를 쏟아 부 었는지 모르겠지만, 그 길을 계속 지키고 있다면 클래스에 대한 초기화 코드를 작성해야한다고 생각합니다. 위에서 한 것처럼 수행하거나 initialize()으로 전화하거나 위에 언급 한 것처럼 불량 재산으로 전화하십시오. 이 코드 중 일부를 자신의 ASTTransformation 클래스에 넣으려고 시도 할 수도 있지만 시도하지는 않았습니다. source을 잡고 org.codehaus.groovy.ast.MixinASTTransformation을 살펴볼 수 있습니다.

+0

안녕하세요 Brian, 답변 해 주셔서 감사합니다. 글쎄, 자동 완성 선택 목록이 "f"를 입력 한 후 IDE (IDEA를 사용)에서 팝업 될 때. private 메소드 fooA는 선택 가능한 옵션으로 나열되지 않습니다 (그러나 fooB는 선택 사항입니다). B의 인스턴스에서 여전히 fooA를 호출하는 개발자는 이전에 일종의 경고를 받았습니다. 아마 충분하다. 결국, 나는 이전의 "모든 유형의 안전"세계에 너무 많이 익숙하지 않다 ;-). – OlliP