-3

Please see the code below:

public class Calculator
    {
        private readonly int Number1;
        private readonly int Number2;
        private readonly int Answer;

        public Calculator(int _Number1, int _Number2)
        {
            Number1 = _Number1;
            Number2 = _Number2;
            Add();
        }

        public void Add()
        {
            Answer = Number1 + Number2;
        }

    }

The code above errors as expected because I am trying to initialise a read only field outside of the constructor. I realize that the one line of code in 'Add' could be moved to the constructor to make this work. However say Add was a very complex function.

Q1) Should the Calculator class be immutable? Q2) If the answer to Q1 is 'Yes', then would all the code for the 'Add' function go in the constructor (making it look a mess - assuming that 'Add' has more than 1 line of code - say it has 30 lines of code).

I am talking strictly from a DDD (best practice) perspective. I realise I can just move the one line of code from the Add method to the constructor in this case.

3

The name Calculator is slightly misleading, since the object contains not just the calculation operation, but also the input and the result of a single calculation. So a more fitting name would be Calculation, since the object really represent a single calculation.

Naming might seem a nitpick, but it is actually important since it makes us clarify the purpose of the class. A class representing a single calculation would naturally be immutable, since if it was changed it wouldn't be the same calculation anymore, and more importantly, if either the input or the result was changed independently, the calculation wouldn't be correct anymore! So it definitely seems sensible.

You don't need to have all the calculation logic in the constructor even if immutable. You could have Add be a static method which returns the result. It would be very nice to separate the calculation operation into a pure method.

  • I got a (silent) negative vote for a similar answer. – Constantin Galbenu Jun 15 '17 at 8:04
  • @ConstantinGALBENU, you deleted your answer to quickly for me to upvote it. Your solution is a neat one. DDD and its bloated domain models, is totally over the top of a trivial system like this. – David Arno Jun 15 '17 at 11:07
1

Immutability has nothing to do with lines of code. If the class can be immutable, then by all means, go ahead and make it immutable. Any opportunity to make a class immutable should be pursued tenaciously. If your constructor will be 100 lines long as a result, so be it. And incidentally, it is hardly ever necessary to make a method 100 lines long. You can do something like this, for example:

public class Calculator
{
    private readonly int Number1;
    private readonly int Number2;
    private readonly int Answer;

    public Calculator(int _Number1, int _Number2)
    {
        Number1 = _Number1;
        Number2 = _Number2;
        Answer = Add();
    }

    private int Add()
    {
        return Number1 + Number2; //plus 30 lines of code
    }
}
  • Thanks +1 for the return statement. This will make the constructor much cleaner. Do you think a Calculator object should be immutable? – w0051977 Jun 15 '17 at 7:22
  • From the looks of it, I can hardly see a need for this object to exist. It looks like it should just be a method of another class. But if you have to have such an object, then yes, it looks like it could be immutable. – Mike Nakis Jun 15 '17 at 7:27
  • Thanks. Why should it be part of another class? – w0051977 Jun 15 '17 at 7:39
  • Because if it consists of only what you have shown us, then it does not appear to be performing any processing after construction. It looks like it is just a container for "Answer". – Mike Nakis Jun 15 '17 at 7:45
0

In this case, Calculator seems to be more of a service, not a Value object so it should not have state thus immutability does not make sense for a stateless service.

Perhaps you need to refactor it to something like this:

public class Operand
{
    private readonly int Number;

    public Operand(int _Number)
    {
        Number = _Number;
     }

    private Operand Add(int _Number2)
    {
        return new Operand( Number + _Number2);
    }
}
  • Why did I get the -1? – Constantin Galbenu Jun 15 '17 at 7:51
  • I didn't downvote the answer. However, I think it was downvoted because you have described how to solve the problem using an enemic domain model. I am talking about a rich domain model. – w0051977 Jun 15 '17 at 8:06
  • Anemia is not applicable to value objects, only to aggregates. This is a value object problem. – Constantin Galbenu Jun 15 '17 at 8:08
  • @DavidArno Sometimes there are too many bad people on SE and I get pessimistic – Constantin Galbenu Jun 15 '17 at 11:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.