2011-09-14 4 views
4

리플렉션을 사용하여 동적 IF 문을 작성할 수 있습니까?동적 IF 문 작성 방법은 무엇입니까? 반사?

BeanShell (예 : Dynamic if statement evaluation problem with string comparison)을 사용하여 예제를 보았지만 BeanShell 없이도 할 수 있는지 알고 싶습니다. 또한 필자의 요구에 맞게 몇 가지 예를 지적하고 싶습니다.

기본적 난 형태의 성명이하십시오 운영자 B.

A 및 B 번호 (복식 또는 INT)로 또는 문자열이 될 수 있지만, 항상 A는 B. 오퍼레이터 수있는 바와 같은 유형이다! >, =, ==,> =,>, < =, <, 심지어 다른 행위는 자신의 클래스를 통해 정의 될 수 있습니다. 왜 내가 반사를 사용하는지 다른 이유는 문자열을 가져 와서 리플렉션을 사용하여 적절한 방법.

유사 콘텐츠가 너무 많아서 사용자 생성 입력에 따라 지속적으로 변경되기 때문에 "if"및 "switch"분기를 피하기 위해 (꼭)해야합니다.

당신이

public interface MyComparator 
{ 
    public boolean matches(String operator); 
    public boolean compare(String a, String b); 
} 

같은 인터페이스 그럼 당신은 당신이 모든

public class MyEquals implements MyComparator 
{ 
    @Override 
    public boolean matches(String operator) 
    { 
    return "==".equals(operator); 
    } 

    @Override 
    public boolean compare(String a, String b) 
    { 
    return a.equals(b); 
    } 
} 

같은 인터페이스를 구현하려는 얼마나 많은 클래스를 만들 수 있도록이 같은를로드 할 수

+4

가 왜이 작업을 수행 할 수 있습니까? 왜 전략 디자인 패턴을 사용하지 않습니까? – Raedwald

+2

IF를 동적으로 생성하는 것은 당신이하는 일과 함께 할 수있는 방법이 아닙니다. – Steve

+0

저는 문자 그대로 사용자 정의 스크립트 언어에서 조건을 읽고 있습니다. 형식은 functionA 연산자 functionB입니다. 사업자는 현재 제한적이지만 성장할 수 있습니다. 나는 문자열을 읽고 어떻게 든 표현을 평가할 수 있기를 원합니다. – rciafardone

답변

1

반사가 도움이되지 않습니다. Reflection은 코드 구조 (클래스, 메소드, 속성)에 대한 정보를 제공하지만 기존 코드를 변경하고 업데이트 할 수는 없습니다.

새로운 코드를 생성하지 말고 사용자가 입력 한 내용에 따라 앱의 동작을 변경하는 대신에 새로운 코드를 생성 해보세요.

나는 당신이하려는 것을 정확하게 모른다. 옵션을 좁히는 데 도움이되는 사용자 입력 및 예상되는 동작의 예를 게시하십시오.

  • 는 사용자가 값 텍스트 필드로, 피연산자의 시간을 선택하는 데 도움이되는 사용자 인터페이스 및 운영자에 대한 드롭 다운 상자 유무 :하지만 여기 작업에서 당신을 도움이 될 몇 가지입니다. 간단한 해결책이지만 사용자 인터페이스에 복잡성을 줄 수 있으므로 권장하지 않습니다.
  • 표현식에 대한 파서를 작성하십시오. 이 간단한 언어 (A 연산자 B)에 대한 간단한 파서를 작성하는 것은 적절한 시간 내에 수행 가능해야합니다.
  • 도메인 특정 언어. 응용 프로그램 사용자가 응용 프로그램에서 해석하고 일부 방식으로 응답하는 일부 스크립트를 작성할 수 있습니다. 간단한 비교로 구성된 DSL을 상상할 수 있습니다. 결과는 앱의 동작에 영향을 미칩니다. Groovy를 살펴 보겠습니다.이 사용 사례에 적합한 언어입니다.
+0

고맙습니다. 다른 사람들은 내가 피하고 싶었던 버전을 제공했기 때문에 내가 원하는 것을 오해했습니다. 즉, 운영자 자신을 하드 코딩하는 것입니다. 스크립트 언어에서 적절한 java 구문을 사용하여 문자열을 만들고이 게시물에서 BeanShell을 사용하여 표현식을 평가하는 방법이 있는지 알고 싶었습니다. http://stackoverflow.com/questions/2838801/dynamic-if- 진술 - 문제 - 문자열 - 비교와 문제. 문제는 BeanShell 솔기가 죽은 것입니다. 나는 그것을 내 프로젝트에 추가하고 싶지 않습니다. 사실, 당신의 총알 포인트 1과 2는 이미 내 프로그램의 일부입니다 : P – rciafardone

+0

반사 부분은 BeanShell 트레드에서 내가 사용했던 링크입니다. 그리고 무엇을 사용 하느냐에 따라 apropiate 메소드를 호출하는 프로그램의 일부분으로 사용합니다 스크립트 언어는 말한다. 예 : Count (a.value, set)> = value (4). Count는 set에 몇 개의 a.value가 있는지를 단순히 찾고 값을 반환합니다. 리플렉션을 사용하여 스크립트 파일을 구문 분석 한 후 적절한 메소드를 호출합니다. – rciafardone

1

:

Class compClass = Class.forName(classname); 
MyComparator comp = (MyComparator)compClass.newInstance(); 

사용할 수있는 모든 연산자 목록을 준비하고 그 전후로 반복 할 수 있습니다 n 특성 파일에 구성된 운영자 목록이 있습니다.

+0

이 문제는 연산자를 하드 코딩하는 것을 의미하는데, 이는 내가 원한 각각의 경우에 대해 큰 스위치 (연산자)를 만드는 것과 거의 같습니다. 나는 심지어 각 클래스의 int ID를 가진 클래스 연산자를 가지고 있지만 더 유연한 솔루션을 찾고있었습니다. – rciafardone

+0

누가 사업자 행동을 정의 할 것입니까? 당신 (프로그래머)이나 사용자입니까? – Maxx

+0

\ @Maxx : 훌륭한 질문입니다. 함수의 첫 번째 배치는 나 (프로그래머)에 의해 정의 될 것입니다.하지만 사용자가 만든 Function 클래스를 확장하고 자신의 코드를 추가하려면 문을 열어두고 싶습니다. 기능적으로 클래스를 작성하고, 구성 파일의 이름을 추가하며, 새 기능을 사용하여 조건을 작성할 수 있습니다. 그러나 나는 덜 야심적으로 사양을 바꿀 것이라고 생각한다. 나는 시간이 없다. – rciafardone

3

주어진 입력에 대해 올바른 연산자를 반환하는 팩터 리를 생성 할 수 있습니다.

public class OperatorFactory { 
    private static final Map<String, Operator<?>> OPERATORS = new HashMap<String, Operator<?>>(); 

    static { 
    OPERATORS.put("<Number", new LessThanNumOperator()); 
    OPERATORS.put("==Number", new EqualToNumOperator()); 
    OPERATORS.put("<String", new LessThanStringOperator()); 
    ... 
    } 

    public static Operator<?> getOperator(String someUserSpecifiedOp, Class<?> paramType) { 
    String key = someUserSpecifiedOp; 
    if (Number.class.isAssignableFrom(paramType)) { 
     key += "Number"; 
    } else if (String.class.isAssignableFrom(paramType)) { 
     key += "String"; 
    } 
    return OPERATORS.get(key); 
    } 
} 

public interface Operator<T> { 
    public boolean execute(T lhs, T rhs); 
} 

public class LessThanNumOperator implements Operator<Number> { 
    public boolean execute(Number lhs, Number rhs) { 
    return lhs.doubleValue() < rhs.doubleValue(); 
    } 
} 

그리고 그것을 사용 :

OperatorFactory.getOperator(userDesignatedOperation, lhs.getClass()).execute(lhs, rhs); 
+0

팩토리 및 전략 디자인 패턴을 모두 사용한다는 점에 유의하십시오. –