views:

614

answers:

16

I find that whenever I begin writing an app in Java/C#, things start off good, but over time, as the app becomes more complex, it just gets more and more complicated. I've become aware of the fact that I'm not very good at design and high level architecture. All my classes become fairly strongly coupled and the design isn't "elegant" at all. I'm fairly competent at "low level" programming. That is, I can get just about anything done within a function or a class, but my high level design is weak and I'd really like to improve it. Does anyone have pointers to techniques, books, etc. that would be helpful in making me a better software engineer?

+1  A: 

I would start by sketching my design. That sketch could be a box and arrow diagram to show relationships between classes or it could be a variation on UML (or perhaps even standard UML). But I find that sketches help me see that a design is good/bad and maybe even how to fix it.

I would also look at a book on design patterns.

Thomas Owens
+3  A: 

Books:

  • Code Complete, by Steve McConnel
  • Design Patterns, by Gamma, et. al.
jakber
+1  A: 

Write a large project and let it spread as big as you can. Then study what you can do to improve your code.

Perhaps single large routines can be clean and understandable too, if they are well-structured.

There's no single good answer on good design. It's actually one of those valuable things a programmer can learn.

Cheery
+2  A: 

The answer to your question could fill a book on its own, but I'd suggest you take a look at design patterns.

The classic book on the subject is referred to as the "Gang of Four" book:

Gang of Four Design Patterns Book

Martin Fowler is also highly regarded in the field.

MrCeri
A: 

Try making program outlines and diagrams before you start, and have someone else review and critique it. Then as the program grows, continually update the outlines and diagrams to include the new functionality. Get it reviewed and critiqued by someone else. Eventually, assuming you are learning from the critiques, you will become better at designing programs.

Books and tutorials can only get you so far. While you do need to learn the tools and methods available, knowledge on its own won't help you here. Practice is what will make you better at design, along with having a mentor coach you from time to time to show you how you can better apply some of the knowledge you've gained from the books.

Elie
A: 

Read the books by all means, but don't feel bad if you write code that ends up having stupidities in it. Everybody does. The question is, can you refactor what you have to fix it? To be able to do that effectively and often, you need to use TDD and write lots of unit tests.

Andrew Cowenhoven
+1  A: 

You can refactor mercilessly to improve the design of existing code.

The main idea is, at some point the code did make sense, when new features are bring into the code then probably some features or responsibilities must be moved around to another classes, that's fine. Then you stop developing new features and start refacoring your code.

I would recommend you to read:

Refactoring by Martin Fowler

OscarRyz
A: 

Take a look at this question I asked a while back about design patterns. It's sort of the corollary to your question.

http://stackoverflow.com/questions/85272/how-do-you-know-when-to-use-design-patterns

Robert S.
A: 

I would highly recommend you try Test Driven Development (TDD). You will find that to make your code testable, and not need to constantly perform rework of your tests, you will need to have a solid design. What you will find is that when you add \ change \ remove functionality, your better designs will require a very small set of changes to a specific set of tests. A poor design will wipe out a huge set of tests - because you have tight coupling, objects responsible for multiple concerns, etc, etc, etc ...

I have found that the better I get at TDD, the better my architecture is, and the better the end result is.

Be advised, TDD takes real mental discipline. You should not expect that you use it for 1-2 days and see immediate results. You will need to really want to do it, and really make the effort - otherwise you won't benefit and likely just end up hating it.

HTH ...

A: 

There are a couple of things that you can do

  1. Use tools for high-level and low level design before you actually start programming. E.g. Creating Class UML Diagrams will help your mind visualize the solution in a Diagramtic form rather than Code form.

  2. Familiarize yourself with Java Design Patterns. E.g. Using Inheritance Polymorphically to begin with will warm you up to start using the standard Java and J2EE design patterns.

There are a tonne of books and websites pertaining to both the subjects I just pointed out here.

a-sak
+1  A: 

use Object Oriented Design Principles (http://www.surfscranton.com/Architecture/ObjectOrientedDesignPrinciples.htm). also consider some oo design heursitics (http://www.cs.colorado.edu/~kena/classes/6448/s02/lectures/lecture27.pdf)

Ray Tayek
A: 

Browse through good API code. For instance Spring framework code. Read some good books such as Design Patterns (like everyone else mentioned here) and some other books on good practices. For example in Java, Head First Design, Effective Java series, etc. C++ - Effective C++ series

A: 

Obviously, reading some of the recommmended books will help. I think Head First Design Patterns is definitely less abstract than GoF book.

The primary question I ask is "Is this code doing something very specific that could be re-used anywhwere else?" If so, put in in a class in an assembly that allows for re-use.

If you truly are just starting then one thing I used to do was to consider each database table an 'object'. So each database table represents a class. The purists will tell you this is a disaster, but I found it a good way to get myself started thinking in object terms.

MattH
+3  A: 

I disagree about starting with a book on design patterns or refactoring.

In my opinion, for a solid OO design, you should first be familiar with the main OO design principles, then understand how your problem can be represented in those basic principles. Then you can start discovering opportunities for applying design patterns and refactoring techniques in order to achieve those fundamental principles.

I would start with this book:

Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin

In this book, Robert Martin describes the fundamental principles that make a good OO design, all of them related to encapsulation, coupling and modularity:

  • The Open/Closed Principle
  • Liskov Substitution
  • Dependency Inversion
  • Granularity
  • Common Closure
  • Reuse
  • No Cyclic Dependency
  • Stability Of Dependency
  • Abstraction And Stability

After all, almost every Design Pattern and Refactoring technique I have seen documented in GoF and Fowler is aimed at achieving one of several of these basic principles, depending on their relative priority for a given scenario.

Sergio Acosta
A: 

I would start with : Head first object-oriented analysis and design. and once you mastered it : Head first design patterns.

pmlarocque
A: 

Read Head First Design Patterns.

Alex. S.