Free AI web copilot to create summaries, insights and extended knowledge, download it at here
2132
Abstract
<iframe class="gist-iframe" src="/gist/iamprovidence/6574b3c7f85814332eb016299e47c184.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="ad38">That is not a new thing in programming and being overused, so often, that developers start confusing what terms you should use to describe it. Some refer it as <b><i>if-then-throw pattern</i></b>, other <b><i>fail-fast principle</i></b> and so on. Whatever you call, it’s still the same thing.</p><p id="ff76">However, the simple use of exception, might not ensure that the object is in a valid state. Some complex business validation will require interaction with database. Which is expected. Domain rules can not be fully validated by single entity and most likely you still will need to came up with some service or another solution.</p><h2 id="40f7">Not-always-valid model</h2><p id="05ca">Following this approach, we allow our entity to be invalid. Instead of always keeping it in valid state, we will perform validation of all invariants in a single <code>Validate()</code> method:</p>
<figure id="e137">
<div>
<div>
<iframe class="gist-iframe" src="/gist/iamprovidence/553ab447e1acfc4ff9263647851be4b2.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="9803">The <code>Validate()</code> method is usually called before persisting domain model, but can also be used before performing complex business logic:</p>
<figure id="518e">
<div>
<div>
<iframe class="gist-iframe" src="/gist/iamprovidence/feafca28f0beeb63b5d876e35b74ccea.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="ea65">The advantage here that we gather <i>most of the validation</i> in a
Options
single place. Why most? — you may wonder. Because, there are still some rules that just can not be validated on a final state, like the one we had in <code>Cancel()</code> method.</p><p id="86f9">Secondly, it is also possible to accumulate validation messages in a single exception. With fail-first approach, you would need to send tons of request before you finally configure each property to be correct. On the other hand, this one will return all validation messages together.</p><h2 id="3660">Which one is better? 🤔</h2><p id="767d">Now, when you have seen different validation approaches, we can decide which one to use. Even thought it is up to you, my suggestion would be to use <b><i>Always-valid</i></b> approach.</p><p id="d1f5">With <b><i>not-always-valid</i></b> approach, you simply can not be sure that you have a fully working model. Thus, there is always a need to investigate all references to make sure validation is not missed. That just tons of maintenance overhead.</p><p id="3c95">Although, it may be useful to ignore the validation rule in some cases (when writing a unit test for example it always annoys me that I need to spend hours arranging correct data, for my test to work) I better catch an exception then store invalid data because I forget to call <code>Validate()</code>.</p><p id="a3a8">On the other hand, <b><i>always-valid</i></b> approach decreases complexity of code support. It does not allow violating any business invariants. It does not allow providing wrong arguments, which lead to unstable state of your model. And you should not even do that. You should not have empty address and if something like that happens it is rather exceptional situation that should be reported right away and not in another function after other hundred line of code.</p><p id="b878">Choose <b><i>Always-valid </i></b>approach, and you will see how much easier it is to maintain your codebase.</p><p id="bbd9">📝 Let me know into the comments which one you prefer and why</p><p id="06bf">☕️ Buy me a coffee if you want to support me</p><p id="cf5a">✅ Follow to get more articles about DDD</p></article></body>