Friday, April 30, 2010

jQueryUI Hovering

The jQueryUI user interface library offers developers building interactive web applications not only a set of widgets to use, but also, a set of effects. An effect, in this context, can be thought of as a transition from one state to another by a user interface component. As an example, imagine you have a button element that is in a hidden state. Showing that button would be considered an effect, albeit, a very basic one. A jQueryUI effect adds some appeal to these transitions. In essence, jQueryUI effects can be thought of as user interface component state transitions that enhance the overall user experience.

Another nice feature in the jQueryUI repertoire is the CSS framework used for changing the look and feel of the widget set. This framework allows developers to choose an existing theme or to build their own. CSS classes within the framework are flexible enough that they aren't restricted to the jQueryUI widgets. Your user interface isn't going to be composed entirely of widgets. You can use these CSS classes to help give the non-widget elements of your application more of a theme.

An example use of applying the jQueryUI CSS framework to a non-widget element would be using the ui-state-hover class. Lets say we have a list of li elements. The idea is to add the ui-state-hover CSS class to each li element when the user hovers over it. This is fairly straightforward to do with the jQuery addClass() and removeClass() methods. You call these methods inside a hover in and a hover out callback respectively. Example callback functions are shown below.
function hoverin(element){
jQuery(element).addClass("ui-state-hover");
}

function hoverout(element){
jQuery(element).removeClass("ui-state-hover");
}
jQueryUI allows us to add an interaction to the addClass() and removeClass() methods. Typically, we would only want to add an effect to the addClass() for hover in events. Otherwise, the user interface tends to look too busy. Here is the same example modified to introduce an effect when adding the class. The the visual changes made to the element as a result of adding the class will take place over a duration of 150 milliseconds rather than instantaneously.
function hoverin(element){
jQuery(element).addClass("ui-state-hover", 150);
}

function hoverout(element){
jQuery(element).removeClass("ui-state-hover");
}
There is, however, one problem with this approach. There is a chance that the ui-state-hover class will not be removed from the element by hoverout(). This is because the user can, and most definitely will at some point, hover out of the element during the 150 millisecond effect duration. Keep in mind, the element doesn't actually have the ui-state-hover class until the 150 millisecond effect duration is up. When hoverout() is called during the effect, no class is removed because it hasn't been added yet. Below is a work-around for this issue that involves using a secondary state class.
function hoverin(element){
jQuery(element).addClass("app-state-hover");
jQuery(element).addClass("ui-state-hover", 150, function(){
if(!jQuery(element).hasClass("app-state-hover")){
jQuery(element).removeClass("ui-state-hover");
}
jQuery(query).removeClass("app-state-hover");
});
}

function hoverout(element){
jQuery(element).removeClass("ui-state-hover app-state-hover");
}
Here we introduce a new class called app-hover-state. This class will be used to track the hover state of the element since we are now using an effect. The hoverin() function will now add this class to the element before starting the visual effect. The hoverout() function will now remove both the ui-state-hover and the app-state-hover classes. This is important because even if the effect hasn't yet finished when the user hovers out of the element, the app-state-hover class will be removed from the element. The visual effect in hoverin() now has a callback function that is executed when the duration of the effect has completed. This callback will remove the ui-state-hover class if the app-state-hover class has been removed. In this case, if app-state-hover has been removed can only mean one thing; a hoverout() call was made during the duration of the effect and the ui-state-hover class should also be removed.

Tuesday, April 27, 2010

Passing URIs

Uniform Resource Identifiers (URIs) are what enable us to find things on the web. These things refer to a resource, uniformly identified by a string. A resource is any digital media that has been made available on the Internet. At a higher level, search engines are what allow us to find resources that live somewhere in the web. Without a URI, there would be nothing useful for the search engines to display in their results. Additionally, it would be impossible for search engines to crawl websites without theURIs that make up the structure of the site.

APIs can be built with a set of URIs as well. These URI-centric APIs are sometimes referred to as RESTful APIs. RESTful APIs have a close association with the HTTP protocol. Because of this we can pass parameters to resources through GET or POST requests made by a client. But these are often primitive types that can be represented as a string. For instance, if I'm using someAPI to update my user profile, a numeric user ID might be a POST parameter I need to send. This is necessary so the application knows which user to update. But what if I were able to pass an entire URI as the identifier for the resource I want to update? Does that even make sense? Well, lets first think about how applications identify resources internally.

The most common way for a web application to identify a resource internally is by a primary key in a database table. This key is typically an integer value that is automatically incremented every time a new record is inserted. This key is unique for each record in that table. This makes the primary key of a database table an ideal candidate for using as part of a URI. You'll often see integers as part of a URI, for instance "/user/4352/". There is a good chance that the number is a unique primary key in the database. This uniqueness maps well toURIs because every URI should be unique in one way or another.

One potential problem with using primary database keys in URIs is that different records in different database tables may share the same key. This doesn't necessarily weaken the uniqueness of the URI because it is still referring to a different type of resource. Consider two database records in two different database tables. These records both have the same integer primary key value, 5. TheURIs for these two resources are still unique because they are referring to two entirely different concepts. So the first URI might be "/user/5/" and the second URI might be "/group/5/". But what if you don't care about the resource type?

A canonical URI might be composed of a UUID instead of the primary key of a database table. UUIDs themselves are unique and may refer to any resource. That is, a UUID doesn't need a context in order to be unique. If our above two URIs were to use UUIDs, they might look something like "/user/cadb1d94-5305-11df-98a5-001a929face2/" and "/group/d8eee85c-5305-11df-8d08-001a929face2". As you can see, we really don't need "user" or "group" as part of the URI. We could refer to a resource canonically with something like "/data/cadb1d94-5305-11df-98a5-001a929face2/". This could refer to either a user or a group. This can be both flexible and dangerous.

Having a canonical URI based on a UUID can be flexible because the client requesting the resource doesn't need to know the context. The client might have acquired this URI and has no idea what exactly it is a representation of. Even with just theUUID , the client now has the ability to discover the type of resource this URI is pointing to based on the data it returns. This can also be dangerous for exactly the same reason. If a client doesn't know how to handle the data returned by a canonical URI, chances of the the client malfunctioning are higher. The data representations returned by URI resources are a lot like interfaces; different data types can still provide the same interfaces by having a subset of common keys.

The location part of a URI might also be useful for passing as parameters to web applications. Until now, I've only been talking about the path in which the server must look for the resource. But this is making the assumption that the resource in question still lives on the same server. By only passing primary database keys or UUIDs as parameters, we leave the location aspect out of the equation. It might be more flexible to pass a full URI as a parameter. Even if the URI location is pointing to the same location in which the request arrived. It really isn't a big deal for a server to check when processing requests. If the resource lives here, we simplydissect the URI and process as usual. Otherwise, we forward the request to the appropriate location. I realize I'm oversimplifying this a little too much but the idea is to think about passing wholeURIs as parameters, not so much the details of how we should go about implementing a full-fledged distributed computing platform.

So remember that canonical URIs composed of UUIDs can be useful when treated with care. If context is important, don't use them. Stick to using primary database keys if it helps keep things simple. Try experimenting with a simple web application that will accept a full URI instead of an ID string of some sort. A flexible solution might even accept either or.

Monday, April 26, 2010

Value In The Cloud

Cloud computing is definitely one of the top buzzwords in technology today. Yet, there doesn't seem to be any consensus on what it all means. Yes, many people have there own opinions or definitions of the topic, each slightly different from one another. There aren't many agreed-upon components that make up cloud computing technology. At least one thing remains unclear; where is the value for the end user in all of this?

To better understand the some of the more obscure value propositions offered by cloud computing technology, we need to understand the shortcomings of the current technology available. That is, the current technology that allows people to make applications available over the web. There is no shortage of hosting providers out there that make it easy for both businesses and individuals to deploy an application over the web. In fact, these providers often have the application pre-built and ready to go. It really depends on what you are trying to do on the web and if it falls within the realm of the commonplace, you're in luck.

Once you want to start requiring customizations that these pre-built applications simply cannot provide, it is time to build something. If you're not a developer, you need a team of them to build you a web application that does what you need. This means that you need to figure out which framework to use, what platform it will run on, etc. These are all details that just don't interest non-technical folks. Nevertheless, it is a reality in order to survive these days.

Whether you use a pre-built, or a custom-built web application, having a presence on the web is the ultimate goal. The Internet has an ever growing user base and without if you're not there, you'll go unnoticed. The web is a big part of cloud computing but that isn't the whole story. What about desktop applications? Do they simply have no place in cloud computing? Like it or not, desktop applications are still in heavy use today. Some development efforts involving re-creating the same desktop applications that will run in a web browser. This is nice to have but it would also be nice if we could move desktop applications into the cloud without re-inventing the wheel.

Virtualization allows us to do just that. We can run our desktop applications inside a virtual machine without having to re-write the entire program. We can also access these virtual machines remotely so we don't necessarily need to see the user interface inside a web browser, even though it is possible to do so. Virtualization is another key component of cloud computing. In fact, it is probably the key to differentiating cloud computing from a more traditional web application deployment. Virtual machines can be created an destroyed upon request. They can also be moved around to different physical nodes without interruption to the running application contained within the virtual machine.

There are several well known virtualzation technologies available today that service providers can use to their advantage. If they have the hardware, they can make the these cloud computing resources available to their customers. One shortfall to using these virtualization platforms is that they are missing several key components necessary in order to provide a cloud offering. For instance, we're doing some interesting things here at Enomaly with our cloud computing platform, ECP. ECP offers features that are essential to service providers such as multi-tenancy and a highly-customizable user portal.

Having said all this, what is it about cloud computing that really sets it apart from a more traditional web application deployment? That is, where is the value? I believe the value of cloud computing is enabled by virtualization. This gives us a level of freedom to do what we want with our deployed applications previously unheard of. What can be now be done with cloud computing can also be done with a more traditional deployment, it will just cost a lot more. When you loose the ability to create you're own environment precisely as you need it, it suddenly becomes much more difficult to do things.

Virtual machines are their own self contained environment so they can also be copied. That is, once you have an environment setup the way it needs to be setup, that same work is never done twice. You simply clone the virtual machine if you need more capacity, or for some other reason. What this means is that you never have to do the same thing twice and that translates to much time saved.

This customization work can even be performed by the cloud providers themselves. This gives them an opportunity to not only provide the cloud computing services, but to also add value by providing appliances to their customers. These appliances are virtual machines that have been built for a common purpose. Typically, they will have some commonly used application stack installed and minimally configured.

In summation, there is value in cloud computing that is often overlooked because it is obscured by the more technical aspects of trying to define what exactly cloud computing is. The hidden added value cloud computing offers is sometimes hard to see unless you're using the technology that makes it possible. Mind you, this technology is still in its' infancy but the end results all look very promising.

Friday, April 23, 2010

Designing Code

Designing code is one of the most essential jobs of a programmer. That is, programmers do more than just design code. They also write it, document it, and read it. Hence, the term writing code. You never hear a programmer say they're going to spend some time designing code. It is writing code that matters. You could design software for several months and it wouldn't make a world of difference in the mind of a programmer. If no code has been written, no progress has been made.

This is where programmers actually are designing, while they are writing code. When they are sitting there with an editor open, they can see what needs to happen in order to solve the problem at hand. In fact, it is even easier for programmers to debug existing code rather than start from scratch and right something completely new. There is something about code that enables us to see structural and behavioral design and that serves as a reference in our mind.

But every programmer has a different logical representation of the system at hand in their own mind. Two perfectly acceptable solutions to a given problem may be completely incorrect to two opposing programmers. How can this be? Even in the same programming language, two wildly differing solutions are available to solve the same problem. The problem is that in software development, the problem at hand is never just the problem given to us. There are too many environments in the computer universe in which software may run.

These problems given to programmers to solve are only the half of it. The stakeholders really don't care that system X doesn't support interpreter Y and therefore cannot use language feature Z. Programmers will find a way around these limitations. But the problem is that unless you are the programmer doing the implementation, you really can't wrap your head around the full details of implementing a full solution. It really comes down to the fundamental software development concept of having a separation of concerns. Stakeholders in software development projects don't necessarily need to know all the low-level implementation details. They just need to be aware that they exist.

This isn't always the case with stakeholders. Imagine you had an environment in which to implement their solution aligned with what the stakeholders sometimes envision; you write the code to solve their problem and there are no implementation surprises. In a scenario like that, writing code to directly solve their problem is a feasible approach. But that will most definitely not happen any time soon, if ever. So in the mean time, we are stuck dealing with implementation details that fall outside the scope of the business problem.

When programmers write code, they have two tightly-coupled problems. There is the problem of making the software do what it was intended to do, the business problem. There is also the problem of the the other, unforeseen implementation details, the implementation problem. When we begin to write code for the business problem, the implementation problem doesn't really exist yet. How can it? These are unanticipated problems. They don't come into being until you can see them. This makes sense to a certain extent because if you start thinking about potential implementation problems too much before some design activities have started, no code would ever be written.

So what is the real benefit to separating these two problems, if any? It doesn't seem very obvious what the exact benefit of separating the business problem from the implementation details is at first. But one problem with not doing so is apparent. Since implementation detail problems do not really exist until the code is being written, they often affect the business problem implementation once they come about. That is, if a programmer spends time designing some ideal code for the business problem, depending on how specific that design is, an implementation detail problem could put the whole design in jeopardy.

Since code is so tightly coupled with the implementation of a running system, a good way to represent the business problem is with a model. A model is not part of the running system but it is an artifact of the process used to create the running system. UML models are a good way to represent any given software system. They can show almost any level of detail one might be interested in seeing. There is, however, a similar problem with models. You have the ability to start getting into implementation details.

This goes to show that modeling your code before actually writing it isn't a magic way to fix your code design. The common problem with creating models is that they tend to evolve too quickly without writing any code. If the level of specificity in your model gets too high, you've not only taken a waterfall approach but you're also taking a risky path by assuming there will not be any seemingly small implementation issues. Models are a good way to start off the business domain model as long as they are general enough. The level of specificity cannot be too high before code is written. Even then, it doesn't need to delve into too much detail just for the sake of it. Model details are better left out until they become a requirement.

Now lets take a step back and think about this for a moment. We now have a business problem that we're going to solve with software. In order to build this software, we need to write code that will implement the solution to the business problem. We know that there are going to be changes because our computing environments are disparate enough that we has humans cannot predict exactly how our code will behave. In order to help distance our business problem from any potential implementation problems, we build a high-level model of the business problem.

We should now be all set to start coding and hope for the best, right? Starting to code is definitely the right answer. Hoping for the best suggests an uncontrolled level of uncertainty. This can be at least somewhat controlled by expecting unexpected implementation details. Remember that your code and your model will always change throughout iterations of the project. The model you build will also have some overlap with the implementation. This is necessary unless the stakeholders are only expecting a model of the software and not the software itself.

Once these implementation detail issues do exist, is it worth modeling these issues? Only if it is separated from the business problem within the model somehow. It might even make more sense to create a completely separate model for implementation details. But only if it adds value. Modeling the nuances of implementing software isn't an exact science because chances are, these same details will become irrelevant in five years.

To sum this all up, remember that there is value in upfront code design centered around the business problem at hand. This doesn't necessarily mean modeling, it could be as straightforward as prototyping a command line interface simply for the purpose of testing how well the abstractions in your domain work. Modeling does offer a visual design aspect that often cannot be gleaned from code itself.

Thursday, April 22, 2010

Cheating Computer Science

Apparently new computer science students these days love to cheat. I wonder how this will affect these students once they have completed school and have jobs. Will this rigorous process of plagiarism detection lead to less code reuse and constantly reinventing the wheel?

Thursday, April 15, 2010

Programming Sprints

Here is an interesting question, how many hours in a given week can you program? If you've got your head down and the code is just flowing out nicely, it isn't difficult to be very productive for hours at a time. But these sprints come in bursts. This code inspiration needs to come from somewhere. That is the other part of programming that isn't viewed as productivity. I'd say at least half, if not more, of a programmers time is devoted to reading. Either other code, a specific technology, technology in general, or something completely unrelated. Code sprints are spawned from doing this, not perpetually writing code.

Monday, April 12, 2010

Gosling Resigns

The "Father Of Java" has resigned from Oracle. It seems like a common trend since the acquisition and he is probably better off. Best of luck James.

Thursday, April 8, 2010

The Face Of Bad Code

Lets face it, we've all written bad code at one point or another. If we hadn't, we probably would never release any functional software. Remember, code that isn't ideal doesn't equate to code that doesn't run and help someone else accomplish some task. Code can always be re-factored, and, it should be re-factored.

I often find myself testing my own software from and end user perspective and thinking about the code that is running when I perform certain actions. I think "well, it works, but just barely". I have to force myself to think "well, it works, and that is all the user cares about; it can be re-factored later".

Don't be tempted to re-factor before you get something functional into the hands of the end users. Make notes on what doesn't work well and fix it in conjunction with the user-provided feedback. If you don't release, you don't get the feedback. Only you as the developer know what needs to be re-factored, only the end user knows how well your software solves their problem.

Wednesday, April 7, 2010

Atom Syndication

The Atom Syndication Format is the standard nowadays not just for news feeds, put any type of feed that may be updated. If you're thinking about creating a new feed for your site, before deciding on RSS, consider the limitations. Especially when it comes to the type of content that may exist in the format, Atom is much more flexible than RSS.

Language Popularity

According to the TIOBE index, the C programming language is back at number one for popularity. This comes as no big surprise as the language has thrived for decades due to it's simplicity. Also, according to the index, Python and Javascript are down. This seems strange since these two languages are huge in the web application space.

Python Abstract Class

Many object-oriented programming languages, such as Java, allow the developer to state explicitly that a given class is abstract. Abstract classes cannot be instantiated directly. Instead, only descendants of abstract classes may be created. So how does this benefit the design? The presence of an abstract class means that a specialization must be made because the abstract class is too general to fit any particular purpose. Abstract classes might not provide an implementation of it's operations.

In Python, there is no way to explicitly restrict a class from being instantiated. There are, however, ways to make a Python class implicitly abstract. A common use of abstract classes in Python is to define an interface. For instance, here we define an abstract class and a concrete class.
class AbstractClass(object):

def first(self):
pass

def second(self):
pass

class ConcreteClass(AbstractClass):

def first(self):
print self.__class__.__name__

if __name__ == "__main__":

obj = ConcreteClass()
obj.first()
obj.second()

In this example, AbstractClass defines two methods that aren't implemented. The ConcreteClass class inherits the abstract class but only redefines one method. Yet, we are invoking both methods. So one method does something while the other one does nothing.

This is goo in that the expected interface is supported when the object is put to use, but this approach can lead to bugs that aren't trivial to track down. It isn't at all obvious to the clients of these objects that one of the methods isn't implemented. Consider the following approach.
class AbstractClass(object):

def first(self):
raise NotImplementedError

def second(self):
raise NotImplementedError

class ConcreteClass(AbstractClass):

def first(self):
print self.__class__.__name__

if __name__ == "__main__":

obj = ConcreteClass()

try:
obj.first()
obj.second()
except NotImplementedError:
print "Not implemented. Good to know."

Here, AbstractClass will raise a NotImplementedError instead of doing nothing. This way, it complains to clients of it's instances that it can't do anything with the requested behavior. This certainly makes debugging a lot easier while maintaining the ability to define abstract interfaces for classes.

Tuesday, April 6, 2010

Memory Management

There is a new approach to memory management that claims to be able to speed up applications. Actually, it has the potential to but nothing is carved in stone. It would be interesting to contrast the performance gained versus the stability lost after implementing this method.

Optimizing For Readability

How does one measure the readability of a given piece of code? What makes this especially challenging is that developers all have their own unique preferences and style when it comes to reading and writing source code. But readability isn't necessarily the same thing as coding style. Readability should trump style preference.

There are certain aspects of code that make it readable. For instance, meaningful variable names aren't that hard to come up with and make a world of difference when someone else needs to read your code. Adding some space rather than cramming constructs together will always increase readability. At the same time, however, conciseness is always a readability enhancement.

Simple things add up in the long run. There are only larger structural pieces of code that affect code readability. For instance, the location of a class, the modularity affects the difficulty of locating things. These are larger concepts that are more closely related to style than readability. Readability in this context refers to what the developer can see on the screen at any given time.

Software Artifacts

What exactly are software artifacts? Put simply, a software artifact is a file that exists as part of some software system. The most common software artifacts are source code files and executable files. What isn't usually considered an artifact, however, is the logical design of the system.

It sounds strange that the system design isn't considered a software artifact but in most cases, it is the truth. The design of any software system is implicitly captured in the source code files. Because without the system design, there wouldn't be any source code files because they would have no reason to exist.

If the software system is modeled with UML, shouldn't the model files themselves be considered software artifacts. I would like to think so. Especially since they do a better job of making the system design explicit than the source code does.

Additionally, UML models can also make the software artifacts of the modeled system explicit. That is, you can have meta-artifacts. This of course assumes that the model itself is considered an artifact. If it sounds too confusing, it really doesn't have to be. UML artifact elements can help illuminate where in the model these artifacts, usually source code files, are expressed as a logical design.

Monday, April 5, 2010

Hashing URIs

Clients of URIs often need to specify some sort of client parameter that is returned as part of the HTTP response. This parameter is intended to preserve the application state by encoding it into the URI.

A common practice is instead of passing the client state as a GET HTTP parameter, to provide the client state as a hashed URI segment. This segment would represent the client state. It is a preferable URI practice because the application state is still encoded as part of the resource URI but doesn't need to be sent to the server.

One aspect of this practice to be weary of is mistaking application state for resources. If the intent is to use the application state as the hashed URI segment, only use it for application states and not data resources.

Application Portability

In this entry, we see an impressive example of application portability. The application runs on several platforms without any modifications to the code base. Portability is huge these days with the number of mobile devices on the market. How what is the best way to achieve optimal portability? Should this be the responsibility of the application or the platform on which it runs?

Interpreted programming languages like Java and Python attempt to solve the portability problem by producing hardware-independent byte code. This byte code is then executed by a executable interpreter. Here, it is the interpreter's responsibility to maintain portability. And they do a good job for the most part. But applications still aren't aren't fully platform agnostic.

So if all this hard work is done by the interpreter for dynamic programming languages, how do we achieve platform portability with compiled languages such as C++? Here we can use libraries that help developers with platform independence. For instance, Qt is a largely platform independent library. With compiled languages you have more control but the trade-off is that much more complexity is necessary for these applications to run on more than one platform. At least with the same code base.

Query Superclass

Throughout the object-oriented software development process, you're likely to find new and better ways to query object properties. These properties aren't necessarily the defined attributes for the object's class. The methods used to query these attributes are often obvious enough. What about derived properties? These are computed properties and they sometimes go unnoticed until some iteration further down the line.

Is the best approach to adding these newly discovered query methods to add them to the class directly? Probably not because you are adding new responsibilities directly to the class. There are exceptions to not not doing this. For instance, there might be some aspect of the objects that you may want to query that are painfully obvious and were missed for some reason. Also, if the class is somewhat specialized already, the newly discovered query methods may only apply to instances of this class.

When more general query methods are discovered, we can use the inheritance mechanism to extend the functionality of our class. This can go in either direction. You can define a specialized version of your class that is a child of that class. This class would then define the new query methods. The problem with this approach is that rather than being more generalized, you are increasing the specificity level. This is fine if the newly discovered query method are specific to your class. More often than not, however, derived properties that are computed can often be applied to a group of disparate classes. If this is the case, spending the time to develop a highly-reusable query super class may be worthwhile.

Thursday, April 1, 2010

Unixkcd

XKCD now has a Unix style command line interface. Very cool. More web interfaces need command lines.

Message Catalog Loading

With web applications, does it make sense to load the message translation catalog into memory and keep it there? Or, does it make more sense to keep reading the file from disk? Obviously from a performance perspective, repeatedly reading the file from disk is unacceptable. But from a usability perspective, it isn't exactly desirable to have to restart the service in order to correct a typo. But that seems to be the limitation these days.

What would be really neat is some kind of administrative message catalog editor that edits both the file on disk and the in-memory labels.

Topeka

Google has officially changed its name to Topeka. I found this link by "Topekaing" April Fools.

jQueryUI Dev Tool

The jQueryUI library is a themable user interface library. As such, all themes are CSS based and can be interchanged within the same application. The jQueryUI dev tool is a simple bookmark you can use to develop your own themes or to see how your application will look with an already existing theme. There are plenty to choose from. What makes this to interesting is that this tool works well even for production systems.