views:

32

answers:

1

We're building a game, so that may help to put the objects into context better.

I have a situation where I have a structure kind of like this..

- Template
  - Data(ICollection<Statistics>)

  - Character: Template
    - Data (ICollection<Statistics>)

To elaborate... Let us assume that every character has a property "Health". Now, the default for "Health" is 15.

Now let us assume that every character starts with that. As a character over its lifetime, it might add to "Health" with new values. But they still need to retain the default reference.

Now, 'Character' inherits defaults from 'Template', but each character will have its own set of data that appends the defaults. Raw inheritance does not work because the Item appends, it does not overwrite. The original defaults still need to exist.

I can solve it like this..

- Character
 - Template
 - Data (ICollection<Statistic>)

But this is redundant to me. It requires a lot of extra database calls. Basically every call to a item has to do the same code twice because it has to construct a Template object too.

Is there a more logical way to go about this?

+1  A: 

If I'm understanding you correctly, it sounds like you want to have static values in the template, and then dynamically update the inheritors of those values? If all characters need to have the same default data, can you do something like this?

abstract class Template { 
    ICollection<Statistics> DefaultData;
}

class CharacterTemplate : Template { 
    private CharacterTemplate() {
        //appropriate data initialization
    }

    private static readonly CharacterTemplate _instance = new CharacterTemplate();
    public static Template Instance { get { return _instance; } }
}

class Character { 
    Template template = CharacterTemplate.Instance; /* CharacterTemplate */
    ICollection<Statistics> Data ;
}

Have the Template implementors implement the Singleton pattern, and you have to initialize it from the database at most once.

For the background on the singleton pattern, check wikipedia: http://en.wikipedia.org/wiki/Singleton_pattern#C.23

arootbeer
I don't understand how that will work with the Entity Framework system. What is Singleton pattern, exactly? I'm not familiar with this concept.
Stacey
The Singleton pattern defines a way to only ever have one instance of a class in a system. It basically guarantees that every Character object has a reference to the same CharacterTemplate object, which is how you get around having to initialize it every time. It should work fine with EF, because it doesn't affect how you populate the object, just when.
arootbeer
So you're saying to retrieve the data from the database in CharacterTemplate constructor, and then have everything access it?
Stacey
So do I need to create an instance of CharacterTemplate to do the initialization? I am still a bit confused. Could you elaborate more on how the CharacterTemplate class would be initialized?
Stacey
Augh, I wish I could post blocks of code inline with comments on SO. So I add my template to the database, then call CharacterTemplate.Template and retrieve the item from the database, then when I construct a character , I use the 'single' static instance to initialize its template?
Stacey
You're not initializing the template every time you construct a Character - you're simply setting its template variable to a reference to the same object. Other than that, you've got it. This is assuming that Characters have a different template from Vehicles or Buildings. If EVERYTHING shares a template data, there's no need for subclassing Template. I added the singleton initialization code from wikipedia as well.
arootbeer
Everything in this game has it's own 'default' template. However each of the default templates are different. So what should I do? Build a TemplateFactory with the defaults for each type of object?
Stacey
Would it be best to assign the Template at the time of object creation and insertion, or in the actual object constructor? That is to say, when I add a Character to the database, should I assign it there - or should I put the assignment in the Character constructor?
Stacey
That's another approach - instead of having each class know about a specific type of template, have a template factory that knows about all the classes that get templates. You'd still want to use the singleton pattern for implementing the subclasses of Template so you only do the initialization once. Either way, the only change would be the right hand side of the declaration of template.
arootbeer
Hrnm. But then when I call on the Character.Template later, won't it just try to pull it from the database?
Stacey
I think this will work! I need to refine the idea. This works for initializing the classes, but I don't see how it will work for actually calling instances of them. It will still be trying to call data from the database, won't it?
Stacey
No - that's the purpose of the singleton pattern. If the application is shut down and restarted, then yes it will be populated again. Beyond that, as long as the application is running the class itself holds the reference, and so it will never get garbage collected.
arootbeer
I just tried it out, and it tries to make a table to store the relationships. This tells me that it is still trying to pull it from the database. I'm not sure how to get it to use the C# object instead of a memory object.
Stacey
EF is still going to want to store the data in the database if you make the templates EF objects - it's just not going to have to load them more than once per game session. If you don't want it to hit the database, then just make it a regular object and put the values in the code. If EF's trying to persist the template because it's referenced by the Character class, then you'll have to find out why EF is doing that and suppress it - I haven't done EF.
arootbeer
Well, when I made Template a {get;set;} property, it tried to make a table for it. But when I made it a simple instance field, it didn't... I need the templates stores in the database, and I wouldn't mind the references being there - but I don't want it trying to re-query just because it finds tables and foreign key references, you know?
Stacey
Now you're getting into EF, and I won't be able to help you with wiring that up.
arootbeer
That's fine. Thank you. You have been a tremendous help. The answer was SO SIMPLE! I cannot believe I didn't think of this myself!!!!!
Stacey