development

Java에서 Mixin을 구현 하시겠습니까?

big-blog 2021. 1. 7. 20:34
반응형

Java에서 Mixin을 구현 하시겠습니까?


Java 6을 사용하여 어떻게 mixin을 구현할 수 있습니까? Ruby에서는 매우 쉽고 가능합니다. Java에서 어떻게 유사하게 만들 수 있습니까?


이를 위해 CGLIB사용할 수 있습니다 . 클래스 믹스 인은 여러 인터페이스 / 개체로부터 위임 동적 클래스를 생성 할 수있다 :

static Mixin    create(java.lang.Class[] interfaces,
                        java.lang.Object[] delegates)
static Mixin    create(java.lang.Object[] delegates)
static Mixin    createBean(java.lang.Object[] beans) 

객체 구성을 사용한다고 말하고 싶습니다. 새로운 기능을 추가하고 싶을 때마다 다른 객체를 클래스에 구성원으로 작성하십시오. 모든 혼합 클래스를 동일한 유형으로 만들려면 각 요소가 다른 모든 요소로 구성된 구성원 객체로 배열을 사용하고 특정 요소에 전달할 수 있습니다.


기본 방법

나는 질문이 Java 6이라고 말한 것을 알고 있지만 Java 8에서는 꽤 괜찮은 대안 인 default methods가 있습니다.

인터페이스 메서드의 '기본'구현을 추가 할 수 있으므로 인터페이스를 구현하는 모든 클래스를 중단하지 않고 새 메서드를 추가 할 수 있습니다.

믹스 인이 상태를 필요로하지 않는 한 인터페이스에 코드를 작성할 수 있습니다. 그런 다음 클래스가 원하는만큼 이러한 인터페이스를 구현할 수 있으며 붐이 발생 하면 mixins가 있습니다.

이것은 시스템의 남용입니까? 조금 있지만 상태가 없기 때문에 다중 상속 문제가 발생하지 않습니다.

물론 이것이이 접근 방식의 가장 큰 단점이기도합니다.


Java는 단일 상속 만 지원하므로 불가능합니다. WP : Mixin을 살펴보십시오 .

편집 : 인터페이스에 대한 주석 때문에 : 믹스 인의 멋진 점은 조합의 코드를 작성하지 않고도 조합 할 수 있다는 것입니다. 인터페이스를 사용하면 조합의 기능을 직접 구현해야합니다 (확장 할 수있는 하나의 클래스 제외)!


가장 간단한 방법은 정적 가져 오기를 사용하는 것입니다. 클래스의 일부인 것처럼 보이지만 실제로는 다른 곳에 정의 된 코드 재사용을 허용합니다.

장점 :

  • 정말 쉽습니다
  • 원하는만큼 정적 가져 오기를 '혼합'할 수 있습니다.

단점 :

  • 정적 메서드는 'this'에 액세스 할 수 없으므로 수동으로 전달해야합니다.
  • 상태 없음 : 정적 메서드는 자체 인스턴스 필드를 가질 수 없습니다. 고유 한 정적 필드 만 정의 할 수 있으며 정적 메서드를 호출하는 모든 개체에서 공유됩니다.
  • 클라이언트 클래스에서 공용 메서드를 정의 할 수 없습니다 (코드가 혼합 된 클래스). Ruby에서 mixin을 가져 오면 실제로 이러한 공용 메서드가 클래스의 공용 메서드로 정의됩니다. Java에서는이 경우 상속이 더 나은 솔루션이 될 것입니다 (여러 클래스를 확장 할 필요가 없다고 가정).

예:

import static my.package.MyHelperUtility.methodDefinedInAnotherClass;

public class MyNormalCode {
    public void example() {
        methodDefinedInAnotherClass();
    }
}

Ruby 믹스 인은 Java 추상 클래스와 동일하다는 점에서 Java에서 믹스 인을 구현할 수 없습니다. 인터페이스를 사용하고 따라서 믹스 인에 코드를 전혀 정의하지 않으면 가까이 다가 갈 수 있지만 Ruby 믹스 인과 동일한 동작을 직접 달성 할 수는 없습니다.


방금 가로 질러 : http://www.berniecode.com/blog/2009/08/16/mixins-for-java/


업데이트 : Qi4j는 이제 Apache Polygene, https://polygene.apache.org입니다.

Qi4j의 Mixins 정의는 기본 클래스로 시작하지 않기 때문에 매우 독특합니다. 극단적으로 가면 응용 프로그램이 구축되는 방식에 대한 완전히 새로운 패러다임이 나타나고이를 복합 지향 프로그래밍이라고합니다. Composite는 '객체'와 동일하며 Mixins가 함께 연결되어있을뿐만 아니라 Constraints (유효성 검사), Concerns (주변 조언) 및 SideEffects (메소드 결과를 변경할 수 없음)도 있습니다.

그래서 Qi4j는 매우 강력한 Mixin 스토리를 가지고 있다고 생각합니다. 믹스 인은 '유형화'또는 '일반'이 될 수 있으며 공개 (복합 외부에서 액세스 가능) 또는 순수 개인 (복합 내부) 일 수 있습니다. Qi4j는 속성이 무엇인지 강력하게 정의하고, 스토리지 구현을 도메인으로 유출하지 않는 기본 제공 지속성을 유지합니다 (주의 : Qi4j가 도메인에 유출 됨). 그리고 영구 엔티티가 그림에 들어 오면 연관에 대한 강력한 정의도 필요합니다 (Qi4j에 포함됨).

좋은 개요는 http://www.qi4j.org/state-modeling.html참조 하십시오 .

Qi4j에서는 Mixins에만 상태가 있습니다. Constraints / Concerns / SideEffects는 state를 가질 수 없습니다 (만약 그들이 private mixin을 참조해야하는 경우).

Qi4j에서 컴포지트를 정의하려면 유형 자체에서 구조적으로 수행하거나 런타임 모델이 생성 될 때 부트 스트랩 시간에 수행 할 수 있습니다.

구조적으로;


@Mixins({PetrolEngfineMixin.class, FourWheelsMixin.class})
public interface Car extends HasEngine, HasWheels, EntityComposite
{}

부팅시;


public interface Car
{}

public class CarModuleAssembler implements Assembler { public void assemble( ModuleAssembly module ) { module.entities( Car.class ) .withMixins( PetronEngineMixin.class, FourWheelsMixin.class ); } }

그러나 이것은 Qi4j의 기능 표면을 만지고 있습니다.


http://code.google.com/p/javadude/wiki/AnnotationsMixinExample을 살펴보십시오 .

내가 만든 주석 세트를 사용하고 있습니다.

참고 : 일부 API 손상을 포함하여 주석에 대한 주요 업데이트를 작업 중입니다. 앞으로 몇 주 안에 새 버전을 출시 할 계획입니다.


자바에서 가짜 믹스 인 : http://jonaquino.blogspot.com/2005/07/java-mixin-pattern-or-faking-multiple.html


AspectJ ITD를 사용하여 이제 Java (예 : 5,6,7)로 Mixins를 수행 할 수 있습니다 . 물론 Java 8은 방어자 방법으로 더 나은 기능을 추가 할 것입니다.


찾고있는 믹스 인의 기능이 정확히 무엇인지 확실하지 않지만 대부분 데코레이터 패턴을 사용하여 수행 할 수 있습니다.

http://en.wikipedia.org/wiki/Decorator_pattern#Java


나는 생각 나는 완전히 모르겠지만 ... 당신의 질문에 대답 할 수 있는지 나는 믹스 인은 아직 이해 ...


예, 자바에서 mixins 접근 방식을 구현하는 가장 간단하고 편리한 방법은 정적 메소드를 포함하는 일부 클래스에서 정적 가져 오기를 사용하는 것입니다.


Java 7에이를 제공하는 방법을 탐색하고 있습니다. 첫 번째 작업은이 기사에 표시된 예제를 사용하는 것입니다.

Java 6에서 작동해야하며 위의 다른 주입 옵션과 유사합니다. C # 및 Ruby에서 Mixins에 대한 경험을 바탕으로, 단순히 에뮬레이트하거나 가짜가 아닌 믹스 인 구현을 목표로해야합니다.

또 다른 모델은 Jackson 과 함께 사용되는 모델입니다 .

새로운 Java 8 릴리스를 사용할 수 있다면, 예를 들어 시험판 모드에있는 경우 도움이 될 수 있습니다.

'노력 필요 가상 확장 방법, 사용 할 수-A '믹스 인을. 그래서 제 생각에는 아직 초기 단계이며 첫 번째 링크에서 제공하는 깔끔한 접근 방식 (또는 유사)을 선호합니다.


'Mixin'이라는 용어는 aspect 지향 프로그래밍 운동에서 Java 용어 'aspect'와 동일하지 않습니까? AspectJ는 아마도 볼만한 가치가 있습니다.


오래된 질문에 대한 답변.

Apache Zest를 살펴 보았습니다. 나뿐일지도 모르지만 예제가 조금 번거 롭다는 것을 알았습니다. 그리고 나는 요점을 이해하지 못했습니다. 또 다른 대안은 개체 팀일 수 있습니다.

하지만이 저장소를 살펴볼 것을 제안합니다.

https://github.com/Mashashi/javaroles/

원하는 작업을 부분적으로 다룰 수 있습니다. 간단 해 보입니다.

다음은 그 예입니다.

역할에 대한 인터페이스 정의 :

public interface Human {
String hello(); 
String die(String age);  
String eat();
String dance();
}

public interface Monkey {String hello(); String eat();}

강체 유형 AnimalRoles 정의 ...

public class AnimalRoles implements Human, Monkey{

public static final String HALLO = "Default hallo";
public static final String DIE = "Default they kill me...";
public static final String EAT = "Default eat...";

@ObjectForRole public Human human;

@ObjectForRole public Monkey monkey;

public AnimalRoles(Human human, Monkey monkey){
    this.human = human;
    this.monkey = monkey;
    if(this.human!=null){
        ((Portuguese)this.human).core = this;
    }
}

@Override
public String hello() {
    return HALLO;
}

@Override
public String die(String age) {
    return DIE+age;
}

@Override
@TurnOffRole
public String eat() {
    return EAT;
}

@Override
public String dance() {
    return "Just dance";
}

public String notInRole(){
    return "Oh oh";
}
}

클래스 역할 Bonobo 정의 중 ...

public class Bonobo implements Monkey{
public Bonobo() {}

@Override
public String hello(){
    return "Ugauga";
}

@Override
public String eat() {
    return "Nhamnham";
}

}

수업 역할 포르투갈어 정의 중 ...

@RoleObject(types = { AnimalRoles.class })
public class Portuguese implements Human{

public static final String HALLO = "Hey there";
public static final String DIE = "They killed me";
public static final String EAT = "Eating boiled pork now";

public AnimalRoles core;

public Portuguese() {}

@Override
public String hello() {
    return HALLO;
}

@Override
public String die(String age) {
    return DIE+age;
}

@Override
public String eat() {
    return EAT;
}

@Override
public String dance() {
    return core.dance()+" modified!";
}

}

테스트 실행 중 ...

new RoleRegisterComposition().registerRools();
AnimalRoles a = new AnimalRoles(new Portuguese(), new Bonobo());
System.out.println(a.hello());
System.out.println(a.dance());

인쇄합니다 ...

"Hey there"
"Dance modified!"

cglib를 사용하여 순수 자바에서 믹스 인을 만드는 방법에 대한 내 작은 데모 프로젝트를 살펴보십시오. 주로 프록시 생성기에 대한 호출입니다. 이것은 동맹입니다. 이 예제에는 프록시를 인스턴스화하는 방법을 보여주는 junit 테스트 케이스가 포함되어 있습니다.

https://github.com/literadix/JavaMixins

참조 URL : https://stackoverflow.com/questions/587458/implement-mixin-in-java

반응형