Question

I've set myself the task of implementing a real time MIDI application. Like all the other software I've written to date, I began by coding. I implemented a tiny GUI (GTK2) application that can control the transport state of the Jack Audio Connection Kit and its clients.

I have never written a real-time application before, and have only ever written one multi-threaded program. Both of these details combine to make this a substantial challenge for me as all the software I have written to date, has not required me to design it first. I've only occasionally needed a pen and paper to work things out.

This project however, won't let me proceed by coding. But I know next to nothing about software design, I am self taught (discounting a 2 yr computer studies course in the mid 1990s). I've always worked stepwise, getting something working and then building upon it.

During my research I've come across the Model View Controller pattern but I'm finding it really difficult to not think about details, and can't find any foundation to build upon without finding problems which bring it all tumbling down.

I need advice to get past this block. I need to stop finding distractions which loose my train of thought. This is one of the distractions. How do I get past this block?

Was it helpful?

Solution

In very broad terms, "software design" is the process in which you decompose the problem at hand in a series of module, and specify what each module responsibility are, and how each module should communicate with the other modules (if at all).

There are various ways to proceed with this activity. Considering this would be your first attempt at it, keep things as simple as possible: grab some paper sheets and a pen.

First step: write down a list of tasks that your new application must be able to execute. After this try to group the tasks in different sets that you think belong logically together.

For each subset, find a name, write it on blank sheet (one for subset) and describe what the module does in a little more detail, including which type of data it should work on and/or exchange with others. Each of these is a "module design paper"

On another blank sheet draw a box for each subset, label it with the proper name, and try drawing arrows from one box to the other, each arrow should have a name and represents one of your module calling another. Let's call this your module "interface design paper".

Double check your modules description with the interfaces they should offer to other modules, and see if this requires change to the original task list and how this affects the data they manage.

Modules can be subdivided iteratively if they look too complex/big to you. Just draw another interface design paper if you split a module in submodules, and remember that the sum of the submodules should be able to carry on all the tasks you had originally envisioned for your module, and be able to answer the requests of the rest of the system.

See also CRC cards for more detail.

OTHER TIPS

The answers already written for this question are great but none of them mention the most unique part of real-time software development: the real-time technical requirements.

You need to figure out exactly how responsive your software needs to be, how large of a memory footprint it may hold, how fast boot-up may be, and how large the executable may be. The if you're on a normal PC, the memory requirements may not be as important to you, but the run-time speed requirements will be important whatever your target platform is.

If your high-level technical requirements are "good enough that the user is happy", then you'll only have to worry about the low-level technical requirements -- basically, what your target computer, your target OS, and your third-party libraries can handle.

It sounds like you've written some low-level code already. I would recommend writing the rest of your hardware/OS/library interface code and time each piece of it, both for error conditions and the happy path. This will give you a much better idea how your code should treat each of its interfaces. (For example: The timeout on this utility call is long enough to make my application back up! I'd better see if I can shorten the timeout or have some better error-checking before I call it!)

Finally, most real-time software is written as a loop something like so:

while( program_running )
{
  // This period needs to be long enough for you to do your work
  //  but short enough that your user doesn't think your program
  //  is choppy. Anything better than 50 Hz is usually good enough
  //  for an application with a human interface.
  wait_for_short_period() 
  check_interfaces_for_new_data()
  update_model() // or state machine
  update_outbound_interface() // the speaker, monitor, whatever
}

There are variations on this (periodic callbacks instead of waits), but that's the general idea.

One way would be to discuss your requirements and very ruffly scetch out a design with someone who is familiar with designpattern and designing software. During this process you could discuss the concepts of the applied designpattern.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top