Code Smell 139 - Business Code in the User Interface
Maxi Contieri
Posted on June 9, 2022
Code Smell 139 - Business Code in the User Interface
Validations should be on the interface, or not?
TL;DR: Always create correct objects in your back-ends. UIs are accidental.
Problems
Security problems
Code Duplication
Testability
Extensibility to APIs, micro-services, etc.
Anemic and mutable objects
Solutions
- Move your validations to the back-end.
Context
Code Duplication is a warning for premature optimization.
Building a system with UI validations might evolve to an API or external component consumption.
We need to validate objects on the back-end and send good validation errors to client components.
Sample Code
Wrong
<script type="text/javascript">
function checkForm(form)
{
if(form.username.value == "") {
alert("Error: Username cannot be blank!");
form.username.focus();
return false;
}
re = /^\w+$/;
if(!re.test(form.username.value)) {
alert("Error: Username must contain only letters, numbers and underscores!");
form.username.focus();
return false;
}
if(form.pwd1.value != "" && form.pwd1.value == form.pwd2.value) {
if(form.pwd1.value.length < 8) {
alert("Error: Password must contain at least eight characters!");
form.pwd1.focus();
return false;
}
if(form.pwd1.value == form.username.value) {
alert("Error: Password must be different from Username!");
form.pwd1.focus();
return false;
}
re = /[0-9]/;
if(!re.test(form.pwd1.value)) {
alert("Error: password must contain at least one number (0-9)!");
form.pwd1.focus();
return false;
}
re = /[a-z]/;
if(!re.test(form.pwd1.value)) {
alert("Error: password must contain at least one lowercase letter (a-z)!");
form.pwd1.focus();
return false;
}
re = /[A-Z]/;
if(!re.test(form.pwd1.value)) {
alert("Error: password must contain at least one uppercase letter (A-Z)!");
form.pwd1.focus();
return false;
}
} else {
alert("Error: Please check that you've entered and confirmed your password!");
form.pwd1.focus();
return false;
}
alert("You entered a valid password: " + form.pwd1.value);
return true;
}
</script>
<form ... onsubmit="return checkForm(this);">
<p>Username: <input type="text" name="username"></p>
<p>Password: <input type="password" name="pwd1"></p>
<p>Confirm Password: <input type="password" name="pwd2"></p>
<p><input type="submit"></p>
</form>
Right
<script type="text/javascript">
// send a post to a backend
// backend has domain rules
// backend has test coverage and richmodels
// it is more difficult to inject code in a backend
// Validations will evolve on our backend
// Business rules and validations are shared with every consumer
// UI / REST / Tests / Microservices ... etc. etc.
// No duplicated code
function checkForm(form)
{
const url = "https://<hostname/login";
const data = {
};
const other_params = {
headers : { "content-type" : "application/json; charset=UTF-8" },
body : data,
method : "POST",
mode : "cors"
};
fetch(url, other_params)
.then(function(response) {
if (response.ok) {
return response.json();
} else {
throw new Error("Could not reach the API: " + response.statusText);
}
}).then(function(data) {
document.getElementById("message").innerHTML = data.encoded;
}).catch(function(error) {
document.getElementById("message").innerHTML = error.message;
});
return true;
}
</script>
Detection
[X] Semi-Automatic
We can detect some behavior patterns in our UI code
Tags
- Mutability
Conclusion
Use TDD.
You will put all your business logic behavior on your domain objects.
Relations
Code Smell 97 - Error Messages Without Empathy
Maxi Contieri ・ Oct 27 '21
Code Smell 01 - Anemic Models
Maxi Contieri ・ Oct 20 '20
Code Smell 90 - Implementative Callback Events
Maxi Contieri ・ Oct 7 '21
More Info
Credits
Photo by Lenin Estrada on Unsplash
I think another good principle is separating presentation or user interface (UI) from the real essence of what your app is about. By following that principle I have gotten lucky with changes time and time again. So I think that's a good principle to follow.
Martin Fowler
Software Engineering Great Quotes
Maxi Contieri ・ Dec 28 '20
This article is part of the CodeSmell Series.
Posted on June 9, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.