Search Unity

Component based instead of inheritance based Inventory

Discussion in 'Scripting' started by Myhijim, Jul 14, 2015.

  1. Myhijim

    Myhijim

    Joined:
    Jun 15, 2012
    Posts:
    1,148
    Hey all,

    Been a while since I posted, busy bee.

    But now I have design question relating to inventory system design, of which I currently can see 2 options.

    1. Inheritance based approach

    The fairly stock standard approach where there is a base item class and from that subclasses are inherited and interfaces applied for additional functionality.


    Code (CSharp):
    1. public class Item
    2. {
    3. int id;
    4. string name;
    5. }
    6.  
    7.  
    8. public class Food : Item, IConsumable
    9. {
    10. public void Consume()
    11. {
    12. }
    13. }

    2. 'Attribute' component based approach

    Now this is something I am very interested in trying as it seems to be a very modular way of implementing things with a singular 'Item' class and then many different sub attribute classes that act as additional components to the base item class.

    A very simple mock-up, I put together in about 5 mins :

    Code (CSharp):
    1. public class Item
    2.     {
    3.         string name;
    4.  
    5.         int id;
    6.  
    7.         List<ItemAttribute> attributes;
    8.  
    9.         public bool HasAttribute<TItemAttribute>() where TItemAttribute : ItemAttribute
    10.         {
    11.             for (int a = 0; a < attributes.Count; a++)
    12.             {
    13.                 if (attributes[a] is TItemAttribute)
    14.                 {
    15.                     return true;
    16.                 }
    17.             }
    18.             return false;
    19.         }
    20.  
    21.         public void AddAttribute<TItemAttribute>() where TItemAttribute : ItemAttribute
    22.         {
    23.             if (!HasAttribute<TItemAttribute>())
    24.             {
    25.                 TItemAttribute newAttribute = new ItemAttribute() as TItemAttribute;
    26.                 attributes.Add(newAttribute);
    27.             }
    28.         }
    29.  
    30.         public TItemAttribute GetAttribute<TItemAttribute>() where TItemAttribute : ItemAttribute
    31.         {
    32.             for(int a=0; a<attributes.Count; a++)
    33.             {
    34.                 if (attributes[a] is TItemAttribute)
    35.                 {
    36.                     return attributes[a] as TItemAttribute;
    37.                 }
    38.             }
    39.             return null;
    40.         }
    Then each attribute can be added and called as required as well as their corresponding functionality.


    Pros
    - Appears to be a more modular design with less codependancy.
    - Ease of addition and removal of 'components'

    Cons
    - Unsure of speed of operations (I'm not sure it is that relevant)
    - Difficulty of serialization

    Would love to hear any thoughts/suggestions on this.

    (Sorry it is such a rough post, had to make it quick)
    - Myhi
     
  2. landon912

    landon912

    Joined:
    Nov 8, 2011
    Posts:
    1,579
    James, have you looked into the Decorator Pattern? It looks similar to what you're trying to do. The second method is better than the first, IMO, but I'd think it'd expand(badly), quickly, once you get into sorting functionality in items.
     
  3. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    landon91235 just beat me to the punch about the Decorator pattern. You've essentially implemented it in your example code, but identifying the pattern explicitly will make it easier for others to comprehend quickly, and it can serve as a reminder if you step away from the code for a while.

    This includes adding and removing at runtime, which is more difficult when properties are hard-coded into inherited subclasses in inheritance trees.

    I agree that speed of operations usually isn't relevant with inventory. It shouldn't be difficult to serialize, either. Inherited classes have their own serialization issues anyway.

    A component-based approach looks like the better tool for the job.
     
    landon912 likes this.
  4. Myhijim

    Myhijim

    Joined:
    Jun 15, 2012
    Posts:
    1,148
    Thanks for the insight guys, I have used the decorator pattern before just I am never good with the real technical names of things, often find I am using patterns without even realising :p . Just was comparing the options here, just because I see a lot of people treat the hard written inheritance and interface tree still as a viable option and I think that made me think 'something must be wrong with this seemingly better way to do things'. But I'm not 100% sure I would call it a decorator pattern, unless I'm just getting two things mixed up that are essentially the same.

    After using the Service-Locator pattern, a design supposedly to 'replace' singletons, it is basically similar in it's component based structure.
     
    Last edited: Jul 15, 2015