2014-04-17 2 views
0

가 난 할 노력하고있어 내 주요 방법에서 작동하는 코드의 라인을 얻을 수 있습니다 :변환 유형

public interface Expression { 

public int accept(EvaluationVisitor visitor); 
} 

내 작업 클래스 : 여기

Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1), 
       new Value(7.1))); 

은 내 코드입니다

public class Operation implements Expression { 

private Expression lhs; 
private Expression rhs; 


public Operation(Value lhs, Value rhs) 
{ 
    this.lhs = lhs; 
    this.rhs = rhs; 
} 


public Expression getLHS() 
{ 
    return lhs; 
} 

public Expression getRHS() 
{ 
    return rhs; 
} 



public int accept(EvaluationVisitor visitor) { 

    return 0; 
} 



} 

값 클래스 (float 값을 나타내는) 0

추가 내와 곱하기 방법 :

public class Add extends Operation { 

private Value lhs; 
private Value rhs; 

public Add(Value lhs, Value rhs) 
{ 

    super(lhs,rhs); 

} 

public String toString() 
{ 
    return String.valueOf(lhs.getValue() + rhs.getValue()); 
} 


public Value add() 
{ 
    return new Value(lhs.getValue() + rhs.getValue()); 
} 

} 




public class Multiply extends Operation{ 

private Value lhs; 
private Value rhs; 



public Multiply(Value lhs, Value rhs) 
{ 
    super(lhs,rhs); 
} 


public String toString() 
{ 
    return String.valueOf(lhs.getValue() + rhs.getValue()); 
} 


public Value mul() 
{ 
    return new Value(lhs.getValue() * rhs.getValue()); 
} 
} 

여기 다시 코드의 라인이다 : 나는 일을 얻으려고 코드 내 라인에서

Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1), 
        new Value(7.1))); 

, 내가 찾고 싶어요 Multiply 객체가 값이 될 수있는 방법을 인수로 사용할 수 있습니다. Value 객체를 반환하는 내 메서드를 호출하여 객체를 만든 다음 배치 할 수 있지만 생성자는 객체의 상태가 유효하도록 객체를 설정해야합니다. 이 문제를 해결할 수있는 방법이 있습니까?

+2

왜 코드에서 쓸모없는 줄 바꿈을 많이 사용합니까? –

답변

1

값과 연산자 식을 무차별로 처리 할 수 ​​있도록 인터페이스를 최대한 활용해야합니다. 지금은 그 일을하지 않고 있습니다. 예를 들어, Operation은 인수로 Value 두 개를 취하고 Expression으로 저장합니다.

Operation의 서브 클래스가 lhsrhs이라는 중복 구성원을 선언하고 있다는 문제점도 있습니다. 아마도 여러분은 이미 AddMultiply에서 메서드를 호출하려고하면 null 포인터 예외가 발생한다는 사실을 이미 알고있었습니다.

public interface Expression { 
    public Value evaluate(); 
} 

public class Value implements Expression { 
    private final float floatValue; 

    public Value(float floatValue) { 
     this.floatValue = floatValue; 
    } 

    public float floatValue() { 
     return floatValue; 
    } 

    @Override 
    public Value evaluate() { 
     return this; 
    } 
} 

public abstract class BinaryOperator implements Expression { 
    protected final Expression lhs, rhs; 

    public BinaryOperator(Expression lhs, Expression rhs) { 
     this.lhs = lhs; 
     this.rhs = rhs; 
    } 
} 

public class Add extends BinaryOperator { 
    public Add(Expression lhs, Expression rhs) { 
     super(lhs, rhs); 
    } 

    @Override 
    public Value evaluate() { 
     return new Value(
      lhs.evaluate().floatValue() 
       + 
      rhs.evaluate().floatValue() 
     ); 
    } 
} 

public class Multiply extends BinaryOperator { 
    public Multiply(Expression lhs, Expression rhs) { 
     super(lhs, rhs); 
    } 

    @Override 
    public Value evaluate() { 
     return new Value(
      lhs.evaluate().floatValue() 
       * 
      rhs.evaluate().floatValue() 
     ); 
    } 
} 

지금 당신이 할 수있는

32.309998 (정답)를 출력
Expression exp = (
    new Add(new Value(3.2f), new Multiply(new Value(4.1f), new Value(7.1f))) 
); 
System.out.println(exp.evaluate().floatValue()); 

:

여기에 약간의 재 설계이다.

evaluate이 단순히 float을 반환하면 위의 재 설계를 더 단순화 할 수 있습니다.

+0

방문자 패턴을 적용 할 수있는 방법이 있습니까? 나는 디자인을 좋아하지만 방문자 변수와 메소드 (accept())를 완전히 없앤다. – iii

+0

방문자 패턴은 런타임 의사 결정을위한 것입니다. 여기서 어떻게 적용되는지 모르겠습니다. 그것의 사용법은 단지 placeholder (아무 조치도 취하지 않고 단지 0을 반환하기 때문에) 나는 당신에게 무엇을 말해야할지 모른다. 당신이 그것을 사용하려고 시도했는지 확실하지 않습니다. – Radiodef

0

생성자는 Value 객체를 가지고 있지만 Multiply 확장되지 않습니다 Value

0

당신이 작업에 값을 추가하고있다. 당신이 정말로하고 싶은 것은 값에 값을 추가하는 것입니다 (후자는 연산의 결과입니다). 당신이 다음을 수행해야합니다 그래서 : 또는

Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1), 
      new Value(7.1)).mul()); 

을, 당신은 당신의 Operation 클래스 Value를 확장하고 곱셈을 수행 할 수 Multiply 클래스 내부의 getValue() 메소드를 오버라이드 (override)을 수행 할 수 Add 클래스 마찬가지로 (값을 반환 할 수 추가하고 값을 반환).