views:

179

answers:

8

As a soon-to-be computer science graduate, I have to come realization that I have a long way to go when it comes to the overall design of an application. After spending many semesters of programming from the hip I have come to appreciate the mulling over the needs of an application before diving head first into the coding portion. My question is to the intermediate and expert programmers, how can I improve in the area of the design phase of development?

+1  A: 

I would say your best bet is experience and staying humble and willing to learn from more experienced people.

Geoffrey Chetwood
A: 

The main thing that I've noticed from many "just out of college developers", is the lack of thinking that the code relevant for a much longer period than a semester, i.e. things like clean readable code, easier to maintain, good logging, encapsulation (this is maybe my biggest pet peeve), will make much easier to keep building the applications over time.

I find myself many times going over code that was written 2 or 3 years ago and it makes a huge difference clean code, vs. "working code"

webclimber
+2  A: 

The first step is to understand the actual problem. What are the needs of the customer? - what do they truly want to accomplish? If this question is not answered properly, all that follows is at best a high-quality solution to the wrong problem. Working interactively on these kinds of questions will strenghten your relationship to the customer, and be of great help when difficulties arise.

Next, understand the solution space - what tools and experience can you leverage to accomplish the solution. Don't always do things the way others do them, or based on the current trends. Do what you do well. If there is time/money available, spend some time researching new techniques and ideas.

Finally, make sure you understand the big picture, as well as the low level costs of architectural choices. Many people can see the big picture, and many can understand implementation details, but the few are able to do both.

I realize this does not cover the detail of design, but it should put you in the right perspective.

Dan Hewett
A: 

It is important to break down the problem in a manner that suits the end result. Often I have had to work on projects in domains I know nothing about and learned from those experiences that you need to know:

  1. Who the target audience is and what their knowledge base is

    • Are they car mechanics who don't like computers?
    • Are they PhD professors who can code computers themselves?
    • Are they familiar with standard keyboard shortcuts?
    • etc etc
  2. That whoever they are, they aren't using your tools just to use your tools. It's a means to an ends, rarely the ends itself. The tool will need to be as fluid and inconspicuous as it can (in most cases - maybe not for an alarm system).

  3. Learn the project domain.

    • What are the users doing with the tool and why.
    • How do they use existing solutions.
    • What are the basic requirements (always be wary of "like the old tool did it" requirements)

With this kind of information, you'll have a better idea of what you are trying to achieve. From there, start breaking it down into layers and objects as you determine who is responsible for what and what they're interfaces should be.

Overall, the more you know about the problem you're solving and who you are solving it for, the better. It will not only guide how you design the user interface but also how you design data layers, persistence formats, hardware interfaces, and any number of other important details of the system before you've even determined what relationships exist within that system.

Jeff Yates
+1  A: 

Here's what I do:

Close the IDE/compiler and engage the customer first. Make sure the lines of communication are open and you are both on the same page. This is critical, probably more critical than choosing a language or a design tool or any of that stuff.

Determine what problem(s) I'm trying to solve. Now that you've got the customer's attention, make sure you know what their priorities are. Typically there is a "must have" list and a "nice to have" list and a "if you've completely run out of everything else" list. It is astounding how often we jump right into the code slinging stage without a clear idea of where we're supposed to end up. Determine which problems get solved first, which features will be rolled out first in which iteration (I'm big on short iterations that have working code at the end of each).

Put together your initial high-level design. It doesn't have to be in some fancy tool, but it could be. It could be on paper, on a white board, or a bulleted list. The point is that you need to have the overall idea sketched out so that people can look at it and toss it around and help find issues before you go off coding for 3 months. Enlist your team members, your supervisor, a mentor, the customer (depending on your situation, this may be feasible or not) or someone else who can review it. You ought to be able to talk intelligently about the big picture and a little about the details at this point. Take the input and if necessary, rinse and repeat.

Move onto a little lower level design where necessary. Depending on your deliverables and the environment you work in, you might need to do diagrams or whatever. The point is that you out to have a good idea about how the smaller components generally work. If there are interfaces, you should know these and have generally defined them at this point. Utilize the review process (whatever that is at your shop) to help make sure you are still designing the solution you are supposed to and that the solution is going to work. Don't be married to the ideas, but don't just roll over either. You should be able to defend why you did X rather than Y but be open to changing to Y or Z if it is determined that X isn't really the solution to the problem.

At this point, I'd be writing test code and then writing code to pass the tests I've written. You may operate differently in your shop, but that is how I do business and it works for me. The tests will help enforce the design and the code you write (the production code) will operate within the parameters of those tests.

Really, I think the big point is that design can't be an afterthought but you can't really expect to have everything designed down to the smallest piece before you sling some code. I'm not sure it is all that productive to do so anyhow, but opinions will vary on this point. The second big point is that "we're all in this together" and so you need to enlist the eyes and brains of those around you who are able to provide you with feedback. Some problems just aren't solved well (or at all!) without having multiple eyes on it.

Hope that helps some.

itsmatt
A: 

I think there is an illusion here. If you are a fresh-man I don't think you actually will get into that position to design a new application soon. If you are in a good company they will let you do design when you are ready. In my +10 yrs as a Software Engineer I've only had the privilege to design a new application a handful of times. Today I work with code that is older than 5 yrs and that's how I think it's out here. There is way more old code in existence that needs changes than new applications needed to be written. My expertise is basically that I can read others code and often fix stuff rather having to re-write it. But I enjoy doing design too, so I try to do some in my spare time, just as I want to do it.

Make an application for people to use, ie some Open Source, Freeware or Shareware. It doesn't have to be big.

Package it, distribute it, upgrade it and do support for it. The mistakes you make are good, they show where you went wrong.

When you get the whole life-cycle of a piece of software I think you have a good foundation of stuff that needs to be thought of in a design phase.

Experience trumps...all

epatel
+2  A: 

There are a lot of answers to your question, but I'll point out what I think are key basics.

  1. Keep it simple. It should only do what it needs to do, and it should do it well. (Test Driven Development can really help in this regard... TDD is a great habit to get into)

  2. Understand the business problem that you're trying to solve. Too often I've seen jr. programmers get so wrapped up in the technical side they forget what the business problem is - and this often leads to horrifically complex solutions that are unnecessary.

  3. Design in a group, or get somebody far smarter than you to review your design. If you're the smartest one there, than get a new job.

  4. Keep in mind that nothing is written in stone. Business requirements and strategies change over time, so will your application. Allow it to grow... which leads me to the following 2 key points

  5. Buy this book. Seriously, just buy it. It's simple and can have a dramatic effect on how you approach your design. Head First Design Patterns

  6. Focus on the principles, not the technology.
cranley
You're missing the link to the "head first" book.
Andrew Edgecombe
holy crap... I can't get think linking to work despite using the visual tools.... sorry guys. Ridiculous.
cranley
A: 
  1. Come up with any many possible implementation strategies as you can to solve a particular problem
  2. Analyze each strategy on its relative merits and drawbacks
  3. Select a strategy based upon which quality attributes you care to optimize for

In other words, define multiple solutions to a given problem, understand the pros and cons of each possible solution and then select the most appropriate solution given your situation.

If you have difficulties brainstorming multiple implementation strategies for a given problem study additional programming paradigms (functional, declarative, imperative, OO, procedural, etc.) to increase your exposure to how problems are approached--in a general sense--from different programming languages/perspectives. This will expand how you think.

If you have difficulties analyzing each strategy on its merits and drawbacks you'll want to make it a habit of asking yourself (and/or others) questions like "What can possibly go wrong with this approach?". If you know what makes a bad option bad and a good option good that is one of the most useful skills that you can have.

If you have difficulties selecting a strategy based upon quality attributes you'll want to prioritize the quality attributes you care to optimize for and then make decisions accordingly. For example, if you're torn between, say, two options, you'd choose the option that exhibits the quality attribute(s) that you prioritized higher.

Fhoxh