Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am writing a class library to serve as a managed .NET wrapper over a REST API. I'm very new to OOP, and this task is an ideal opportunity for me to learn some OOP concepts in a real-life situation that makes sense to me.

Some of the key resources/objects that the API returns are returned with different levels of detail depending on whether the request is for a single instance, a list, or part of a "search all resources" response. This is obviously a good design for the REST API itself, so that full objects aren't returned (thus increasing the size of the response and therefore the time taken to respond) unless they're needed.

So, to be clear:

  • .../car/1234.json returns the full Car object for 1234, all its properties like colour, make, model, year, engine_size, etc. Let's call this full.
  • .../cars.json returns a list of Car objects, but only with a subset of the properties returned by .../car/1234.json. Let's call this lite.
  • ...search.json returns, among other things, a list of car objects, but with minimal properties (only ID, make and model). Let's call this lite-lite.

I want to know what the pros and cons of each of the following possible designs are, and whether there is a better design that I haven't covered:

  1. Create a Car class that models the lite-lite properties, and then have each of the more detailed responses inherit and extend this class.
  2. Create separate CarFull, CarLite and CarLiteLite classes corresponding to each of the responses.
  3. Create a single Car class that contains (nullable?) properties for the full response, and create constructors for each of the responses which populate it to the extent possible (and maybe include a property that returns the response type from which the instance was created).

I expect among other things there will be use cases for consumers of the wrapper where they will want to iterate through lists of Cars, regardless of which response type they were created from, such that the three response types can contribute to the same list.

Happy to be pointed to good resources on this sort of thing, and/or even told the name of the concept I'm describing so I can better target my research.

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

Based on your description, I would use option three. Option two is probably the worst of the bunch since you would be maximizing duplication and minimizing reuse.

Option one is the inheritance model. I don't feel like it's a good fit for the situation. The resulting class hierarchy will introduce complexity but you won't be gaining much in the trade-off. Inheritance can be very useful when you have a number of different objects which all share a common superclass. In this case you really only have one type of object (a car), you just have varying levels of completeness.

With your single car class from option three, there are some good tricks you can use like lazy loading of properties. Basically if your class has been filled with the least amount of data possible then in the getter of the other properties you can trigger a call out to the more detailed API and fill in the rest of the information. Be careful to model this type of behavior around actual usage patterns the object may see, but it can greatly help with ease of use for other programmers who consume your object.

share|improve this answer
    
Fabulous, thanks! –  sasfrog Nov 12 '12 at 3:49
add comment

In C#, you can add attributes to the properties of an object:

It would be easy enough to create an attribute that defines the level of detail a property represents - lite or full - and add the attribute to each of the properties of the car object. Once you've decorated all of the properties with attributes, write a serialiser class that can be fed an object and a level of detail as its arguments. It will:

  • Use reflection to find a list of all properties relevant to the current detail level;
  • Spit out a list of those properties and their current values.

This gives you:

  • A single class instead of multiple classes;
  • The ability to have a fully-populated object and produce a lite representation without having to create an intermediate abridged copy;
  • A class that can be extended with new properties and have them automatically be added to the REST API.
share|improve this answer
    
This is very helpful, thank you. Together with Bryan's answer, which addresses each of the options in turn, I feel like I have a comprehensive response and plenty to look into. –  sasfrog Nov 12 '12 at 3:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.