Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Arrays of Sub-Objects ... How to handle these?

Status
Not open for further replies.

icodian

IS-IT--Management
Aug 28, 2001
74
US
I'm having trouble searching for what I'm trying to figure out, so please forgive my ignorance here. I build a small business application using VB about once per year and I just don't know the words I should be searching for my new problem.

I am hoping someone can suggest the appropriate objects, containers, collections, lists, or whatever I should be using to accomplish this. I can do the research on how to use them, I just don't know what will help me do this.

I am creating a simple VB game for fun and my kids using VB.NET Express 2013. I want to create an object that can have a variable number of "sub-objects". And each sub-object may have sub-objects. Here's what I mean:

1. Master House object (Length, Width, Height variables; AddRoom method)
2. The House object may also contain Room objects. There could be any number of Rooms in the House...1, 2, 3...10. (Each room has it's own L,W,H; and an AddComputer method)
3. Each Room object may contain Bookshelf objects. Any number of Bookshelves per room. (Each Bookshelf has it's own Size, Color, etc.; and an AddBook method)
4. Each Bookshelf may contain any number of Books.

So based on this, here are my thoughts. Feel free to tell me how my thinking is wrong on this.

1. In a business app, I would just store this info in the DB with the appropriate keys and would generally only access info for a small dataset at a time, so speed isn't an issue. If I want to have 100 Houses on the screen for instance, with quick access to the details inside each House on a mouseover, pulling from the DB each time seems inefficient.

So it seems that loading this info into memory is a better way to go. Am I right on this?

2. I've tried using List. This worked well for 2 levels when I could create the House and add Rooms to it. But once I was trying to create a new House, the Rooms in it, and the Bookshelves per room, I got a little lost. The code to add an object got so long and unwieldy it was ridiculous.

I couldn't help but think I wasn't handling it correctly. There must be a better way. Is there a container or collection that's made to handle this sort of thing?
 
OK I am confused. Why would the dataset itself not be the natural container?
 
You may have just answered my question. As usual I'm probably overthinking this and making it way hard than it needs to be. Ugh...
 

Each object should have one collection or list for each type of object it can hold. Then to access, say, a particular book, in a bookshelf, in a room, in a house:

Houses(1).Rooms(4).Bookshelves(3).Books(7)

Yes, it can get long and a bit unwieldy, but that is indeed the correct way to access objects, contained within objects, contained within objects, etc.

You can manage this a bit. For instance, if you have some code that does a few different actions on a book, you can use a With block so you don't have to type out all the object references each time:

With Houses(h).Rooms(r).Bookshelves(b).Books(b2)
.SomeMethod
.SomeProperty = SomeValue
.SomeOtherMethod(SomeParameter)
End With

If you are using nested objects for all this, there really isn't a way around the long strings of object references.

One last thing: since you intend to store all this in a database, I strongly recommend you look into object serialization. This will allow you to easily store a house and all it's sub-objects in a database, then recreate it quickly and exactly at a later time.


I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson

Arrrr, mateys! Ye needs ta be preparin' yerselves fer Talk Like a Pirate Day!
 
I may have misread how you plan to do this, so simply using a dataset may or may not fit your needs. But if it does not then this should be a very simple and clean design. It is OOP 101. All you need to do is build composite/complex classes (classes that have properties that are themselves classes). So build it from the bottom up. You need Class Book, Bookshelf, Room, and House. Although not needed I think it is worth it to make a custom collection class for each one of these classes. Once you build one collection class the rest are all the same and for organization it is worth the effort. So you need collection classes Books, Bookshelves, Rooms, Homes. Once you made these classes it will be very organized and easy to manage. You will have a collection of Homes containing houses, each house contains a collection of rooms, each room contains a collection of bookshelves, and each bookself contains a collection of books.

1) Class book
2) Custom collection Class Books
have methods to add, delete, get a book
I personally like to use a generi list(of T) so the collection would be based on a list(of Books). Lots of performance benefits. May want to google
3) Class BookShelf
with a Property of Books of type custom collection of books
4) Custom collection class Bookshelves
with metods to add, delete, get a bookshelf
5) Class Room
with Property of Bookshelves of custom collection of bookshelves
6) Custom collection class Rooms
with method to add, delete, get a Room
7) Class House
with a property Rooms of type custom collection of rooms
8) Custom collection class Homes
with a method to add, delete, get a room


So eventually you would be able to intantiate objects something like this.

dim myHomes as Homes
myHomes.add("Home1")
with myHomes("Home1")
.address = ...
.length,
.Width
.Height
end with
'lets assume that all homes have rooms so you instantiated rooms in the constructor
'And you have a room constructor like Name,Len,Wid,Hght
myHomes("Home1").Rooms.Add("Master Bedroom",20,12,8)
myHomes("Home1").Rooms.add("2nd Bedroom",12,12,8)
Dim masterBookshelves as bookshelves
masterBookshelves = myHomes("Home1").Rooms("Master Bedroom").bookshelves
with masterBookshelves
.add("BookShelf By Bed")
.add("BookShelf by Window")
end with

.....


So eventually you could iterate like

For each myHome as Home in MyHomes
for each myRoom as Room in myHome.Rooms
For each myBookshelf as bookshelf in myRoom.bookshelves
for each myBook as Book in myBookshelf
messagebox.show myBook.Title & MyBook.Author
next myBook
next myBookShelf
next myRoom
next myHome
 
Both of you have helped and I appreciate it. It seems as though using the List like I was originally trying to do was on the right track. It just seemed so cumbersome, but looks like I was at least on the right track.

@MajP: I started building it from the top down... Started with House, then worked my way to Rooms, then got to Bookshelves and had trouble. I'll trying building from the bottom up instead as you suggested, that may help a bit so I don't miss things. Adding additional sub-objects within each object is going to be a bear too.

One of my problems is that I won't know the number of sub-objects to put in an object, the number of books on a bookshelf for instance is generated "randomly", so I've got so many sub-loops my eyes are blurring. When accessing I can definitely see how the For Each will come in handy.

@jebenson: Appreciate the With block suggestion and I will definitely look into object serialization, I appreciate that tip. I've seen that referenced as I was doing some research but didn't read much into it. Is there any advantage between Collection or List?
 
The generic list has some serious performance advantages because you are not boxing and unboxing your objects. But I have no idea how you could do this top down. How can you debug this, until you are completely finished. I can build a book and test its properties and methods. Then build the Books custom "collection" class and test adding, deleting books to that. Then build a bookshelf and test that by adding books......
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top