2010-06-24 10 views
2

의 내가있다, 클래스 Unit과 서브 클래스 UnitA, UnitB, UnitC자바 반사 나쁜 패턴?

모든 장치 클래스에는 다음과 같은 생성자 (이 예에서 RTS의 단위) 유사한 클래스가 많이 있다고 가정 해 봅시다 (포함 단위) 매개 변수를 포함

public class UnitX { 
    public UnitX(FileReader fr) { 
     ...read parameters for constructing the unit... 
    } 
} 

내 파일 형식을

UnitX params 
UnitY params 
.... 

및 파일에있는 모든 단위의 목록을 작성하는 것은 내가 파일에서 개체를 만들 때 매우 자주이 패턴을 사용하는 것이 실현

Class[] params = {FileReader.class}; 
while(fr has more to read) { 
    String unitType = fr.getString(); 
    Unit u = (Unit) 
java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params); 
    Unit u = (Unit)constr.newInstance(new Object[]{fr}); 
    list.add(u); 
} 

같은 동안 루프가 될 것입니다. 제 질문은 이것이 나쁜 패턴입니까? 이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

2

코드 자체는 문제가 없습니다. 생성자는 전통적인 코드화 된 인터페이스의 일부가 될 수 없으므로 다음으로 가장 좋은 것은 일관된 반사 인터페이스입니다.

그러나이 코드를 여러 곳에서 반복한다면 그다지 좋지 않습니다. 이를 파일에서 유닛 이름을 제공하는 일종의 공장이나 빌더에 집중시키고, 해당 유닛에 정의 된 매개 변수와 함께 UnitFactory를 통해 제공된 매개 변수로 유닛을 인스턴스화하는 핸들러 구현과 짝을 지을 수도 있습니다. UnitFactory는 리플렉션을 사용하여 명명 된 Unit을 인스턴스화하고 매개 변수를 제공합니다.

이렇게하면 재사용이 가능하며 파일을 인스턴스화와 인스턴스화 방법에서 분리 할 수 ​​있습니다.

+0

유닛 클래스 자체가 파일러 리더/라이터에 상태를 읽고 쓰는 방법을 제공하는 것이 더 합리적이지 않습니까? 추가 단위 클래스는 내 공장 클래스에서 변경을 요구하지 않습니다. –

+0

네, 그럴 수도 있습니다. 다만, 당신이 책임감을 혼합하고 있다는 것을 알아 두십시오. 그러나 당신이 알고있는 한 그것이 의미하는 바는 괜찮습니다. 단위 테스트는 일반적으로 의도적으로 단순하므로보다 직접적이며 결합 된 방법이 더 적합하기 때문에 종종 더 명확합니다. – mdma

0

이것은 간단한 직렬화입니다. 나는 이것이 당신의 목적에 맞는 것이라면 좋다고 말하고 싶습니다.

1

귀하의 구현이 괜찮다고 생각합니다. 다른 방법 : 텍스트 파일은 DSL (도메인 특정 언어)의 간단한 형식입니다.

더 동적 인 jvm 호환 언어로 전환 할 수 있습니다. groovy (내가 좋아하는 ;-)), javascript (Rhino, ...), BeanShell, jython 등과 같은 동적 언어는 도메인 특정 언어 (DSL)를 구현하는 데보다 쉽게 ​​사용할 수 있습니다. 좀 더 복잡한 DSL의 경우 XText 프로젝트를 살펴볼 수 있습니다.

3

factory pattern의 경우 그건 :

java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params); 
Unit u = (Unit)constr.newInstance(new Object[]{fr}); 

이 공장은/다른 경우 생각의 다음

Unit u = UnitFactory.create(unitType, fr); 

에 목록이되어 변경 될 수 있습니다.