I know immutable objects are preferred to mutable objects for reasoning and maintenance. But in occasions making a class immutable have some costs, let me explain it with a simple example:
class Mutable { private int i; public Mutable(int _i) { i = _i} public void Print() // impure function { print(i); i++; // logic inside } } ... caller int i =1; Immutable m = new Mutable(i); while (true) { m.Print(); } I call it mutable because its internal state changes and Print varies on each call.
Versus.
class Immutable { private int i; public Mutable(int _i) { i = _i} public int Print() // pure function { print(i); return i; // returns its state } } ... caller int i =1; while (true) { Immutable im = new Immutable(i); i = im.Print(); // get the previous obeject's state i++; // logic outside } My actual problem (you may skip the example below)
I have a class which draws a text in a box:
class TextDrawer { private string text; private Rectangle box; public TextDrawer(_text, _box) {...} public void DrawTextInBox() { } } It is probable that the Text overflows from the box and part of it wasn't written. I should know the remaining unwritten part to draw it in a new box.(in fact I take an snapshot of the old box as a video frame and need to make a new frame for the remaining text to make a video of the text)
Now I have two options:
1- Make the TextDrawer mutable (its internal state is mutable) and DrawTextInBox a non-pure function and on each call it draws the remaining part of text in the box.
class TextDrawer { private string text; private Rectangle box; private string remaining; public TextDrawer(_text, _box) { remaining = text = _text; box = _box; } public void DrawTextInBox() { draw as you can from remaining update remaining part; } } 2- Keep the TextDrawer immutable and DrawTextInBox a pure function which returns the remaining part, then the caller should keep track of the remaining and pass it again to the TextDrawer or instantiate a new TextDrawer by the remaining text until there is nothing to write.
class TextDrawer { private string text; private Rectangle box; public TextDrawer(_text, _box) { ... } public string DrawTextInBox() { draw as you can from text; return remaining part; } } The second approach is immutable but actually shifts the responsibility of updating the remaining part outside of the class. The first approach is mutable (am i correct? because its internal state (the remaining part is mutable) but it encapsulates the logic and just need a call to DrawTextInBox to draw the remaining part.
Question: The logic of the above examples was simple but this logic could be more complex, then I don't know to extract this logic from a class in order to make it immutable or let it be mutable and have the logic inside?