0

I was doing some reading here about creating immutable object in java and I was wondering, is it okay to create a mutable object in certain situations?

For example, let's say we were creating a ping-pong game in C#, obviously, we would have a class that represents a ball, and the two paddles, would you write the ball class like this:

 class Ball
    {
        private readonly int xPosition;
        private readonly int yPosition;
        private readonly int ballSize;
        private readonly string ballColor;

        public Ball(int x, int y, int size, string color)
        {
            this.xPosition=x;
            this.yPosition=y;
            this.ballSize = size;
            this.ballColor = color;
        }

        public int getX
        {
            get
            {
                return this.xPosition;
            }
        }
        //left out rest of implementation.

or like this:

    class Ball
    {
        private int xPosition;
        private int yPosition;
        private int ballSize;
        private string ballColor;

        public Ball(int x, int y, int size, string color)
        {
            this.xPosition=x;
            this.yPosition=y;
            this.ballSize = size;
            this.ballColor = color;
        }

        public int getX
        {
            get
            {
                return this.xPosition;
            }

            set
            {
                this.xPosition = value;
            }
        }


    }
}

In a situation where our object(ball) can change position, size(smaller or larger depending on level) and color, wouldn't it be better to provide a setter property? In this case making it mutable makes sense? How would you approach this?

Community
  • 1
  • 1
  • 1
    If the ping pong ball were to float in the air the same way as bricks don't then it would be ok. In other-words, if it doesn't move make it immutable. But a non-moving ping pong ball is not much fun so maybe mutable is the way to go, complete with setters. :) –  Jul 13 '15 at 15:12
  • So my second approach is the logical one, correct? –  Jul 13 '15 at 15:13

1 Answers1

4

If you are using c#, you do not need to go thru the overhead of creating separate fields to make objects immutable. Instead you can do something like this -

    class Ball
    {
         public Ball ( int x, int y, int size, string color) 
         { ... }
         public int XPos {get; private set; }
         public int YPos {get; private set; }
         public int Size {get; private set; }
         public string BallColor {get; private set; }
    }

This way, you can still write methods in the class to mutate the properties but nothing outside of the class can change their values.

KnightFox
  • 3,132
  • 4
  • 20
  • 35
  • AH, exactly what I had in mind, but, just wanted to make sure. Answer accepted! –  Jul 13 '15 at 15:23
  • How does it address _"In a situation where our object(ball) can **change position, size(smaller or larger depending on level) and color**, wouldn't it be better to provide a **setter** property? In this case making it mutable makes sense? How would you approach this?"_. Would have been nice perhaps to simply `ball.XPos = ...` –  Jul 13 '15 at 15:24
  • You can always add functions in Ball class like Move(int x, int y) that allow you to move the ball to a certain position. There can be custom validation of inputs etc in these functions before the values of the properties are actually set. That way to you can restrict how other classes interact with a Ball instance – KnightFox Jul 13 '15 at 15:27
  • @KnightFox Yes, `Move()` would suffice, though the validators could be in the setter. –  Jul 13 '15 at 15:29
  • @MickyDuncan - Correct, validations in the setter would check to make sure that the object has the correct values, and then we call the Move method –  Jul 13 '15 at 15:30
  • 1
    Nice. Here have a +1 –  Jul 13 '15 at 15:31
  • @MickyDuncan - The setters approach is nice when there is not relationship between the individual properties. I am vary of setters in such cases when there are limitations on X based on values of Y. Consider the ping pong example and the virtual space around the net. If the center of the net is set to be center of the coordinate space, the ball can be placed anywhere on X =0 or Y =0 lines, however, it cannot be placed at (0,0) because that space is occupied by the net. If you use the setter approach, ball.X=0 will go thru, ball.Y=0 will throw exception. Move(0,0) however can validate that. – KnightFox Jul 13 '15 at 15:33
  • @KnightFox - The private setter could make sure that the ball as a proper start position, and the move method will handle the ball while it moves, make sure it doesn't go out of bounds, and in the proper area. –  Jul 13 '15 at 15:37
  • @Nexusfactor - Remember also that Move(0,0) or Move (1,1) cant be done if the ball size is 3 and you have a restricted net or area. In simple words not going thru walls or flying without gravity or something like that. – mijail Jul 13 '15 at 15:42
  • @mijail - I understand that, and the move method would make the proper checks before doing anything. I'm just saying, the setter would give the ball a start position, color, and size. The move of course would have it's own checks to make sure it stays within the rules of the game. –  Jul 13 '15 at 15:45