Question: I'm working on a large project (for me) which will have many classes and will need to be extensible, but I'm not sure how to plan out my program and how the classes need to interact.

I took an OOD course a few semesters back and learned a lot from it; like writing UML, and translating requirements documents into objects and classes. We learned sequence diagrams too but somehow I missed the lecture or something, they didn't really stick with me.

With previous projects I've tried using methods I learned from the course but usually end up with code that as soon as I can say "yeah that looks something like what I had in mind" i have no desire to dig through the muck to add new features.

I've got a copy of Steve McConnell's *Code Complete* which I continually hear is amazing, here and elsewhere. I read the chapter on design and didn't seem to come out with the information I'm looking for. I know he says that it's not a cut and dried process, that it's mostly based on heuristics, but I can't seem to take all his information and apply it to my projects.

So **what are things you do during the high level design phase (before you begin programming) to determine what are the classes you need (especially ones not based on any 'real world objects') and how will they interact with each other**?

Specifically I'm interested in what are the methods you use? What is the process you follow that usually yeilds a good, clean design that will closely represent the final product?

Answer: 
1. study & master Design Patterns.
2. Next, learn about the Domain Driven Design
3. After that, learn the requirement gathering

> 
> I took an OOD course a few semesters
>  back and learned a lot from it; like
>  writing UML, and translating
>  requirements documents into objects
>  and classes. We learned sequence
>  diagrams too but somehow I missed the
>  lecture or something, they didn't
>  really stick with me.
> 
> 
> 

4. You know about the step 3. You need to master it. I mean, via a lot of practice to make it become your second nature. That's because the method you learn, is simply against the way we used to have. So you need to really master it. Otherwise, you will always find yourself go back to your original way of doing thing. This is somehow like Test Driven Process, where a lot of java developer give it up after a few tries. Unless they fully master it, otherwise it's just a burden to them
5. Write use cases, especially for alternate course. Alternate course occupy more than 50% of our development time. Normally when your PM assign you a task, for instance, create a login system, he will think it's straight forward, you can take 1 day to finish it off. But he never take into account that you need to consider, 1. what if user key in wrong password, 2. what if user key in wrong password for 3 times, 3. what if user doesn't type in user name and etc. You need to list them out, and show it to your PM, ask him to reschedule the deadline.
One useful technique is to relate your unique problem description to something you can find in the real world. For example, you are modelling a complex health care system that will take the world by storm. Are there any examples you can readily call upon to model this? 

Indeed. Observe how the side pharmacy would operate, or the doctor's room.

Bring your domain problem down to something understandable to you; something to which you can relate. 

Then once the "players" within the domain start to appear obvious, and you start to model your code, opt for a "provider-consumer" modelling approach i.e. your code is the "provider" of the model, and *you* are the "consumer".

Relating to the domain and understanding it at a high level is key part of any design.