Semmi baj nincs a mutabilitással, anélkül nem is létezne kód.
Csak éppen korlátot kell szabni a mutabilitásnak.
Ahogy a strukturált programozás és a "goto considered harmful" a vezérlésátadásra adott korlátokat, emiatt nehezebben állhat elő olyan kód, ami hibás (persze még így is sok hibás logikás kód van, de gotoval még szarabb lenne a helyzet).
Hasonlóan a state módosítására is kell valami eszköz, ami korlátot ad, például úgy, hogy maguk az objektumok immutable-k, és ha módosítani akarsz valamit, akkor létrehozol egy módosított másolatpéldányt.
Ennek az az értelme, hogy például a "copy constructorban" tudod vizsgálni a class invariantokat, és nehezebben fordulhat elő olyan, hogy egy objektumnak invalid állapota van, mert a sok-sok egymástól távol lévő mutator hatása káoszt okoz.
Persze hasonlóan, minden setterben lehetne vizsgálni a class invariantokat. Vagy temp objektumokkal (akár builder patternnel) dolgozni, és az új objektumot egy menetben, a builder állapota alapján létrehozni.
Stb.
Van ennek értelme, csak ésszel kell használni, és tudni, hogy mit áldozunk fel (egy kis teljesítményt) mire (kevesebb lehetséges side effectre).
Hogy másként mondjam: a strukturált programozás szabályozott kereteket ad a végrehajtás alatt lévő kód változásának módjaira vezérlési szerkezetekkel.
Az immutability meg szabályozott kereteket ad memóriában lévő adat változásának módjaira.