Today’s developers are
cursed blessed with a massive list of libraries and technologies for solving problems. And some of the worst sins against code stem from simply selecting the wrong tool for the job. It’s recently become clear to me that when considering tools, the risk for picking the wrong tool for the job is strongest near the boundaries. Consider some common technologies for building web applications today. Each technology has a specific purpose.
- HTML provides semantic markup of our content
- CSS separates our styling from our markup
- Server-side languages manage the business logic
- SQL is useful for RDBMS data access and manipulation
And here’s the thing: It’s the boundaries and interactions between technologies that get people in trouble. Let’s discuss the interactions between each of these technologies and common situations where developers select the wrong tool for the job.
[pageview url="http://jsfiddle.net/housecor/EkNTn/embedded" height="245"]
Note how the HTML for generating a row is buried within the for loop and set to a variable called
[pageview url="http://jsfiddle.net/housecor/3cXwh/embedded/html" height="100"]
HTML and SQL Boundary
Here’s two simple examples of ignoring the important boundary between data and HTML:
SELECT '<strong>' + Username + '</strong>' FROM Users
Relational databases should contain raw normalized data that can be leveraged for a variety of purposes. Thus, storing HTML in the DB or injecting HTML in query results as shown above is problematic. It binds the presentation and data storage together making reuse difficult.
One common exception is content management systems where users must be able to store and manage HTML which is persisted in the database. This scenario sacrifices data reuse and normalization for end user management power. Think very carefully about saddling data with presentation concerns since it radically reduces flexibility by “hard coding” in the presentation. Mixing presentation and data should be avoided. They’re separate concerns and should be treated as such.
HTML and CSS Boundary
It’s a very similar story with the HTML/CSS interaction. Avoid doing this:
[pageview url="http://jsfiddle.net/housecor/6gT8f/embedded/html" height="75"]
It’s tempting to place styles inline in HTML, but this mixes semantic markup with style. These are separate concerns and doing so eliminates the opportunity for caching and reuse of CSS and hinders maintenance down the road. The DRY principle applies here: If you’re going to use a style in more than one spot, it pays to declare the style once in a separate stylesheet.
SQL and Server-side Language Boundary
It’s easy to create highly dynamic SQL in a server-side language like C# using strings to generate SQL statements, but stored procedures and ORMs often provide a safer and more elegant approach to generating dynamic SQL. Writing dynamic SQL in strings opens the door to SQL injection vulnerabilities and eliminates the opportunity for DBAs to manage and enhance the performance of such queries. SQL in strings also introduce a high risk for run-time errors in the application when schema changes occur. ORMs provide a strongly typed interface to the database and will thus fail to compile when the schema becomes out of sync with existing database queries.
So before you dive into writing that next line of code, think twice – are you near a boundary? Does a more elegant solution exist on the other side of the boundary? Clean coders should strive to stay native: – the file extension should be a good indicator of the technology that lies within.
If you’re interested in learning more about writing clean code, check out my new Pluralsight course: Clean Code: Writing Code for Humans
See other boundaries to consider? Chime in below or join the discussion on Hacker News.