We help IT Professionals succeed at work.

class hierarchy opinion

Hi,

I'm kinda stuck on my class hierarchy (not sure if this is the right term).
So i'm creating a trading card game  and have been thinking on how my classes are made.
This game is created in XNA but as of now I'm just building up my business layer in c# without the xna framework.

So first question:
The cards will be coming from xml files (which is after reading a few articles the only way to save cards for the xbox 360). My first idea was to create the following:

enum Element
    {
        Black,
        Green,
        Blue,
        White,
        Red
    }

    enum Rarity
    {
        Common,
        Uncommon,
        Rare,
        Legendary
    }

    enum Type
    {
        Hero, //maybe different Class + equipment Type (weapon/shield slot)
        Equipment,
        Resource,
        Creatures,
        Sorceries,
        Enchantments,
    }

    //Should class be static? As it all comes from a database/xml files.
    class Card : Entity<Int32>
    {
        public Card(String name, String description, Element element, Rarity rarity)
        {
            Name = name;
            Description = description;
            Element = element;
            Rarity = rarity;
        }

        public Card() { }

        //Boolean FaceUp;
        //Boolean Tapped; // Should be checked if its in play or not (probably in Setter)

        public readonly String Name;
        public readonly String Description;
        public readonly Element Element;
        public readonly Rarity Rarity;
        //public readonly Double Appearance; //Percentage for boosterpack
        //public readonly Decimal Value;
        public Type Type
        {
            get { return _Type; }
        }

        protected Type _Type;
    }
class Enchantments : Card
    {
        public Enchantments()
        {
            _Type = Type.Enchantments;
        }
    }
class Resources : Card //amount of cards will be added to pool each turn
    {
        public Resources()
        {
            _Type = Type.Resource;
        }
    }

Open in new window


But after some thinking i thought the best OO manner is to be using static classes so no instance could be made for the classes. Is this a good idea? also what about the readonly members and private once?


Second question:
The idea is to add certain skills to a card (which will also be created in an xml file). So for example I have a dragon card (with 3 attack and 7 defence) but one of his skills is Firebreath (cost = 2 fire resources) which will do damage to all opponents creatures.
How can I create such class? I first thought of using a dictionary (cost, skill) but problem is teh cost can be a combination of 2 different elements (fire/earth for example).
Comment
Watch Question

Rahul GadeSr. Architect
Commented:
Regarding first question:
Why don't you go for XMLSerialization of your class, in that case saving and retriving the xml to your C# object will be very easier. Using SingleTone class is not a bad practice, but one should avoid using it as long as it is not really required. Usually the singleton is prefered if you want to maintain a instance for the entire lifecycle of your process, so yes in your scinario you can use SingleTone without any problem.

Regarding second questions:
If you use XMLSerialization, in that case you can better go with the collection classes. You may want to use online tool like
http://www.bware.biz/default.htm?http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/GenerateInput.aspx
That will help you generating collection classes as you want from XSD. So, that if you make any future changes to the structure of XML, you just need to modify the XSD and regenerate the partial classes from this URL. There are many other similar tool that can perform similar activity.
In other way, you can have a base class called skill and derive all other skills from it, the collection can hold all objects derived from it, and you can keep getSkillType() to each of them overriden from base class to know the type of instance.

-Rahul Gade
My 2 cents worth:

If you are talking about the relationship between your XML and your classes/objects I would call that an XML mapping to an object model.  I think of the class hierarchy as something that relates specifically to inheritance relationships between classes.  I'm not sure if the computer science boffins would agree with all that, I'm just saying that is how I use the terms.

If I were writing this I do not think I would make those classes static.  The way I like to design things I end up creating instances so I have a place to hang the state.  Its is the relationship between these instances that make the application sing.  I normally only use static classes to abstract generic functionality. Of course I sometimes add a static method to a non-static class when it is specific to the class but invariant to the instance. I'm not saying this is the best way, again, it is just what works for me.

So the first thing I write is the part that reads the XML and creates the object model.  The I write the part that reads the object model and writes the XML (round-trip).  None of this is static because sometimes I need multiple copies of the object model. Then I add the customised (smart) compare because I like to be able to see the delta.  This all helps me to fine tune the relationships between the XML and the object model. I often have logic that lets me change things visually and save the XML or just compare it to the saved version to see the differences. This is all for me to help with development, not for the user, although since you are working on a game (which I have never done), perhaps some of capability might be exposed to the user (?).

I find all this to be a huge help to me but I can see that for some people it would be a lot of work for something that only the developer will use.  

I would create a class that implements List<TradingCardItem> and then if I need customised views I would use methods that return various appropriate containers with the appropriate key (or no key).  Assuming a reasonable size list, my experience is that a quick scan, returning the best container for the job in the big picture is much more efficient then trying to determine a one-size fits all container design.  

And of course, the TradingCardItem class is subclassed for all kinds of specialised uses, and since you can return any containers you want off your List it doesn't matter that you didn't think of some of it before you started.  

Well, I have no idea if any of this is any help to you at all so I will stop now.  I can rant about this all night.  Good luck!  
Question 1
You are using polymorphism, and it looks like you will have more than one instance of each class. Both polymorphism and multiple instances rule out static classes, so static classes aren't an option here.

Question 2
... How can I create such class? I first thought of using a dictionary (cost, skill) but problem is the cost can be a combination of 2 different elements (fire/earth for example).
You just need to use a 'Cost' struct instead of using a scaler for cost. The cost struct would look like something like this:
struct Cost {
  public readonly double Earth;
  public readonly double Wind;
  public readonly double Fire;
  public Cost(double earth, double wind, double fire) {Earth = earth; Wind = wind; Fire = fire;}
// You will also want arithmetic operators for this class, like this:
  public static Cost operator+(Cost lhs, Cost rhs) {return new Cost(lhs.Earth + rhs.Earth, lhs.Wind + rhs.Wind, lhs.Fire + rhs.Fire);}
  public static Cost operator-(Cost lhs, Cost rhs) {return new Cost(lhs.Earth - rhs.Earth, lhs.Wind - rhs.Wind, lhs.Fire - rhs.Fire);}
  // etc. with other operators
 // This allows you to say 'Cost totalCost = cost1 + cost2;'
}

Open in new window

There is more to this "value class" then just what I've written here. For more information on how to make your 'Cost' struct, read this: http://msdn.microsoft.com/en-us/library/aa691324%28v=VS.71%29.aspx, and http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx
Hi Mutsop,  I was just wondering if anything of these responses were helpful to you?  If you could further clarify what you are asking I'm sure you would get more responses.  Thanks!

Author

Commented:
Sorry for the late response but overlooked the question as this project was on hold for the time being.

But all ideas were good! I'll reopen it in the following weeks :)