Join 3,494 readers in helping fund MetaFilter (Hide)


OOP class design conondrum..
July 26, 2012 4:43 AM   Subscribe

OOP class design conondrum. I am designing a set of classes for an online survey/quiz engine. I need some help with designing my classes.

Preface, I am writing this in C# and the project is an attempt to teach myself proper OOP. I am working my way through the Head First Design Patterns Book
and understand the SOLID design principles but I lack experience in applying them and am not even sure which pattern if any will solve my problem. I also fear I may lack the vocabulary to properly describe my question so I will be monitoring this thread to give any additional information needed to solve it.

Here the main classes:
Candidate
Assessment
Test
QuestionSet
Question
Answer

Here is what I think you need to know about the classes:
Each Candidate is Assigned a single Assessment.
Each Assessment contains a number of Tests.
Each Test has a QuestionSet
Each QuestionSet has a series of Questions
Each Question has a set of possible Answers


My difficult is knowing how to design the relationship between the Assessment and the Candidate. Here is where I am stuck:

Candidate objects have an Assessment member which gives access to the whole Assessment hierarchy. So when they login in I can easily access the tests in the assessment, when they select a test I can easily output the questions and possible answers for them to complete. However the way I have designed the Assessment to Answers objects hierarchy does not accommodate information on which tests have been taken by a Candidate to date nor which responses the Candidate has provided. Why you ask? Well I am getting the Assessment details from a Data Access Layer and as they rarely change I want to cache each Assessment object to avoid a major round trip to the database each time someone takes a test. If I am to redesign this hierarchy of objects to include information on which Tests have already been taken by the Candidate I will be unable to cache the Assessment even though it will be the same for everyone when they login for the first time. I also need to be able to store the Candidates ResponseSet which records the answers they provides to the questions, I will also need to allow for information like when the test was started how long it too etc.

In its simplest terms I have defined the Assessments and all associated objects as it if they make up an untaken set of tests, a blank test workbook if you will. Everyone should get the same one when they start, hence the desire to cache them. However when the candidate is finished with the workbook each one will be different and am at a loss as to how to handle (in the class design) the information the Candidate provided .

How can I best design this set of classes to allow for maximum data caching while adhering to good design practice?
posted by therubettes to Computers & Internet (7 answers total) 3 users marked this as a favorite
 
You might get out of your conundrum by thinking about what services an Candidate needs from an Assessment, and designing an interface that provides those services. Then, have the Candidate implement that interface (sorry for the Java-centric vocabulary here). A Candidate object could have, for example, a private reference to your Assessment cache, and the details of getting data can be offloaded to that cache.
posted by thelonius at 6:59 AM on July 26, 2012


Everyone should get the same one when they start...

I think this is wrong. Perhaps everyone should get an 'empty' instance of an Assessment, but they should certainly get their own instance. You already describe that the relationship is Candidate:Assessment::1:1. You are getting ahead of yourself with the caching concern. I advise you to step back and consider that you will probably refactor for performance later.

Build to good design practices and think about caching later.

However the way I have designed the Assessment to Answers objects hierarchy does not accommodate information on which tests have been taken by a Candidate to date nor which responses the Candidate has provided. Why you ask? Well I am getting the Assessment details from a Data Access Layer and as they rarely change I want to cache each Assessment object to avoid a major round trip to the database each time someone takes a test.

I think you should include the information on tests taken, etc in the object model. Just fill it later on, when it's necessary. On the client-side, you can have a rich domain model, but judiciously decide when or if to fill each object's data.

Build the object model to - as accurately as necessary - model the real world.
posted by j_curiouser at 7:00 AM on July 26, 2012


I think you should include the information on tests taken, etc in the object model. Just fill it later on, when it's necessary. On the client-side, you can have a rich domain model, but judiciously decide when or if to fill each object's data.


Yeah maybe I am being too precious about the performance concern. Taking this approach will allow me to progress right now. I am curious to know if there are better alternative approaches.

In terms of modelling as soon as the test booklet is given to a candidate it is unique. I am as you say going to need one single copy of the tests for each candidate.

Side question: If I do have an Assessment as a member of Candidate what is the best way to cascade down the CandidateID to the Tests and Responses?
posted by therubettes at 7:22 AM on July 26, 2012


Improving the model - some thoughts:

1) QuestionSet seems superfluous. I think a Test is a collection of questions.

2) Get the ordinality and cardinality of each class relationship strongly ingrained in your mind. Sketch the object model diagram, sketch the ERD for the db.

3) Look at constructor injection as a way to relate the Candidate to other types. ('Cascade' is the wrong word, it has special meaning in db domain)

I'll look at more later when i have a few minutes.
posted by j_curiouser at 8:36 AM on July 26, 2012


1) QuestionSet seems superfluous. I think a Test is a collection of questions.
I guess it does make sense to remove this....thanks for the other link it looks relevant, now just to wrap my head around it!! I really appreciate the help...
posted by therubettes at 8:50 AM on July 26, 2012


(I work on distance learning software, but am not an OOP expert.)

So I don't know if you're doing this just as an exercise or for real world use, but the IMS QTI standard uses (basically) this hierarchy: assessments contain one or more question sets, which contain one or more questions. Question sets are useful even if you only have one per assessment, in that they can help keep metadata about the questions -- which tends to be retained when the question sets are reused in multiple assessments -- separate from the metadata about the assessment (test date, grade scale, etc) which tends to be specific to that assessment.

I'm not sure about the distinction you're drawing between assessment and test -- the term "test" is generally avoided in the field as too vague; when it's used at all it's generally as an instance of an assessment (on a specific date for specific students, say.)
posted by ook at 2:58 PM on July 26, 2012


Thanks for your input ook... That is very helpful...
posted by therubettes at 3:22 PM on July 26, 2012


« Older Do you have good examples of W...   |  Looking for a pediatrician in ... Newer »
This thread is closed to new comments.