Occam's chainsaw Occam's chainsaw - 25 days ago 13
C# Question

Does my code violates Single Responsibility Principle?

I'm making a console calculator as a test project. Main feature of my realisation of it is that i made digits and operators classes inherited from ITerm interface:

public interface ITerm
{
Object Value { get; }
}


Now, i'm inheriting it in IOperand and IOperator interfaces and using these intefaces in further calculations via reverse poland notation.

And now, i've been told that using this Object-type property both to keep numbers and operators is violation of Single Responsibility Principle.

private ITerm CalculatePostfixExpression(IEnumerable<ITerm> input)
{
var tempResult = new Stack<ITerm>();
foreach (var term in input)
{
if (term is IOperand)
{
tempResult.Push(term as IOperand);
}
if (term is IOperator)
{
tempResult.Push(ProceedOperation(term as IOperator, tempResult));
}
}
return tempResult.Peek();
}


This is how i am handling calculation. So there are two questions:
1. Is there some defects in my idea about storing both operands and operators in Object variable?
2. Is there some ways to improve my code? I'm considering using visitor pattern in CalculatePostfixExpression method now.

Answer

It's definitely not the most obvious approach imho.

It is also not very clear to me what you're storing in the Value property ?

The fact that you have 2 interfaces IOperand and IOperator that both derive from the same base interface ITerm, while those IOperand and IOperator do not have a is-a relation is imho a code smell at least.

This means that IOperand and IOperator are not interchangeable although they're both ITerm instances, which is a violation of the Liskov Substitution principle (one of the SOLID principles).

I have created a similar console-test project myself (reverse polish calculator console-app) a few weeks ago, which you can find on github: https://github.com/fgheysels/Calculator

Comments