The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

OOP question: how much up front design?

In my post earlier today, it was noted that you can't define all your classes up front. Too much detail, not enough known about implementation.

If you are rewriting a program (so you know exactly what the program MUST do, plus some *future* features that you want) would you still only create some of the class designs  up front?

If so, at what point do you design the additional classes? Do you write procedural code then refactor into classes? or do you design additional classes once you need something done that doesn't fit within the existing design?  I.e., "most code should go in a class *somewhere*. If you're writing code and it doesn't fit anywhere, consider whether you need a new class"


-Still learning the OOP approach.
Mr. Analogy Send private email
Saturday, October 21, 2006
 
 
Mr Analogy,

I feel your pain. I still remember when I was learning OOP with VB6. It was quite painful back then. I got that "Aha!" moment when I read "VB COM" book. It is a bit dated now, but I believe the author does an excellent job to help transitioning from procedural to OOP programming.

You can get this book for about a buck from Amazon. Here's the link:

http://www.amazon.com/Vb-Com-Thomas-Lewis/dp/1861002130/sr=1-1/qid=1161485354/ref=pd_bbs_sr_1/102-9856339-5260964?ie=UTF8&s=books

A lot of the questions you've been asking are answered in this book. This book is what led me to have a good foundation to understand OOP. After this book, I started reading books about business objects from Rockford Lhotka and Peter Wright.

Now to try to answer your questions...

Since you are beginning, the best strategy for now is to create classes that encapsulate specific behaviors. Don't worry about this too much right now.

The best rule of thumb I've found is to create Subs and Functions that encapsulate all of the specific behaviors. The class will contain data that will be exposed through the properties. Once you find yourself copy and pasting code, stop and make that into its own Function, and point the Subs to this new Function.

You already have some behaviors in mind, so create a classe for each behavior and write your Subs without putting code into them. Once you have stubs (code skeletons) then you can sit back and change either the names or the locations of your Subs and Functions.

Now you can start copying and pasting code from your old program. Repeat the process until you feel comfortable. And don't worry, you'll get better at this with practice, and will look back at your old code and think "What was I thinking?!?" But that's normal, and to be expected.

HTH!
Hector Sosa, Jr Send private email
Saturday, October 21, 2006
 
 
I know Allen Holub can be controversial, but his articles articles (which can be found on JavaWorld) have helped me quite a bit.  As he advocates, think in terms of message flows between objects.  He says that he starts by doing collaboration or sequence diagrams for just two or three classes (if I remember correctly) and then starts coding and then immediately refactors as necessary. 

Class diagrams, according to Holub, are not useful during design since they show a static view of the system, and I agree.  He also says that most UML tools are not much good, and I agree with that statement also.

The problem with Holub is that he does not always explain things very well.  Understanding his writings took me a long time because he can be long-winded and light on practical examples, but eventually I got what he means when he says "Don't ask for the information you need to do the work; ask the object that has the information to do the work for you."

I could go on further about my methodology, but like everything else related to software development, you cannot truly standardize on anything because every project is different.

As some people say, once you finish initial code, it's already in maintenance, so I don't think approaches to OOP need to vary much based on where in the development cycle you are.
Ryan
Saturday, October 21, 2006
 
 
>> how much up front design?

(for OOP)

Answer: however much that you can do confidently. If you are not confident doing up front OOP design, then I recommend not to do any up front OOP design.

What I do: if I am uncertain how a piece of an application can be implemented as a class, I will simply write that section procedurally or as a collection of preexisting platform objects wired together in code.

Once I have developed an application in this manner, I generally observe ways in which the code I have developed can be packaged as an class.

In application development, one strong candidate for a new class generally turns out to be a piece of a UI that has very consistent and well explained behaviors in different incarnations in different applications, and which consists of existing components assembled in a complex way. A class in that context wraps all that ugliness of one or more stock components tethered in a complex way, into a new higher level component that you now can re-use.

Ultimately a class is like a "little program within your program". If you can't determine the behavior of that "little program", you can't design it. Just as if you can't determine the behavior of a program, you can't really design it, either.

Once you have been through several of these iterations - procedural & glue code migrated to a class definition - one starts to recognize instances up-front in which a class design becomes "obvious". Once you cross that divide, you can achieve what you are now trying to do, which is to be able to design classes from scratch.
Bored Bystander Send private email
Sunday, October 22, 2006
 
 
> would you still only create some of the class designs  up front?

Yes, because by the time you've created all the classes your program is finished, but you can't finish it all in one go!

You can do a higher-level design at the begining (partition the system into packages, assemblies, components, layers of responsibility), accepting that the detailed design of each package will entail more than one internal implementation class.

> Since you are beginning, the best strategy for now is to create classes that encapsulate specific behaviors.

A related approach is to create classes which wrap data. A class is a data type (a bunch of data members and associated methods).

Whether a new piece of data goes into an existing class or into a new class depends on whether that data can be instantiated independently, for example you can have one form with two buttons and three lists, therefore 'form' and 'button' and 'list' are separate classes; and you can have one multiple-choice test with 10 questions and fourty choices, so 'test', 'question' and 'choice' are separate classes.
Christopher Wells Send private email
Sunday, October 22, 2006
 
 
Look into robustness diagrams.
Manes
Sunday, October 22, 2006
 
 
"In my post earlier today, it was noted that you can't define all your classes up front."

Some classes I know I'll need, so I'll start building them early.  But the interfaces usually change once I get around to using them. Most often I'll create classes on the fly as needed -- I'll write some code assuming I have the class and then create a class to satisfy that assumption.

"Do you write procedural code then refactor into classes? or do you design additional classes once you need something done that doesn't fit within the existing design?"

If I'm writing a piece of a code and I need, for example, a stack.  If I don't have a stack written, that doesn't stop me, I just start writing the code as if I have a stack:

items = new Stack()
items.push(item);

And then after that I go and write the stack class.  Same is true of data entities or widgets or whatever you can think of.  After a bit of that it's time to refactor to make some sense of it all.
Almost H. Anonymous Send private email
Sunday, October 22, 2006
 
 
"when I was learning OOP with VB6"

lol that is funny  :)
Recce
Sunday, October 22, 2006
 
 
> As he advocates, think in terms of message flows between objects.

I think that's good as I advocate responsibility driven design, but you also have to think about OO simply as a structural mechanism. You create base classes with virtual methods that can be overridden. This is hard core structural mechanism for reuse both in code and type. Thinking at the more abstract levels sometimes misses the down and dirty part of coding.
son of parnas
Sunday, October 22, 2006
 
 
I write medical device software, so even though we do SCRUM, we do a fair amount of up-front analysis & design.  Mostly this is because the FDA does regular audits of us, but partly because it's been identified as a business need.

Analysis: Identify all the participating business entities
Design: Flesh it out to where you've identified all your classes and their public "face" -- leave the private members & methods for the actual implementation.

Our rule of thumb for design is: if you were to be hit by a bus, could someone pick up your design and code it?
xampl Send private email
Sunday, October 22, 2006
 
 
> if you were to be hit by a bus, could someone pick up your design and code it?

All you really need then is requirements.
son of parnas
Sunday, October 22, 2006
 
 
Imagine you are designing software for ATM(Automatic Teller Machine)..
unknown Send private email
Monday, October 23, 2006
 
 
I write administerative CRUD applications, and I don't waste my time in designing complicated class hierarchies. Instead I start by designing my database, then I create one class for each database table, with most of the code inherited from an abstract table class. It's simple, and it works.

Much, much easier than designing a class structure first and leaving the database till last.
Tony Marston Send private email
Monday, October 23, 2006
 
 
Iterate a lot from design into code and then testing. Testing is a must because that is running code!

Go in small steps.
Dino Send private email
Monday, October 23, 2006
 
 
Try Domain Driven Design  :)
Recce
Monday, October 23, 2006
 
 
>Do you write procedural code then refactor into classes?

Yuk. No. Thats twice the work. OO should save time.

>or do you design additional classes once you need something done that doesn't fit within the existing design?

Yes. Rough out a design with pencil and paper or post-it notes. Work out the major domain classes and how they relate to each other (is-a, has-a etc). Take some time to get this right. Then add supporting classes for graphics, networking, database etc. Inevitably there will be things you didn't anticipate and you will have to tweak your design as it progresses. With OO and strong typing refectoring is usually pretty easy.

Don't get too obsessed with OO. Its a means to an end. Its fine to have a free floating function from time to time.
Andy Brice Send private email
Tuesday, October 24, 2006
 
 
As an advocate of TDD, the problem (IMHO) is *NOT* up-front design.  The problem is when that up-front design is taken as gospel, and overrides learnings during development. 

Do enough up-front design to enable you to understand the problem/domain.  Feel free to follow the design as you do your coding (just remember to write a test before you write the code!).  And do the design on a whiteboard or paper, so that you can change/revamp/rewrite the design as you learn more.
Another Anonymous Coward
Tuesday, October 24, 2006
 
 
For any non-trivial software I've built, I have observed what Fred Brooks (author of the Mythical Man Month) describes: "Build one to throw away; you will anyway." Invest a little bit of effort in sketching out a design on a piece of paper, then start hacking together a simple instance of the problem you are trying to solve. As you write code you will invariably learn things that you did not know before. An API works differently than you expected, performance in this part of the system is quite adequate, key abstractions will start to surface. Program like an artist sketches, adding and removing lines of code as you converge on something that captures the heart of the problem.

Once you have that, start over and design your classes and interfaces using the insight you gained from building the prototype. For fun, look at your original design, it will most likely be very different than what you end up with.
Gorf
Tuesday, October 24, 2006
 
 
I'm surprised no one has mentioned anything about functional design yet.

In my opinion, it's very difficult to do any low-level technical design (class diagrams, public interface design, database design, etc) without a really well fleshed-out functional design.

I like to have a document describes all of the functionality of the system, from the user's perspective, ignoring all of the underlying technical implementation issues.

Only when I have a pretty mature version of the functional spec do I feel comfortable starting to rough out the underlying design.

But once I've got that in place, I actually don't feel a deep need to do a detailed UML diagram of the application. I just sketch out the classes and their public APIs. And when I have a pretty good skeletal design, I start writing the code. The design will change as I implement it. But without doing the preliminary functional design, I'm more likely to head down the wrong path with the technical design.

So...

Functional Spec: Big Up Front Design
Technical Spec: Small Up Front Design, Iterative changes
BenjiSmith Send private email
Tuesday, October 24, 2006
 
 
Functional Spec: Big Up Front Design
Technical Spec: Small Up Front Design, Iterative changes

Yes!

OOP? Only if the problem demands it.  In any event, the object design is the LAST thing one should do - not the first.

Its dumb cubed to expect to be able to design an object structure without understanding the problem to be solved.  That's like a manager expecting to make decisions without knowledge, understanding, skill, or experience.  Not that lacking those things has ever stopped a manager from making decisions or a designer from designing.

Keep in mind that nine out of ten new business ventures fail.  Why?  The managers made wrong decisions.  Also at least nine out of ten new software projects fail by their own standards.  Why?  Because the designers made the wrong decisions.  That the wrong design decisions were commonly forced by managers making wrong decisions is no excuse.

For the most part decision is pointless and useless.  Especially without an adequately executed prior discovery process.  However, if you have executed an adequate discovery process, decisions are unnecessary.  The path to the solution becomes obvious.  The management's job is reduced to little more than keeping the bathrooms clean, the trash emptied, and the coffee pot filled.  The designers job is reduced to filling out the paper work.
Lionell K. Griffith Send private email
Wednesday, October 25, 2006
 
 
For the purposes of this discussion, please remember that this is a rewrite/refactor.


So, we have a working program as a guide for functional and technical requirements. No, they're not in a feature list that you can check off, but they're known and anyone who wants to have a list has but to use the program.

So, the question is: once you KNOW what the program will do, and know that requirement wont' change, how much of the OOP class design do you do up front?
Mr. Analogy Send private email
Friday, October 27, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz