{"tag":"bug","articles":{"blog\/technology\/immutable-and-stateless":{"key":"blog\/technology\/immutable-and-stateless","type":"article","published":true,"meta":{"createdAt":"2018-01-14T13:35:17+01:00","publishedAt":"2018-01-14T13:24:00+01:00","group":null,"category":"blog","subcategory":"technology","slug":"immutable-and-stateless"},"content":{"en":{"slug":"immutable-and-stateless","title":"On the importance of immutability and statelessness","intro":"\u003Cfigure\u003E\n                \u003Cnoscript\u003E\n                    \u003Cimg src=\u0022https:\/\/avris.it\/image\/mutants-everywhere_small.jpg\u0022 alt=\u0022\u0022 class=\u0022border-bottom\u0022 width=\u0022480\u0022 height=\u0022261.6\u0022\u003E                \n                \u003C\/noscript\u003E\n                \u003Cspan class=\u0022hide-noscript\u0022\u003E\u003Cimg src=\u0022data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAATCAYAAAD4f6+NAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAGxklEQVRIiVWW229cVxXGf\/syZ+bMzRPbsV3bgSRtcJrUJSmJklaNiihUDRJEPCFFPMCfAOIf4IV\/AnjgAQlaxAM88YD6kFBoGhTSNL0kdhw7Tnyb8XjuZ+bsvRcPZ5KSLR1t6eyzz\/7W9631ra1+\/tOrgjbklPB0GGOwVpHTCgigAAGFotlNCCFA9op8FJGmKSJCCIGeA2U0RaPZSDXFWhlr7bM9z\/aKjOdAGI54tdDGGo0FQYKAeQpHCMHjUkXQGmMURgkiQv9gn5\/88lfkcjnW1tao1\/c4\/fLLrK6u0my1uXjxInfu3GFhYYFiscgf3nufg1H\/\/w7\/KmgRQSmFCAQUMgZns\/CzoZSi1UvQKgAKRKGV4HotSp0Gc7Fm89Emy68uZ5GKsLb2AOcc09PTzMzM8GRzk+BSUJpvnDjBjbu3nwPyPDvyjOkgCoVC\/eJnV0WUEOfyGA31To\/D1SIiCuc9Adj6z8dcPj3Di0dm+PNmQOVrDIKnWi6ROs9olIKGfD6msX9AMc4zUZtgtd4mRBpjDAgEGcsVBJAxK0I68pyKWhQN6AylQquMIaUUSPZ5ECG4wIXT83x9NkaXy7w9q4mTA6oGSLow7JOXlJI4zKBNhOAHCeFgl3w4QLJTCYRMCxEmCajE81QIACcKUYL2IeA8pM7jQgBRGXbJHlGwdHye+Tii0mkwbTxT2meAg4BLmPQ9nBsihHHkgsPQkeozmV5yq0Qu4QUTeG0KTsQpIfWZbApSCYh4NKIgCE403glBAl7CM10Ryz82Ax0xxHGOraFnJxHGZ3Nh2vLdF0ucKsaEp4GMZxGVVZ8IT5ij1O5yugyDRpdSeQqJFBKyAEaiUaLRZIUNAbwIPgSC13j\/VeKJMnzYNAxGjtlIUauWcAS8CJPGQxihGRKbCBAW5w2VqZhKZewXwEDHTE1ZGp0uaZzjk539p0soBT4oPKC9ypgQIHhFCJqhCzgRfBACPlNPR9xYb\/LH21tsp2H8J8NKP8fSfJmlmsP1PGcWylg7pGn3oJNgySzj3eM13l5a4H4HPmob0kIOJdmaljFTItjMgDxBMupEhGHq0U4Q0WjxLB+bIHnwBWbUot32xNOevFbUKjX+vd3i0Z92aLoehSNFGjVDt5iw8kGf7y8d581XjnL9yRaXFiI+uPWQYa5AMIaKdJgMe6zqYyhgKJkBWCUhY2DMXzkuYIxGkRlXjKOxepNoeoF7TxocmnRsbt9j4dwMcXHEt0\/Mcrh8nJmJdb7cesLtVov6ukb3hW6nR82khNJj1pqOh\/UBJg3kfEoinj2pkJdWVv5qhBQ0Nku8kGW7ZLCc98+qYzY6oD2oc\/1akx9\/Z4l7Dzaoql0kLJAUO7T1SWrlGmv3P8T\/bYXcleOoVkSlZHjv+mcMvUJXNH+V++z0PdpX0UEjIngUmhEiQrmsKeQN9jk7zxJjXCEZQzXaLJ54iXe\/d4qVtRW0KTOyMWpfsTvoMXfmSxruHsm0YeXk12hcM1RLFeJqzJsXjnJ39yF6FwJl9NjjApmdCJ4yPVJdYm7C0h0OsSIpzo1QPsk6ShA0CvCgFMq0KOQOcfvOXfoHj5BkhJUqYb\/ByJZQe5ajySFa\/RrDfJ\/dgx0+vf8YZSrUJg+olLsIYAjjBg0Yi40UPk2ZtNsMmEJGFeyohY3q97DiMEpnGxXkxvaEhjvNFrWtzxlJRBTlODdT4v3P+ixXE+7vDdj+LOa\/7W0e7LVZ32vR6vYo5fO8cXKRnE+Ik2HW0WXMvoJgI8IQckFIUFAYUm9oGPawc3lw2KzzAnpxmTRotNYko4Tlo9Ns7rTp1g\/o2grNXIHjFwy+lmfYuIaeP8ZGe4MwUeT10+fY32\/S7fYpz0+gkoQgQqVSxVpLr9fD5iMmymW2d7eR3gHS2kIPEqxN8Ah24D0SFAoICt5450e88tr58fWiThSGhOkWxwoxly9f5je\/\/R1TJcs3L1zik49vcekHV5ldukehUGBxcYGd3V0erW9w5swZPv\/ic86dO8\/Ozg5nz57l5s2brKyscOXKFW7c+Ih\/\/uX3xDZrvBow1mJzWhF0xo4RxcbGBvHEJPV6HWs0Sb+DMpbDhw+zvr7OcDgiUSnOOaZmZuj1uvjRiK3mPnNzs+zt7LI4fYg7t24yWZtga2ubBw9WmZqaIkkSclqzt7tHCILN5TBGgxgMDq0C6tc\/XBaR7O4jGlr9IaDRCspxIM4P+PSxodNpMj\/zAjfak7x1xGHSNnkMJop56\/Vv8fe7W\/S2H\/PO+SUqk4f512qf5uoNnAiozPVVEEx1GlOu4ZyjEOXIWwMiuKRLVK7yP6sQ4wkEHMxKAAAAAElFTkSuQmCC\u0022 data-src=\u0022https:\/\/avris.it\/image\/mutants-everywhere_small.jpg\u0022 alt=\u0022\u0022 class=\u0022border-bottom\u0022 width=\u0022480\u0022 height=\u0022261.6\u0022\u003E\u003C\/span\u003E\n                \n            \u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EKeeping your classes \u003Cstrong\u003Eimmutable and stateless\u003C\/strong\u003E makes your code \u003Cem\u003Eway\u003C\/em\u003E less prone to bugs. Yet somehow this clean code rule isn\u2019t as popular and as often invoked as\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E SRP\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/You_aren%27t_gonna_need_it\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E YAGNI\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Don%27t_repeat_yourself\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E DRY\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/KISS_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E KISS\u003C\/a\u003E\nand others... Maybe it\u2019s because of the lack of a catchy acronym?\u003C\/p\u003E\n\u003Cp\u003EAnyways, I\u2019d like to take a look at two examples of when sticking to this rule could save your ass (or at least save you some time debugging).\u003C\/p\u003E\u003Csvg xmlns=\u0022http:\/\/www.w3.org\/2000\/svg\u0022 style=\u0022display: none;\u0022\u003E\u003C\/svg\u003E","content":"\u003Cfigure\u003E\n                \u003Cnoscript\u003E\n                    \u003Cimg src=\u0022https:\/\/avris.it\/image\/mutants-everywhere_big.jpg\u0022 alt=\u0022\u0022 class=\u0022border\u0022 width=\u0022600\u0022 height=\u0022327\u0022\u003E                \n                \u003C\/noscript\u003E\n                \u003Cspan class=\u0022hide-noscript\u0022\u003E\u003Cimg src=\u0022data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAATCAYAAAD4f6+NAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAGxklEQVRIiVWW229cVxXGf\/syZ+bMzRPbsV3bgSRtcJrUJSmJklaNiihUDRJEPCFFPMCfAOIf4IV\/AnjgAQlaxAM88YD6kFBoGhTSNL0kdhw7Tnyb8XjuZ+bsvRcPZ5KSLR1t6eyzz\/7W9631ra1+\/tOrgjbklPB0GGOwVpHTCgigAAGFotlNCCFA9op8FJGmKSJCCIGeA2U0RaPZSDXFWhlr7bM9z\/aKjOdAGI54tdDGGo0FQYKAeQpHCMHjUkXQGmMURgkiQv9gn5\/88lfkcjnW1tao1\/c4\/fLLrK6u0my1uXjxInfu3GFhYYFiscgf3nufg1H\/\/w7\/KmgRQSmFCAQUMgZns\/CzoZSi1UvQKgAKRKGV4HotSp0Gc7Fm89Emy68uZ5GKsLb2AOcc09PTzMzM8GRzk+BSUJpvnDjBjbu3nwPyPDvyjOkgCoVC\/eJnV0WUEOfyGA31To\/D1SIiCuc9Adj6z8dcPj3Di0dm+PNmQOVrDIKnWi6ROs9olIKGfD6msX9AMc4zUZtgtd4mRBpjDAgEGcsVBJAxK0I68pyKWhQN6AylQquMIaUUSPZ5ECG4wIXT83x9NkaXy7w9q4mTA6oGSLow7JOXlJI4zKBNhOAHCeFgl3w4QLJTCYRMCxEmCajE81QIACcKUYL2IeA8pM7jQgBRGXbJHlGwdHye+Tii0mkwbTxT2meAg4BLmPQ9nBsihHHkgsPQkeozmV5yq0Qu4QUTeG0KTsQpIfWZbApSCYh4NKIgCE403glBAl7CM10Ryz82Ax0xxHGOraFnJxHGZ3Nh2vLdF0ucKsaEp4GMZxGVVZ8IT5ij1O5yugyDRpdSeQqJFBKyAEaiUaLRZIUNAbwIPgSC13j\/VeKJMnzYNAxGjtlIUauWcAS8CJPGQxihGRKbCBAW5w2VqZhKZewXwEDHTE1ZGp0uaZzjk539p0soBT4oPKC9ypgQIHhFCJqhCzgRfBACPlNPR9xYb\/LH21tsp2H8J8NKP8fSfJmlmsP1PGcWylg7pGn3oJNgySzj3eM13l5a4H4HPmob0kIOJdmaljFTItjMgDxBMupEhGHq0U4Q0WjxLB+bIHnwBWbUot32xNOevFbUKjX+vd3i0Z92aLoehSNFGjVDt5iw8kGf7y8d581XjnL9yRaXFiI+uPWQYa5AMIaKdJgMe6zqYyhgKJkBWCUhY2DMXzkuYIxGkRlXjKOxepNoeoF7TxocmnRsbt9j4dwMcXHEt0\/Mcrh8nJmJdb7cesLtVov6ukb3hW6nR82khNJj1pqOh\/UBJg3kfEoinj2pkJdWVv5qhBQ0Nku8kGW7ZLCc98+qYzY6oD2oc\/1akx9\/Z4l7Dzaoql0kLJAUO7T1SWrlGmv3P8T\/bYXcleOoVkSlZHjv+mcMvUJXNH+V++z0PdpX0UEjIngUmhEiQrmsKeQN9jk7zxJjXCEZQzXaLJ54iXe\/d4qVtRW0KTOyMWpfsTvoMXfmSxruHsm0YeXk12hcM1RLFeJqzJsXjnJ39yF6FwJl9NjjApmdCJ4yPVJdYm7C0h0OsSIpzo1QPsk6ShA0CvCgFMq0KOQOcfvOXfoHj5BkhJUqYb\/ByJZQe5ajySFa\/RrDfJ\/dgx0+vf8YZSrUJg+olLsIYAjjBg0Yi40UPk2ZtNsMmEJGFeyohY3q97DiMEpnGxXkxvaEhjvNFrWtzxlJRBTlODdT4v3P+ixXE+7vDdj+LOa\/7W0e7LVZ32vR6vYo5fO8cXKRnE+Ik2HW0WXMvoJgI8IQckFIUFAYUm9oGPawc3lw2KzzAnpxmTRotNYko4Tlo9Ns7rTp1g\/o2grNXIHjFwy+lmfYuIaeP8ZGe4MwUeT10+fY32\/S7fYpz0+gkoQgQqVSxVpLr9fD5iMmymW2d7eR3gHS2kIPEqxN8Ah24D0SFAoICt5450e88tr58fWiThSGhOkWxwoxly9f5je\/\/R1TJcs3L1zik49vcekHV5ldukehUGBxcYGd3V0erW9w5swZPv\/ic86dO8\/Ozg5nz57l5s2brKyscOXKFW7c+Ih\/\/uX3xDZrvBow1mJzWhF0xo4RxcbGBvHEJPV6HWs0Sb+DMpbDhw+zvr7OcDgiUSnOOaZmZuj1uvjRiK3mPnNzs+zt7LI4fYg7t24yWZtga2ubBw9WmZqaIkkSclqzt7tHCILN5TBGgxgMDq0C6tc\/XBaR7O4jGlr9IaDRCspxIM4P+PSxodNpMj\/zAjfak7x1xGHSNnkMJop56\/Vv8fe7W\/S2H\/PO+SUqk4f512qf5uoNnAiozPVVEEx1GlOu4ZyjEOXIWwMiuKRLVK7yP6sQ4wkEHMxKAAAAAElFTkSuQmCC\u0022 data-src=\u0022https:\/\/avris.it\/image\/mutants-everywhere_big.jpg\u0022 alt=\u0022\u0022 class=\u0022border\u0022 width=\u0022600\u0022 height=\u0022327\u0022\u003E\u003C\/span\u003E\n                \u003Cfigcaption\u003E\n                    \u003Ca href=\u0022https:\/\/makeameme.org\/meme\/mutants-mutants-everywhere-n6biem\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\n                        \u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E\n                        makeameme.org\/meme\/mutants-mutants-everywhere-n6biem\n                    \u003C\/a\u003E\n                \u003C\/figcaption\u003E\n            \u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EKeeping your classes \u003Cstrong\u003Eimmutable and stateless\u003C\/strong\u003E makes your code \u003Cem\u003Eway\u003C\/em\u003E less prone to bugs. Yet somehow this clean code rule isn\u2019t as popular and as often invoked as\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E SRP\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/You_aren%27t_gonna_need_it\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E YAGNI\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Don%27t_repeat_yourself\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E DRY\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/KISS_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E KISS\u003C\/a\u003E\nand others... Maybe it\u2019s because of the lack of a catchy acronym?\u003C\/p\u003E\n\u003Cp\u003EAnyways, I\u2019d like to take a look at two examples of when sticking to this rule could save your ass (or at least save you some time debugging).\u003C\/p\u003E\n\u003Ch3\u003EDateTime\u003C\/h3\u003E\n\u003Cp\u003EPHP offers a \u003Ccode\u003EDateTime\u003C\/code\u003E object that encapsulates, well, a date and time. And it\u2019s pretty cool: it can parse strings like \u201cnext monday\u201d, it can understand instructions like modify \u201c+1 week midnight\u201d, the standard library offers support for time zones and for iterating over time (like from \u201cnow\u201d to \u201c+1 day\u201d every \u201c+30 minutes\u201d).\u003C\/p\u003E\n\u003Cp\u003EBut there\u2019s a huge catch involved: \u003Ccode\u003EDateTime\u003C\/code\u003E is mutable.\u003C\/p\u003E\n\u003Cp\u003ELet\u2019s say you have a \u003Ccode\u003EUser\u003C\/code\u003E entity:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs php border\u0022\u003E\u003Cspan class=\u0022hljs-comment\u0022\u003E\/**\n * \u003Cspan class=\u0022hljs-doctag\u0022\u003E@ORM\u003C\/span\u003E\\Entity\n * \u003Cspan class=\u0022hljs-doctag\u0022\u003E@ORM\u003C\/span\u003E\\Table\n **\/\u003C\/span\u003E\n\u003Cspan class=\u0022hljs-class\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Eclass\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EUser\u003C\/span\u003E\n\u003C\/span\u003E{\n    \u003Cspan class=\u0022hljs-comment\u0022\u003E\/**\n     * \u003Cspan class=\u0022hljs-doctag\u0022\u003E@var\u003C\/span\u003E \\DateTime\n     * \u003Cspan class=\u0022hljs-doctag\u0022\u003E@ORM\u003C\/span\u003E\\Column(type=\u0022datetime\u0022)\n     *\/\u003C\/span\u003E\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Eprivate\u003C\/span\u003E $createdAt;\n\n    \u003Cspan class=\u0022hljs-comment\u0022\u003E\/\/ many other fields...\u003C\/span\u003E\n\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Epublic\u003C\/span\u003E \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003E__construct\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E()\u003C\/span\u003E\n    \u003C\/span\u003E{\n        \u003Cspan class=\u0022hljs-keyword\u0022\u003E$this\u003C\/span\u003E-\u0026gt;createdAt = \u003Cspan class=\u0022hljs-keyword\u0022\u003Enew\u003C\/span\u003E \\DateTime();\n    }\n\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Epublic\u003C\/span\u003E \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EgetCreatedAt\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E()\u003C\/span\u003E: \\\u003Cspan class=\u0022hljs-title\u0022\u003EDateTime\u003C\/span\u003E\n    \u003C\/span\u003E{\n        \u003Cspan class=\u0022hljs-keyword\u0022\u003Ereturn\u003C\/span\u003E \u003Cspan class=\u0022hljs-keyword\u0022\u003E$this\u003C\/span\u003E-\u0026gt;createdAt;\n    }\n}\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EIt looks as if you could be sure that \u003Ccode\u003EcreatedAt\u003C\/code\u003E will be stored in the database as exactly the moment when the entity was first created, right? After all there\u2019s no setter given, so unless you hack around with reflections, there\u2019s no way to modify that value ever again, is there?\u003C\/p\u003E\n\u003Cp\u003EWell, let\u2019s say in your app it\u2019s important to display, how many Sundays have passed since some stuff happened, and one of them is the registration of a given user.\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs php border\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Epublic\u003C\/span\u003E \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EcountSundays\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E(\\DateTime $datetime)\u003C\/span\u003E: \u003Cspan class=\u0022hljs-title\u0022\u003Eint\u003C\/span\u003E\n\u003C\/span\u003E{\n    $datetime-\u0026gt;modify(\u003Cspan class=\u0022hljs-string\u0022\u003E\u0027next sunday 23:59:59\u0027\u003C\/span\u003E);\n    $sundays = \u003Cspan class=\u0022hljs-number\u0022\u003E0\u003C\/span\u003E;\n\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Ewhile\u003C\/span\u003E ($datetime \u0026lt; \u003Cspan class=\u0022hljs-keyword\u0022\u003Enew\u003C\/span\u003E \\DateTime(\u003Cspan class=\u0022hljs-string\u0022\u003E\u0027now\u0027\u003C\/span\u003E)) {\n        $sundays++;\n        $datetime-\u0026gt;modify(\u003Cspan class=\u0022hljs-string\u0022\u003E\u0027+1 week\u0027\u003C\/span\u003E);\n    }\n\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Ereturn\u003C\/span\u003E $sundays;\n}\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EAt first glance this code seems fine as well. We get some value, we use it to calculate some other value, and we return the result. But notice that we keep modifying the input data! If you did it with a string, int or an array, the input would not be modified at all (unless explicitly passed as reference, \u003Ccode\u003E\u0026amp;$string\u003C\/code\u003E). But \u003Ccode\u003E\\DateTime\u003C\/code\u003E, although it\u2019s just a simple value wrapped in a class, is a class after all, so it\u2019s always passed by reference.\u003C\/p\u003E\n\u003Cp\u003ESo even though you cannot set \u003Ccode\u003EUser\u003C\/code\u003E\u2019s \u003Ccode\u003EcreatedAt\u003C\/code\u003E to a \u003Cem\u003Edifferent\u003C\/em\u003E object, you can pass that object to some function that will modify the \u003Cem\u003Einside\u003C\/em\u003E of that object. So if you happen to save your \u003Ccode\u003EUser\u003C\/code\u003E entity to the database after its number of Sundays has been calculated, you will end up with all the users having been registered \u003Cem\u003Ein the future\u003C\/em\u003E and constantly changing their registration date.\u003C\/p\u003E\n\u003Cp\u003EIt might be quite difficult to find the source of this bug. After all, there is no setter, and the connection between this date and \u003Ccode\u003EcountSundays\u003C\/code\u003E might not be too obvious \u2013 maybe hidden in a Twig extension or an external library...\u003C\/p\u003E\n\u003Cp\u003EHow to mitigate that? Ideally, use \u003Ca href=\u0022https:\/\/secure.php.net\/manual\/en\/class.datetimeimmutable.php\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E \u003Ccode\u003EDateTimeImmuttable\u003C\/code\u003E\u003C\/a\u003E, which \u201cbehaves the same as DateTime except it never modifies itself but returns a new object instead\u201d.\u003C\/p\u003E\n\u003Cp\u003EOr if you don\u2019t want to adjust your whole project to use \u003Ccode\u003EDateTimeImmuttable\u003C\/code\u003E, you might instead remember to \u003Ccode\u003Eclone\u003C\/code\u003E a \u003Ccode\u003EDateTime\u003C\/code\u003E variable before passing it anywhere.\u003C\/p\u003E\n\u003Cp\u003EBtw, in the Rust programming language all variables are \u003Ca href=\u0022https:\/\/doc.rust-lang.org\/book\/first-edition\/mutability.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E immutable by default\u003C\/a\u003E \ud83d\ude0d\u003C\/p\u003E\n\u003Ch3\u003EInvoices import\u003C\/h3\u003E\n\u003Cp\u003EI had to work on a code like this recently:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs php border\u0022\u003EinvoiceService = \u003Cspan class=\u0022hljs-keyword\u0022\u003Enew\u003C\/span\u003E InvoiceService\nshop = \u003Cspan class=\u0022hljs-keyword\u0022\u003Enew\u003C\/span\u003E Shop\n\ninvoices = shop.loadInvoices\n\n\u003Cspan class=\u0022hljs-keyword\u0022\u003Efor\u003C\/span\u003E each invoice in invoices {\n    invoiceService.saveInvoice(invoice)\n}\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EAnd somewhere inside \u003Ccode\u003EsaveInvoice\u003C\/code\u003E, this function was executed:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs php border\u0022\u003E\u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003ErunSQL\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E(sql)\u003C\/span\u003E \u003C\/span\u003E{\n    result = database_exec(sql)\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Eif\u003C\/span\u003E result is \u003Cspan class=\u0022hljs-keyword\u0022\u003Efalse\u003C\/span\u003E {\n        log(database_error)\n        \u003Cspan class=\u0022hljs-keyword\u0022\u003Edie\u003C\/span\u003E\n    }\n}\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EThe code was PHP, but it\u2019s such a \u003Ca href=\u0022http:\/\/govnokod.ru\/\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E govnokod\u003C\/a\u003E that the above pseudocode with ~90% of original logic removed, is the best way to show it without crying...\u003C\/p\u003E\n\u003Cp\u003ESo the problem was: no invoices are generated anymore. Can you see why? If any invoice fails, the script just logs the error and just dies. When it runs again, it tries with the same invoice and dies again, over and over again, never even trying to handle any other invoice.\u003C\/p\u003E\n\u003Cp\u003EThe underlying error was easy to find and reasonably easy to fix. But we wanted to also make that old, shitty code just a tiny bit better \u2013 if one invoice fails, it shouldn\u2019t block all the others anymore.\u003C\/p\u003E\n\u003Cp\u003EInstead of \u003Ccode\u003Edie\u003C\/code\u003E-ing, the \u003Ccode\u003ErunSQL\u003C\/code\u003E would throw an exception. All the other places, where \u003Ccode\u003ErunSQL\u003C\/code\u003E is used, would basically work as they used to (uncaught exception would terminate the script anyway), but on loading the invoices we would just catch the exception and carry on with all the other invoices.\u003C\/p\u003E\n\u003Cp\u003EWhat could possibly go wrong?\u003C\/p\u003E\n\u003Cp\u003EWell, if you do it on Friday, while starting to get a bit sick, and with \u003Ccode\u003EInvoiceService\u003C\/code\u003E class consisting of \u0026gt;1000 lines of messy, overcomplicated code \u2013 a lot can go wrong.\u003C\/p\u003E\n\u003Cp\u003EAll because \u003Ccode\u003EInvoiceService\u003C\/code\u003E is stateful. That means running \u003Ccode\u003EinvoiceService.saveInvoice(invoice)\u003C\/code\u003E might result in different stuff actually being done, depending on the context it was run in. In this case, the class was keeping invoice items (and other stuff) as a private object property \u2013 first loading them from somewhere, then saving to the database, and finally cleaning it up.\u003C\/p\u003E\n\u003Cp\u003EObviously, with the try-catch, the last step wouldn\u2019t be executed. So if \u003Ccode\u003EinvoiceService.saveInvoice(invoice1)\u003C\/code\u003E fails, then \u003Ccode\u003EinvoiceService.saveInvoice(invoice2)\u003C\/code\u003E wouldn\u2019t really save the \u003Ccode\u003Einvoice2\u003C\/code\u003E, as name suggests \u2013 it would load \u003Ccode\u003Einvoice2\u003C\/code\u003E plus some failing items from \u003Ccode\u003Einvoice1\u003C\/code\u003E... The errors pile up, the invoice items accumulate, and we end up with hundreds of invalid (empty) invoices with the last one claiming that someone owes us 1,9 mln \u20ac...\u003C\/p\u003E\n\u003Ch3\u003EAlways immutable and stateless?\u003C\/h3\u003E\n\u003Cp\u003EObviously not. Some types of classes you \u003Cem\u003Eexpect\u003C\/em\u003E to be stateful. What would be the point of a \u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Builder_pattern\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E Builder\u003C\/a\u003E, if it couldn\u2019t hold an internal state? How to implement \u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Event_(computing)\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E Events\u003C\/a\u003E elegantly, if they were immutable?\u003C\/p\u003E\n\u003Cp\u003EForm libraries like \u003Ca href=\u0022https:\/\/symfony.com\/doc\/current\/forms.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E Symfony Forms\u003C\/a\u003E or \u003Ca href=\u0022https:\/\/gitlab.com\/Avris\/Forms\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E Avris Forms\u003C\/a\u003E require you to provide getters and setters for your entity \u2013 and it reflects how your database probably works: a user might change their username or avatar, so the programmer shouldn\u2019t \u003Cem\u003Eexpect\u003C\/em\u003E them to be immutable. (Unless you\u2019re using \u003Ca href=\u0022https:\/\/martinfowler.com\/eaaDev\/EventSourcing.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E Event Sourcing\u003C\/a\u003E, then good for you!).\u003C\/p\u003E\n\u003Cp\u003EBasically, it\u2019s all about what you would expect from a class, see \u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Principle_of_least_astonishment\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E Principle of least astonishment\u003C\/a\u003E.\u003C\/p\u003E\n\u003Cp\u003EA simple data value objects, like \u003Ca href=\u0022https:\/\/secure.php.net\/manual\/en\/class.datetimeimmutable.php\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E date and time\u003C\/a\u003E, or \u003Ca href=\u0022https:\/\/github.com\/moneyphp\/money\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csvg class=\u0022icon\u0022\u003E\u003Cuse xlink:href=\u0022#light-link\u0022\u003E\u003C\/use\u003E\u003C\/svg\u003E monetary value\u003C\/a\u003E should consistently represent the same value. Services that offer a method \u003Ccode\u003EhandleFoo(Foo)\u003C\/code\u003E should behave exactly the same for the same \u003Ccode\u003EFoo\u003C\/code\u003E, regardless of when were they triggered.\u003C\/p\u003E\n\u003Cp\u003EEntities though can be mutable in your project, and that\u2019s ok. Builders, by their nature, are mutable, and that\u2019s fine. You can even see that from the methods they provide: \u003Ccode\u003EaddFoo\u003C\/code\u003E etc. suggest you shouldn\u2019t expect immutability from them.\u003C\/p\u003E\n\u003Cp\u003EI think that Rust\u2019s approach should be followed: immutability by default, mutability explicitly declared. In other terms: write immutable classes, unless you can find a good justification for making one mutable.\u003C\/p\u003E\n\u003Cp\u003EAnd when it comes to finding a nice acronym for this rule... how about JAM?\u003C\/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EJustify All Mutants\u003C\/strong\u003E.\u003C\/p\u003E\u003Csvg xmlns=\u0022http:\/\/www.w3.org\/2000\/svg\u0022 style=\u0022display: none;\u0022\u003E\u003C\/svg\u003E","tags":["bug","class","clean code","immutability","immutable","programming","security","stateless","statelessness"],"hasMore":true,"image":"https:\/\/avris.it\/image\/mutants-everywhere_small.jpg","introLite":"\u003Cfigure\u003E\u003Ca href=\u0022https:\/\/avris.it\/image\/mutants-everywhere_big.jpg\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Cimg src=\u0022https:\/\/avris.it\/image\/mutants-everywhere_mini.jpg\u0022 alt=\u0022\u0022 width=\u0022240\u0022 height=\u0022130.8\u0022 loading=\u0022lazy\u0022\u003E\u003C\/a\u003E\u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EKeeping your classes \u003Cstrong\u003Eimmutable and stateless\u003C\/strong\u003E makes your code \u003Cem\u003Eway\u003C\/em\u003E less prone to bugs. Yet somehow this clean code rule isn\u2019t as popular and as often invoked as\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E SRP\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/You_aren%27t_gonna_need_it\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E YAGNI\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Don%27t_repeat_yourself\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E DRY\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/KISS_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E KISS\u003C\/a\u003E\nand others... Maybe it\u2019s because of the lack of a catchy acronym?\u003C\/p\u003E\n\u003Cp\u003EAnyways, I\u2019d like to take a look at two examples of when sticking to this rule could save your ass (or at least save you some time debugging).\u003C\/p\u003E","contentLite":"\u003Cfigure\u003E\u003Ca href=\u0022https:\/\/avris.it\/image\/mutants-everywhere_big.jpg\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Cimg src=\u0022https:\/\/avris.it\/image\/mutants-everywhere_mini.jpg\u0022 alt=\u0022\u0022 width=\u0022240\u0022 height=\u0022130.8\u0022 loading=\u0022lazy\u0022\u003E\u003C\/a\u003E\u003Cfigcaption\u003E\n                    \u003Ca href=\u0022https:\/\/makeameme.org\/meme\/mutants-mutants-everywhere-n6biem\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Csmall\u003Emakeameme.org\/meme\/mutants-mutants-everywhere-n6biem\u003C\/small\u003E\u003C\/a\u003E\n                \u003C\/figcaption\u003E\u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EKeeping your classes \u003Cstrong\u003Eimmutable and stateless\u003C\/strong\u003E makes your code \u003Cem\u003Eway\u003C\/em\u003E less prone to bugs. Yet somehow this clean code rule isn\u2019t as popular and as often invoked as\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E SRP\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/You_aren%27t_gonna_need_it\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E YAGNI\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Don%27t_repeat_yourself\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E DRY\u003C\/a\u003E,\n\u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/KISS_principle\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E KISS\u003C\/a\u003E\nand others... Maybe it\u2019s because of the lack of a catchy acronym?\u003C\/p\u003E\n\u003Cp\u003EAnyways, I\u2019d like to take a look at two examples of when sticking to this rule could save your ass (or at least save you some time debugging).\u003C\/p\u003E\n\u003Ch3\u003EDateTime\u003C\/h3\u003E\n\u003Cp\u003EPHP offers a \u003Ccode\u003EDateTime\u003C\/code\u003E object that encapsulates, well, a date and time. And it\u2019s pretty cool: it can parse strings like \u201cnext monday\u201d, it can understand instructions like modify \u201c+1 week midnight\u201d, the standard library offers support for time zones and for iterating over time (like from \u201cnow\u201d to \u201c+1 day\u201d every \u201c+30 minutes\u201d).\u003C\/p\u003E\n\u003Cp\u003EBut there\u2019s a huge catch involved: \u003Ccode\u003EDateTime\u003C\/code\u003E is mutable.\u003C\/p\u003E\n\u003Cp\u003ELet\u2019s say you have a \u003Ccode\u003EUser\u003C\/code\u003E entity:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022language-php\u0022\u003E\/**\n * @ORM\\Entity\n * @ORM\\Table\n **\/\nclass User\n{\n    \/**\n     * @var \\DateTime\n     * @ORM\\Column(type=\u0022datetime\u0022)\n     *\/\n    private $createdAt;\n\n    \/\/ many other fields...\n\n    public function __construct()\n    {\n        $this-\u0026gt;createdAt = new \\DateTime();\n    }\n\n    public function getCreatedAt(): \\DateTime\n    {\n        return $this-\u0026gt;createdAt;\n    }\n}\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EIt looks as if you could be sure that \u003Ccode\u003EcreatedAt\u003C\/code\u003E will be stored in the database as exactly the moment when the entity was first created, right? After all there\u2019s no setter given, so unless you hack around with reflections, there\u2019s no way to modify that value ever again, is there?\u003C\/p\u003E\n\u003Cp\u003EWell, let\u2019s say in your app it\u2019s important to display, how many Sundays have passed since some stuff happened, and one of them is the registration of a given user.\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode\u003Epublic function countSundays(\\DateTime $datetime): int\n{\n    $datetime-\u0026gt;modify(\u0027next sunday 23:59:59\u0027);\n    $sundays = 0;\n\n    while ($datetime \u0026lt; new \\DateTime(\u0027now\u0027)) {\n        $sundays++;\n        $datetime-\u0026gt;modify(\u0027+1 week\u0027);\n    }\n\n    return $sundays;\n}\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EAt first glance this code seems fine as well. We get some value, we use it to calculate some other value, and we return the result. But notice that we keep modifying the input data! If you did it with a string, int or an array, the input would not be modified at all (unless explicitly passed as reference, \u003Ccode\u003E\u0026amp;$string\u003C\/code\u003E). But \u003Ccode\u003E\\DateTime\u003C\/code\u003E, although it\u2019s just a simple value wrapped in a class, is a class after all, so it\u2019s always passed by reference.\u003C\/p\u003E\n\u003Cp\u003ESo even though you cannot set \u003Ccode\u003EUser\u003C\/code\u003E\u2019s \u003Ccode\u003EcreatedAt\u003C\/code\u003E to a \u003Cem\u003Edifferent\u003C\/em\u003E object, you can pass that object to some function that will modify the \u003Cem\u003Einside\u003C\/em\u003E of that object. So if you happen to save your \u003Ccode\u003EUser\u003C\/code\u003E entity to the database after its number of Sundays has been calculated, you will end up with all the users having been registered \u003Cem\u003Ein the future\u003C\/em\u003E and constantly changing their registration date.\u003C\/p\u003E\n\u003Cp\u003EIt might be quite difficult to find the source of this bug. After all, there is no setter, and the connection between this date and \u003Ccode\u003EcountSundays\u003C\/code\u003E might not be too obvious \u2013 maybe hidden in a Twig extension or an external library...\u003C\/p\u003E\n\u003Cp\u003EHow to mitigate that? Ideally, use \u003Ca href=\u0022https:\/\/secure.php.net\/manual\/en\/class.datetimeimmutable.php\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E \u003Ccode\u003EDateTimeImmuttable\u003C\/code\u003E\u003C\/a\u003E, which \u201cbehaves the same as DateTime except it never modifies itself but returns a new object instead\u201d.\u003C\/p\u003E\n\u003Cp\u003EOr if you don\u2019t want to adjust your whole project to use \u003Ccode\u003EDateTimeImmuttable\u003C\/code\u003E, you might instead remember to \u003Ccode\u003Eclone\u003C\/code\u003E a \u003Ccode\u003EDateTime\u003C\/code\u003E variable before passing it anywhere.\u003C\/p\u003E\n\u003Cp\u003EBtw, in the Rust programming language all variables are \u003Ca href=\u0022https:\/\/doc.rust-lang.org\/book\/first-edition\/mutability.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E immutable by default\u003C\/a\u003E \ud83d\ude0d\u003C\/p\u003E\n\u003Ch3\u003EInvoices import\u003C\/h3\u003E\n\u003Cp\u003EI had to work on a code like this recently:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode\u003EinvoiceService = new InvoiceService\nshop = new Shop\n\ninvoices = shop.loadInvoices\n\nfor each invoice in invoices {\n    invoiceService.saveInvoice(invoice)\n}\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EAnd somewhere inside \u003Ccode\u003EsaveInvoice\u003C\/code\u003E, this function was executed:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode\u003Efunction runSQL(sql) {\n    result = database_exec(sql)\n    if result is false {\n        log(database_error)\n        die\n    }\n}\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EThe code was PHP, but it\u2019s such a \u003Ca href=\u0022http:\/\/govnokod.ru\/\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E govnokod\u003C\/a\u003E that the above pseudocode with ~90% of original logic removed, is the best way to show it without crying...\u003C\/p\u003E\n\u003Cp\u003ESo the problem was: no invoices are generated anymore. Can you see why? If any invoice fails, the script just logs the error and just dies. When it runs again, it tries with the same invoice and dies again, over and over again, never even trying to handle any other invoice.\u003C\/p\u003E\n\u003Cp\u003EThe underlying error was easy to find and reasonably easy to fix. But we wanted to also make that old, shitty code just a tiny bit better \u2013 if one invoice fails, it shouldn\u2019t block all the others anymore.\u003C\/p\u003E\n\u003Cp\u003EInstead of \u003Ccode\u003Edie\u003C\/code\u003E-ing, the \u003Ccode\u003ErunSQL\u003C\/code\u003E would throw an exception. All the other places, where \u003Ccode\u003ErunSQL\u003C\/code\u003E is used, would basically work as they used to (uncaught exception would terminate the script anyway), but on loading the invoices we would just catch the exception and carry on with all the other invoices.\u003C\/p\u003E\n\u003Cp\u003EWhat could possibly go wrong?\u003C\/p\u003E\n\u003Cp\u003EWell, if you do it on Friday, while starting to get a bit sick, and with \u003Ccode\u003EInvoiceService\u003C\/code\u003E class consisting of \u0026gt;1000 lines of messy, overcomplicated code \u2013 a lot can go wrong.\u003C\/p\u003E\n\u003Cp\u003EAll because \u003Ccode\u003EInvoiceService\u003C\/code\u003E is stateful. That means running \u003Ccode\u003EinvoiceService.saveInvoice(invoice)\u003C\/code\u003E might result in different stuff actually being done, depending on the context it was run in. In this case, the class was keeping invoice items (and other stuff) as a private object property \u2013 first loading them from somewhere, then saving to the database, and finally cleaning it up.\u003C\/p\u003E\n\u003Cp\u003EObviously, with the try-catch, the last step wouldn\u2019t be executed. So if \u003Ccode\u003EinvoiceService.saveInvoice(invoice1)\u003C\/code\u003E fails, then \u003Ccode\u003EinvoiceService.saveInvoice(invoice2)\u003C\/code\u003E wouldn\u2019t really save the \u003Ccode\u003Einvoice2\u003C\/code\u003E, as name suggests \u2013 it would load \u003Ccode\u003Einvoice2\u003C\/code\u003E plus some failing items from \u003Ccode\u003Einvoice1\u003C\/code\u003E... The errors pile up, the invoice items accumulate, and we end up with hundreds of invalid (empty) invoices with the last one claiming that someone owes us 1,9 mln \u20ac...\u003C\/p\u003E\n\u003Ch3\u003EAlways immutable and stateless?\u003C\/h3\u003E\n\u003Cp\u003EObviously not. Some types of classes you \u003Cem\u003Eexpect\u003C\/em\u003E to be stateful. What would be the point of a \u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Builder_pattern\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E Builder\u003C\/a\u003E, if it couldn\u2019t hold an internal state? How to implement \u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Event_(computing)\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E Events\u003C\/a\u003E elegantly, if they were immutable?\u003C\/p\u003E\n\u003Cp\u003EForm libraries like \u003Ca href=\u0022https:\/\/symfony.com\/doc\/current\/forms.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E Symfony Forms\u003C\/a\u003E or \u003Ca href=\u0022https:\/\/gitlab.com\/Avris\/Forms\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E Avris Forms\u003C\/a\u003E require you to provide getters and setters for your entity \u2013 and it reflects how your database probably works: a user might change their username or avatar, so the programmer shouldn\u2019t \u003Cem\u003Eexpect\u003C\/em\u003E them to be immutable. (Unless you\u2019re using \u003Ca href=\u0022https:\/\/martinfowler.com\/eaaDev\/EventSourcing.html\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E Event Sourcing\u003C\/a\u003E, then good for you!).\u003C\/p\u003E\n\u003Cp\u003EBasically, it\u2019s all about what you would expect from a class, see \u003Ca href=\u0022https:\/\/en.wikipedia.org\/wiki\/Principle_of_least_astonishment\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E Principle of least astonishment\u003C\/a\u003E.\u003C\/p\u003E\n\u003Cp\u003EA simple data value objects, like \u003Ca href=\u0022https:\/\/secure.php.net\/manual\/en\/class.datetimeimmutable.php\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E date and time\u003C\/a\u003E, or \u003Ca href=\u0022https:\/\/github.com\/moneyphp\/money\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E monetary value\u003C\/a\u003E should consistently represent the same value. Services that offer a method \u003Ccode\u003EhandleFoo(Foo)\u003C\/code\u003E should behave exactly the same for the same \u003Ccode\u003EFoo\u003C\/code\u003E, regardless of when were they triggered.\u003C\/p\u003E\n\u003Cp\u003EEntities though can be mutable in your project, and that\u2019s ok. Builders, by their nature, are mutable, and that\u2019s fine. You can even see that from the methods they provide: \u003Ccode\u003EaddFoo\u003C\/code\u003E etc. suggest you shouldn\u2019t expect immutability from them.\u003C\/p\u003E\n\u003Cp\u003EI think that Rust\u2019s approach should be followed: immutability by default, mutability explicitly declared. In other terms: write immutable classes, unless you can find a good justification for making one mutable.\u003C\/p\u003E\n\u003Cp\u003EAnd when it comes to finding a nice acronym for this rule... how about JAM?\u003C\/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EJustify All Mutants\u003C\/strong\u003E.\u003C\/p\u003E","words":1181,"readTime":5,"lang":"en"}}}}}