views:

343

answers:

5

Hi,

I have been programming for a couple of years and am now studying computer-science at university. Every time I have coded something, I did so by starting up my editor and improvise. Writing methods, classes as I go. Off course, I think about it beforehand, I take out sketch paper and write my ideas down, do a little list of things to do, etc. This can work for writing little bits of code or simple and relatively small software, but how about complex ones?

When you want to make a complex piece of software, how do you blueprint it? Architects blueprints a building before starting any real work on it, and they do so by following standards. I expect programmers do to, but I have never heard of it. What are the methods, the tools and the steps that are being used to do so.

I don't want opinions.

I'd like something specific: Charts? Maps? Tools? Techniques? Step-by-steps process? ...

+3  A: 

Architects blueprints a building before starting any real work on it, and they do so by following standards.

That's because with many fields there is the exact knowledge beforehand. What is involved, which rules, what laws of physics, what regulations to consider. That's why it is possible to blueprint the whole thing up to the last nail.

With software it is very much different. You can do whatever you want. You can reach anything and nobody can tell you that it is good or bad. Because there are no standards. Only subjective opinion.

Every time I have coded something, I did so by starting up my editor and improvise. Writing methods, classes as I go. Off course, I think about it beforehand, I take out sketch paper and write my ideas down, do a little list of things to do, etc

That's how it usually done. You can experiment with some frameworks, tools, architectures before starting with the project. For example, do a few test projects to learn what you need to attempt to "blueprint" your future software.

I don't want opinions.

Every answer here is going to be an opinion. Because there are no standards to fall back to. Experience and opinion.

I'd like something specific: Charts? Maps? Tools? Techniques? Step-by-steps process?

What has worked for most is:

  1. Involve users from the beginning into your project. Collect regular feedback to adjust your course.

  2. Be agile and follow some kind of iterative process. First, you sketch the UI. Get the feedback. Then you implement some general functionality. Get feedback. Adjust your course. Implement some more features. And so on. Sooner or later there will be enough meat to go v.1.

If you absolutely need some strict guidelines, then use UML (Unified Modeling Language) for charts and diagrams and adopt the RUP (Rational Unified Process) or its analogues. You can follow Scrum, there is also some organizational activity ivolved.

Developer Art
+2  A: 

First of, I like Mind-Maps to visualize what that piece of Software should do and what the relevant constraints are (technology, performance, integration points etc.). I like to use FreeMind (OSS) for this purpose. I think there's a large difference between just talking about requirements and writing them down, because the latter forces you to think about them more precisely. Especially if you are unfamiliar with the problem domain.

By the time I am done with this, I do usually have a pretty good blueprint of things in my head and start coding right away. If not, I start sketching things out on paper in a pseudo UML notation. UML is a modeling language, specifically intended for this purposes. It defines common visual representations for classes, methods, interactions flows etc. It's not uncommon your design will change a little over time as your insight into the problem increases while writing the code. It's important not to hesitate to adapt your design every time this happens.

Depending on the size of the problem to be modeled, you might find it helpful to use an UML tool. But usually they are very rigor and un-flexible. Especially when I decide to change the design of my code, my UML Diagrams get out of sync very fast. What I do really like is the Visual Studio Class Designer, because it works the other way round, I can drop my code on it and it generates a visual (simple UML) representation of it.

Johannes Rudolph
+1 mind maps are amazing
munch
+1  A: 

You should probably take a lecture on Software Engineering if you are interested in the design and development process of software.

The other answers already gave some hints with that respect; however, an important aspect that should not be neglected is that before starting your design you should actually write down what your software is supposed do in a form of a software requirements specification:

A software requirements specification is a complete description of the behavior of the system to be developed. It includes a set of use cases that describe all the interactions the users will have with the software. Use cases are also known as functional requirements. In addition to use cases, the SRS also contains non-functional (or supplementary) requirements. Non-functional requirements are requirements which impose constraints on the design or implementation (such as performance engineering requirements, quality standards, or design constraints).

Such a document helps you keep focused, get clear on the actual use cases, find potential flaws, define certain goals (e.g. regarding performance). The specification will also be the basis for verifying your final implementation (Does your software do what it's supposed to do?) and help you create test scenarios.

0xA3
+1  A: 

My "step-by-step" process would be this:

  1. Create a prototype. It doesn't have to do much, in many cases dragging a few controls on the form designer will do. Then go through the prototype with the customer/end-user. (This is the important part - if you just create the prototype and throw it over the wall, it wouldn't do any good.) Explain how you think the software would work when you show the prototype and listen to what the customer says. Again, listening is more important than explaining. After that, you should have a solid understanding of what the customer needs.
  2. Now I usually take out paper and pencil and start sketching the high-level module structure. Maybe also important classes, but not every last implementation detail. After this step, I know what modules I need, what the responsibility of each module is, how I can test each module.
  3. Implementation is done the way you know it (at least, I do it more or less the way you described it). But you only implement the basic core functionality at first. Otherwise you are bound to miss critical functionality because you're too busy adding bells and whistles.
  4. Rinse and repeat: You now have a program with limited functionality, go back to your customer, show it, let them play with it. Look at how they try to use it: Where do they fail? What are they looking for and can't find?

Book tip: Release It

nikie
+5  A: 

The standard answer nowdays is rather simple: draw UML diagrams.

Back in the years the answer whould have been: "draw flowcharts", "draw Nassi–Shneiderman diagrams", "draw Warnier/Orr diagrams", "draw Data Flow diagrams" ... etc

They would all be good answers and bad answers at the same time. Reality is that there is no single right answer to the question for the simple reason that nobody really knows what software actually is.

Before people jump on my throat, let me explain what I mean.

When an architect creates a blue print of a building, the end product is clear: it will be a physical structure with walls, doors, windows, etc. Our architect will draw a line and say: "this is a wall"; will draw another line and say, "this is the TV-antenna cable from the roof to the basement". Using some convention about dimensions (the scale), colors and types of lines he will be able to communicate to others what needs to be built and how things fit together.

There might be some misunderstanding on the details but nobody will doubt that the 2D model they are looking at, actually represent a building. Even if multiple diagrams are needed (e.g. one per floor) it's rather easy to relate them.

For a software system we are not yet at that level! The first question is "how will you model the software"?

If you use the Object Oriented approach, you will describe your software as a set of "objects" belonging to "classes" that are related to each other (as described in the "class diagram"), with a given behaviour (a "state diagram") and that interact in certain ways (as described in a set of "collaboration diagrams").

There's no single diagram that will show you all the aspects of a software system. That's why UML includes many different types of diagrams.

If you are using a Structured approach, you will describe your system as a set of processing components that transform their input into outputs (a DFD) and as a set data entities (as an ER diagram).

Any diagram will work as long as its meaning is clear to all the involved parties. In fact it's common to start a design session by drawing two boxes on the whiteboard and a line between them saying: "Ok, that's the browser connecting to our web server ...".

The problem lies exactly in what each diagram means.

Actually, we have a good common way of representing the data portion of a system: an entity relationship diagram (or the "static part" of a class diagram) can be directly translated into a live database. I ascribe this to the fact that relational databases are well-founded into the relational algebra and, at the same time, they have use simple concepts that anyone can grasp (tables, foreign keys, join, ...). All the other representation of data have been wiped out (no more hierarcycal database around!).

What we lack is a common, accepted view of the dynamic aspects of software; some unifying view that would be both theoretically sound and not to difficult to use.

That said here is my suggestion.

  1. Remember that the minimal purpose of an architecture is to create a common understanding of the system.
  2. Learn as much type of diagrams as you can.
  3. Use the most appropriate diagram to illustrate the aspect you want to focus on.
  4. Provide a way to relate different diagrams (in my experience this is the most neglected aspect and you end up with a bunch of extremely detailed models that do not fit together!!!).
  5. Constantly revise the models to reflect the new understanding you gain during the design process.
Remo.D
Everyone's answer was useful, but since I have to choose only one, yours was the most complete. I guess I'll try to learn UML and some of the Diagrams you mentioned for a start. Then I guess the important part is that you have a way to express your program clearly for yourself and others on your team.
didibus