Code On Fire Passionate About Cool Code

15Mar/100

Code & Style Separation – Not Always so Useful

Best practices exist for a reason. And sometimes we get so carried away with following the ‘best practices’ that we lose focus of the reason why we’re doing it.

It is important to take a step back every now and then and question our best practices just to make sure they’re still serving their purpose. This is especially true when you start complicating your development arena with newer and evolving technologies.

HTML– Code or Styling?

When we look at HTML and CSS, along with technologies such as vanilla JavaScript, it is easy to categorize HTML into the realm of styling, while JavaScript is obviously code. It is then easy to generalize and state that the separation of code and style should be definitive and large.

function handleClick(){
// perform some action
}

function handleMouseOver(){
// perform some action
}

function handleMouseOut(){
// perform some action
}

<a class=”someClass” href=”javascript:;”
onClick=”handleClick();”
onMouseOver=”handleMouseOver();”
onMouseOut=”handleMouseOut();”>Perform Some Action</a>

In this case it is quite obvious how separation can abstract complex behavior and make your code more readable.

Where things become blurry is when you start using DOM manipulation via JavaScript. If you kept to the code and style separation pattern, you would never even dream of doing DOM manipulation via JavaScript because it violates that principle: Creating HTML using JavaScript just seems to go against the grain.

CSS – Code or Styling?

Same goes for CSS to a lesser degree. CSS is very obviously in the realm of styling. However, if you start using CSS selectors to add behavior to HTML elements via DOM manipulation, the lines start blurring again. In this way, CSS is often used to group a set of elements together for the purpose of behavior modification, which is in the realm of programming, not styling.

Also, CSS styling is often applied to elements based on state changes in your application. This is dragging styling back into your code, further dissolving the boundaries between code and styling.

Redefining the Best Practice

Unless we want to throw away all the possibilities that technologies like DOM manipulation and CSS grouping for programmatic purposes, we have to redefine what ‘best practice’ means in this context.

This means going back to the purpose behind ‘code and style separation’. And this is where the real debate starts.. To keep things simple, I’ll provisionally just say: Let’s assume the purpose behind code and style separation is:

  1. To allow developers and designers to co-exist gracefully. Developers don’t need to know how the styling is being done and designers don’t have to know how the behaviors are being implemented.
  2. To allow design or code to change independent of each other. This, of course, is the ideal – though never really completely achievable. There will always have to be references from the styling towards the behavior and from the code back to the styling.

Now that we have that very basic understanding of why we want to separate code and styling, we can reassemble those goals into a new best practice that achieves the goals and allows for the new methodologies and technologies we want to leverage.

I believe this topic needs a lot more discussion than just my singular input, but here's where I started looking for a solution:

Bring MVC to Browser-based Applications

As soon as you start playing with this concept, you realize that this is a little more complicated than MVC implementations in compiled languages and old-style server-side-scripting implementations.

For one, your model is now a complex interplay between local data objects (JavaScript Objects, cookies, environment variables etc..) and remote data objects (mostly in response to user interaction, these data objects need to be fetched from the server before they become available in the client-side application). The instinctive approach for any good OOP programmer is to try and treat local and remote data sources in the same manner: i.e. write a general class* describing a data source and then extend it to handle the different resources. This way you can access all data sources in the same manner and support multiple types of data.

This however quickly becomes problematic when you run into issues like different storage capabilities of the different data sources and different speed and reliability ratios between remote and local data sources. At a later stage I’ll write more in depth about my implementation of synchronous and asynchronous data model implementations including a framework for caching, retrying, look-aheads and other necessities that made its way into the code.

With regards to the controller, things also complicate themselves considerably on the client side. In a standard implementation of MVC, one would expect the controller to house the code routing the workflow into implementing the correct model tied to the correct view. This was true for PHP, but gets a little more complicated when dealing with a stateful application on the client-side. Suffice it to say, in my framework, the controller performs the function of creating, rendering, updating and destroying elements in the DOM that are bound together by a specific set of view(s) and model(s). More about that in a future post.

Views are also slightly more complicated in the browser. In the standard MVC implementation, a view only defines the actual display along with it’s styling and placeholders for data that the controller will get from the model and fill into the view.

In the browser, we have to conserve resources. For this reason, the actual HTML contained in the view might not reside locally. And once it has been loaded, it might have to be cached locally for future use. Also, it might need to have an expiration date so that we release unused memory for the browser to use on other sites while the user just leaves the tab open.

Once again, in a future post, I will discuss my framework concept of resources with built in customizable functionality catering for caching, expiration, e-tag based versioning and more.

Having those kind of resources available makes it a lot easier to implement views as a structure that does the actual rendering of the elements needed. You might ponder that the rendering should really be part of the control: in the traditional implementation, I would have to agree. But in this environment, rendering might involve more than just filling out a HTML template with values. It might involve DOM manipulation and contextually sensitive event handling. Sound’s hairy.. because it is. But it does simplify life considerably once you start implementing it. In a later post, I’ll discuss the details of how I’ve implemented the view structure in this MVC framework.

Once you have this basic structure in place, you have once again separated the coders from the designers. CSS and the view templates are left to be honed by the designers, while the code can be tended to by the coders.

Bring Semantic Events to the Browser

A second strategy I employ to keep the coders and the designers out of each others’ hair: Semantic Event management. JavaScript doesn’t really support a proper event structure that can be applied to objects. This is something you have to create yourself. And it is a good thing too, because it allows us to implement an event management structure that allows for verbose semantic events.

This means we can expose business-sensible events to the designers, making life a whole lot easier for them. But it also allows modular design based on the observer pattern, making life for the developers a whole lot easier.

Keep in mind the fact that once you start implementing events of this nature in the browser, you quickly want to start propagating events of this type between the browser and the server too. And later on, client-to-server-to-other clients. It gets real exciting.

When you approach this arena, however, you start running into issues best catered for in your event model right from the get go: blocking vs. non-blocking events, event queuing, event stacking and bursts of cached events. More on that in a later post.

In Summary

In the browser application environment, we need to re-think a lot of our ‘best practices’, because the available technologies often force us to go against our instincts. But if we pull things apart and discover the reasons behind our best practices, we can re-assemble them to support the new technologies while still achieving their original goals.

Onwards and Upwards!

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment



No trackbacks yet.