Resilient wrote:What kind of structure would you have for your data file in this case? You can't just go all willy-nilly and list wheelbase for some cars and not for others and expect the view to be able to display that in a consistent manner.
This is the right starting point. And the answer is very much dependent upon the project specifications. Most of your time might be spent working on the file to get it right. Even the question of file type is non-trivial. XML will always work, but it could get ugly fast. If you do, make sure to define the DTD, or you'll be in for a world of headaches. If you're using an interpreted language, you might use the language itself as the format, though it could be a security risk if the files can be altered (as in, traveling through a non-secure network). Personally, I'd probably use either LISP s-expressions or JavaScript's JSON and call it a day (depending on whether it needs to run standalone, or in a browser). The idea, though, is to get it to "look like" the specifications.
For data organization, the original plan was a Tree. "Vehicles" at the root, then Cars, Trucks, Vans, etc. But that didn't work because of the Baja, both a Car and a Truck. So build a lattice instead; multiple inheritance is one way to get that behavior, but this is data, not code. Regardless, defining a finite lattice is trivially easy, once you've chosen that structure. But this was just a way of specifying what vehicles had what things in common. We can do better.
The best plan is to keep it simple, and refactor when complexity appears: for instance, you can list each vehicle and every option available for it, and call it a day. This is the simplest way to accomplish the goal, and should be the
de facto solution. As you go, abstract the common elements: anything that is common to all trucks, specify once that is should be included in each of the trucks. When you have a second attribute common to trucks, you'll find you want to have a list of trucks, so go ahead and define one. Then you can use the shorthand. What if you find something that's exceptional? It's common to
most trucks, or
most vans, but not all, so you want to be able to use the defined list of trucks and remove elements. Perhaps now you see why I would want to use LISP to store this data?
My first thought would be to have a couple of different views, one for cars, one for truck etc. but the problem obviously, is what do you do with the Subaru Baja? It's a car and a truck! Or what about when you want to add motorcycles as you pointed out?
Worse, the Terrafugia is both a car and a plane. But you're worrying about how to deal with corner cases. We'll get back to that.
From your description it sounds like for the Baja I might just list both car and truck data. But the view still needs to know how to display that. And that is where I don't quite follow your design. How do I go about rending things when the data file may be inconsistent? I can make a view for a car or a view for a truck. How can I design a view that is flexible to display a car/truck when I may not have been planning on it via using this data file? Does the data file need to contain data about how to render the data?
Emphatically
yes. Views shouldn't be hard-coded. It's messy, and most design programs today end up writing that code for you, which is even messier. Personally, I find it terrible. Individual components, fine: they need code explaining how to render anyways. But an aggregation of components? No way.
Have you ever worked with Cocoa? UI data is stored in a data file loaded and bound dynamically at runtime. That's what you want. Define views (possible in a separate data file that gets referenced), and let any given
object specify what view it uses. This may sound like OO, but this isn't happening in code.
When doing HTML design, something similar happens. The server sees a piece of data, needs to render it, and places a chunk of HTML into the output. For AJAX, it's even better: the JavaScript asks for the view from the server, and can then drop it right into the page.
--
The takeaway is this: logic and data are separate, and should be kept separate. Project metadata is just another kind of data, and needs to be kept separate from program logic. It might be tempting to just put them into different files/classes/modules, but this is a bad idea: most programming languages provide very few tools for building data at compile time (LISP being an obvious exception), so don't use the programming language (which is tailored, after all, for specifying program logic) to represent the metadata.