Last week I mentioned receiving an email asking what a software engineer typically does. In that post, I talked about defending technical decisions. Today, I am continuing this thread by talking about design. In many companies and projects, design occurs before any development is allowed to start. This is considered “Big Design Up Front” or BDUF, and it is now considered evil by all agile practitioners. Contrary to many anti-agile comments, agilists do practice design of all of their work, it just happens at different times and in different places. In general terms, design is the activity of planning the functionality of a system, including the inputs and outputs of the system where system could mean an entire application or a very small part of an application or even how various applications work together.
Application or System Design
When many people talk about design in software engineering, they are talking about the design of applications or systems like a CMS application or an email client. This is where you see a lot of BDUF style processes because you really cannot start coding something of this magnitude until you have an idea of what the parts are. Some people may call this application architecture, which is a better description, with the understanding that the architecture is only a very high level description of what an application may contain. Typical design tasks are normally for much smaller parts of a large system.
Component is meant as a very generic term for some portion of an application that is fairly self contained and can have standard interfaces or entry points created. If you look at a CMS system like WordPress, there are several components. First, there is the administrative user interface that publishers use every day, which could be made of several components itself. There are likely theme and styling components that will control how the publishers site will appear to various readers. There is a persistence component that will control how post content and media is stored and retrieved. There are probably several other components that I am not mentioning as well, but I am not here to design a CMS.
System Interface Design
As can be seen from the examples in the Component Design section above, many components within a system will need to work together. For the CMS example, the theme components need to know the general structural items of possible post content, but it does not need to know the actual post content. The interface between the theme component and the post editor and persistence component is already defined in the HTML and XHTML specifications. Having a known and proven specification like this can make systems significantly easier to create. However, if you wanted to create a plugin model for your CMS, you need to create an Application Programming Interface (API) for plugins. Once you have published this API, plugin developers can use it to create interesting functionality for your CMS and have an expectation that things will work properly.
For some systems, external data is a requirement in order to function, so the interface design is actually the format of the data as well as how to load the data. For example, in most CMS systems, there is the option to create an RSS feed of your posts. RSS is only a standard data format that is used by content publishers and RSS reader applications like Google Reader. Preferably, these external applications will want to be informed when new content has been published. For this purpose, the Ping services were defined and have been used by many services like Technorati. Ping defines the interface for notifications that your content has changed. In this example, we saw two separate interfaces defined, one for content publishing and one for notifications.
User Experience Design
User Experience Design is becoming a very hot topic lately due to the capabilities we now have in the web browser. I am also lumping into this topic basic web design and graphic design as they are really all parts of the same thing. I am considering graphic design to be the true graphics of the site, like logos, icons and the various images on the page. This may sound like a small part, but poor graphic design can kill the usability of a site and thus make it fail. Web design gets closer to how the entire page layout looks and how the navigation of the site works. Some of the styling for a site is a combination of web designer and graphic designer work.
Time Dependent Design
There is one are that I wanted to highlight, and that is the design of systems that are dependent on time. Back in the dark ages, or when mainframes were the only state of the art, batch systems were incredibly important. Batch systems are those applications that run at specified intervals, like once per day, and process large quantities of data. These systems were important because they required a lot of processing power and needed to run when people were not interacting with the system. This is still important today with web applications. A more current example is the way that Technorati calculates their authority numbers. I am not sure how it works in their newer incarnation, but the old system updated your blog authority once per day.
Real time now has multiple definitions. People are using the real-time term for the interactions on many social media sites. I like to call this “near real time” as there are several network latency issues within all of those systems as well as all of the data transfer between applications like Facebook and Twitter. However, even near real time systems have timing implications. How do you scale a near real time system to the size of 350 million users? How do you transfer data across several different delivery mechanisms like your website, an XMPP connection, an API call and a continuously connected network socket in near real time?
Embedded systems are the original real time systems. These are the systems that are running all of the sensors in your car and other physical devices that have digital displays. Think of the implications of real time systems. In your car, you likely have an antilock brake system (ABS). This system is based on various sensors and the data being reported. What if this was not real time, but only nearly real time? We are talking about the difference of a tenth of a second and 2 seconds. When you are talking about the brakes on your car responding correctly, that difference is enormous.
What Else Is There?
So, I highlighted some major groups of design activities. Hopefully this has given a good overview of design activities, no matter how general it was. The problem is that within each group there are various specialties that require specific knowledge to design properly. Scaling web sites is a major industry now because everyone wants to be able to handle millions of hits per month. Good persistence models are required for many applications, but what if you are dealing with terabytes of information? There are tons of other areas that have different requirements as well. What other major design disciplines did I miss?