Search Unity

WHY did I AVOID interfaces!? Discuss cool things u can do with them here.

Discussion in 'General Discussion' started by Slyder, Jul 22, 2015.

  1. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Coding is an entirely artificial construct. There is no underlying physics controlling how things are done. Its all convention. This means that pretty much any way to do things is valid. That's why there are so many different viewpoints.

    There are certainly better ways to do things and worse ways. But this is very context dependent. Providing a single solution that works for every context is impossible.

    Coding is also changing rapidly. It wouldn't surprise me if someone reading this in ten years would think all of our opinions are out of date and toss the lot of it.
     
    frosted likes this.
  2. the_motionblur

    the_motionblur

    Joined:
    Mar 4, 2008
    Posts:
    1,774
    While we are discussing interfaces ... is there a good project that uses/teaches interfaces more extensively so that I could get a better idea of how to make use of them in Unity and also how to use them correctly?

    I do know about the short explanation and I do know in theory - very basic - how they are used. The roguelike tutorials also used an interface in one instance. But I feel like I'd like to know more about correct usage and logical ways to make use of them.
     
  3. Master-Frog

    Master-Frog

    Joined:
    Jun 22, 2015
    Posts:
    2,302
    Well, they're a tool that I have somehow been able to do without, entirely. So, unless someone can say, "This is what they can do that nothing else can do!" I will have no desire to buy in and add them to my toolbox, but that's just me.
     
  4. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Functional programmers would already say that classes and inheritance are out of date :p
     
    Kiwasi and frosted like this.
  5. Master-Frog

    Master-Frog

    Joined:
    Jun 22, 2015
    Posts:
    2,302
    ...as they use a system built on objects. :confused:

    We may be different colors on the outside, but inside we all operate by way of a linear execution of instructions in a stack structure. Can't we all just get along?
     
  6. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Depends on the language, C# forces you to wrap everything in a class but you can sort of program it in a functional manner not passing mutable objects. In other languages that are more suited to it you can get away with no classes at all.
     
  7. Master-Frog

    Master-Frog

    Joined:
    Jun 22, 2015
    Posts:
    2,302
    I'm pretty sure the entire .NET system is objects. And by now, all operating systems are written in objects as well. I don't think anything exists without some concept of objects. Even in JavaScript, where people are very enthusiastic about the idea of functional programming... proper classes are officially in for ECMA 5.

    Fundamentally, there are no objects. We realize this. There are also no functions... so, to me there's no debate. It's just different ways of organizing your thinking and ordering your instructions. None is inherently better. Objects are super easy to visualize, though. That's a major advantage.
     
  8. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240
    Don't want to derail the thread since it is about interfaces but functional programming is not about whether the language has the concept of an object or not. ES6 has classes but they are just syntactic sugar wrapping a pattern for creating objects to make the transition easier for people coming from other languages, it's still prototypical inheritance under the hood. I would also argue javascript is not really a great functional language to begin with.

    Good examples of functional languages are haskell, clojure, scheme/clisp, python to a degree, etc. Carmack has a good piece on it taken from one of his talks: http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
     
    Last edited: Jul 26, 2015
  9. thxfoo

    thxfoo

    Joined:
    Apr 4, 2014
    Posts:
    515
    Linux is pure C, there are no classes in C.

    Yes, but there are problems for which one way of thinking is better than the other.
     
    Master-Frog likes this.
  10. Master-Frog

    Master-Frog

    Joined:
    Jun 22, 2015
    Posts:
    2,302
    Didn't know that Linux was pure C. That's weird. Learn something new every day.

    As for the problem/thinking thing, that's untouchable... too many people, too many ways of solving the same problem.
     
  11. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    If you're a beginning programmer, it's good to learn about interfaces and stuff.

    You should definitely learn to understand what they are and how you use them. Just temper the usage of tools for indirection. Like, if you're going to be writing code - you should really understand how code works and what the different words and concepts are.

    It's also really important to understand that there is no 'right way'. Personally, I think that the biggest determinant of which way is best involves the people and the team.

    There's a world of difference between "one guy writing code for himself" and an environment where you have developers swapping in and out of projects in a large corporation. It also changes dramatically if you're working on something small that's only a thousand lines of code, or something bigger in the hundreds of thousands of lines. The concerns, the problems, it all varies a lot.

    This board itself is really weird, like the range of experience and competence really ranges from like total noob to extremely experienced. This thread alone has a ton of 'mixed signals' because what one person means when they talk about interfaces (and the code that goes along with them) is just entirely different than what another person might be meaning. People are talking from so many different levels of exposure as well as competence.
     
    Last edited: Jul 25, 2015
    Kiwasi and GarBenjamin like this.
  12. Master-Frog

    Master-Frog

    Joined:
    Jun 22, 2015
    Posts:
    2,302
    Specifically to address that last part... yep. That's why I like this place. Let's face it, nobody knows everything. We're all noobs and we're all pros at something. Nobody shouts anybody down and everyone gets to share their pov, wrong, right or otherwise. I think we all benefit from these kind of discussions.
     
  13. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    I don't think one way is better than another. I think it's about using the proper mix. I do think that the proper mix will ultimately speed up development time.

    I have a hierarchy of items extending from base class "Item"...these are the objects intended to go into inventory and be used by a player.

    I create "Controllers" to control those items...but things are done a little differently with interfaces.

    For Example
    WeaponController contains references to the equipped "Weapons", but some issues come up with typical parent-child class inheritance. In my setup, there could be 2 base classes:
    Weapon (Can be equipped. Generally too heavy to carry around in inventory)
    Tool (can be used in inventory on another object to do something)
    Code (csharp):
    1.  
    2. public class Weapon : Item, IAttack, IEquip{
    3. }
    4. public class Tool : Item, IUse {
    5. }
    6.  
    7. public class FireAxe : Weapon {
    8. }
    9.  
    10. public class Hatchet : Tool, IEquip, IAttack {
    11. }
    12.  
    This fundamentally changes the way my WeaponController will work. Instead of storing equipped "Weapon" type objects, I will now store IAttack objects. The interface implementation "IEquip" defines which items will have the Equip() function visible from the inventory UI.


    Similarly, we can have an "IHit" interface to interact with IEquip Armors (creates another hitbox layer), HitBoxes, Walls, Doors, Enemies or even Item's to add physics on hit.

    There's a ton of stuff you can do when you expand your toolbox, but no one tool is the "right" solution.
     
    NotaNaN likes this.
  14. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I'll stick with classes then when I need fields. Just to stick with the philosophy that interfaces should not have states. Thanks for the examples.
     
  15. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    As has been stated there are all different ways to use (or not) any of this stuff. To me interfaces are ideal just to provide a consistent interface (gasp!) across different classes This is primarily useful to easily swap in new behaviors.

    For example if instead of making a PrinterDriver concrete class that us used for printing what I do (this is speaking of work-wise development) is have that using a IPrinterDriver interface and only the IPrinterDriver interface is actually referenced by other classes. This allows a new class SuperDuperPrinterDriver to be created and set as the current IPrinterDriverInterface and nothing else needs to be updated anywhere in the code. It makes it very simple to do testing for enhancements / bug fixes as well. This instance of IPrinterDriver can be using OldPrinterDriver and a test performed. Then later the instance of the IPrinterDriver can use NewAndImprovedPrinterDriver and another test performed. Also a TestIt concrete class can be used as IPrinterDriver and perhaps it simply writes to a log file, displays information on the screen or whatever.

    These might not be very clear but wuat I am getting at is interfaces allow you to easily swap in new behavior without impacting anything else in the system. By programming to interfaces instead of concrete classes you gain that layer of abstraction that just makes things easier all around for the most part.

    For Unity I use interfaces to make gathering information from other classes (like in the case of collisions) easier and not requiring hardwired references.

    Sorry to typos etc doing this on the cell phone and it is being stubborn. Need a reboot.
     
    Last edited: Jul 25, 2015
    DBarlok and sluice like this.
  16. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    And then there is "the Unity way" to do this which is with components. Every weapon would be GO/prefab with all of the inheritance you outline as a separate component. If it is used to attack, you put an attack script on it and fill out it's values. If it performs a specific interaction, it has a component you attach to it (and this could even be several different scripts for each use case or one script that has assigned values to determine what it's use cases are). This is going to save much more time since you don't have to re-implement (copy&paste) every interface you create.

    A better use case is communication between AI, pathfinding, and steering. AI finds something it want's to go to, and it does a getcomponent for IPathfind on itself. It doesn't matter what the actual pathfinder is, could be one of a thousand different algorithms, it's just going to get the start and end point and return a path. That path then goes to IMove that is a component that has whatever steering behaviors in place. The mob could be a tank, a figure skater, or a bat, but the basic structure of communication between the types of scripts wouldn't change.

    @Slyder The more I look at what you've posted, the more it looks like it's both hacked together and over engineered (an impressive combo to pull off). By the time you get to hatchet, it's pretty clear you're using interfaces to circumvent the deadly diamond while also not saving yourself much work. From what it sounds like, the classes that use these objects don't even really care what types they are and could just as easily use data to represent what they are.
     
  17. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270

    Lol...I think you may be right. I was just building this as an exercise to see when and when not to use Interfaces since it's a fairly new concept to me. I like it quite a bit for certain things, but I am also interested in how I might make this less complicated using components.

    How would I define a different way to Attack for different objects? Separate Attack scripts? or would you use SendMessage("Attack") with an Attack() function in the objects controller script?

    How would you handle the below situations the "Unity Way" using components?
    -Many different Prefabs...some can be collected into inventory some can't (ie Goblin vs Tree vs Potion)
    -Many different Prefabs...some can be stacked in inventory and some can't. (ie Sword vs Scroll)
     
    Last edited: Jul 25, 2015
  18. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    You need to consider what is deciding to attack from what carries out the motions, communications with other GOs, etc. You probably want to look at events (C# events, not Unity events), so that what carries out an action subscribes to what would declare an action. No coupling and typing required.
     
    phatality123 likes this.
  19. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900

    From the very first post in the thread.. When did the Generic version of GetComponent start supporting interfaces..?
     
  20. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    Don't know but it definitely works lol
     
  21. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,193
    "GetComponent family of functions now supports interfaces as generic argument."

    https://unity3d.com/unity/whats-new/unity-5.0
     
  22. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    That's new as of unity 5? Wow, I've not been using interfaces for very long!
     
  23. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    They snuck in a few cool methods in 5.0 that I always forget about. Like the generic version of Instantiate.
     
  24. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    It's hard for me to wrap my mind around the concept of Component based architecture. I "get" it, but I'm just not familiar with it.

    Would this be considered "Component-based"?

    Code (csharp):
    1.  
    2. public class Item : MonoBehaviour {
    3.  
    4.     public string itemName;
    5.     public int itemBulk;
    6.     public Sprite itemIcon;
    7.  
    8. }
    9.  
    10. [RequireComponent (typeof(Item))]
    11. public class ItemStack : MonoBehaviour {
    12.     public int stackSize;
    13.     public int stackBulk { get { return stackSize * GetComponent<Item>().itemBulk; } }
    14. }
    15.  
    16.  
    If I attach both of these to a gameobject i have a "Item Stack".

    upload_2015-7-25_18-1-58.png

    So in this example, I create a Prefab and I have a stack of some Item named Ammo. I would create an Ammo component which would handle everything related to ammo (ie, which guns can shoot it, what kind of Bullet it shoots). In this case, I could remove the "ItemStack" component and create Ammo that no longer stacks, such as a Rocket.

    Is this Component based thinking? Also, where do interfaces and traditional OOD fall into this sort of architecture?
     
  25. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    This is component based thinking at its extreme. You can avoid interfaces altogether by using small MonoBehaviours in there place. It can be messy for complex behaviours.
     
  26. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    So my biggest issue is how you're supposed to communicate with components throughout the object. For example, when the Stack is split, ideally it would return an Item for inventory management purposes. The Transform or the GameObject that these scripts are attached to are the only real things that the components have in common.

    This code would be used for things like Picking up an Item. If the object is stackable but you cannot hold the whole stack, you can Split the stack.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. [RequireComponent (typeof(Item))]
    6. public class ItemStack : MonoBehaviour {
    7.     public int stackSize;
    8.     public int stackBulk { get { return stackSize * GetComponent<Item>().itemBulk; } }
    9.  
    10.     public Transform SplitStack(int numToSplit) {
    11.         if(numToSplit < stackSize) {
    12.             var newStack = Instantiate (this);
    13.             newStack.stackSize = numToSplit;
    14.             this.stackSize -= numToSplit;
    15.             return newStack.transform;
    16.         }
    17.         else
    18.             return this.transform;
    19.     }
    20. }
    21.  
     
  27. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    Why wouldn't the stack just be a part of Item? Why would there be any difference between a stack of 1 and not being stackable? It seems like it would be an intrinsic property of items. Even if it's not going to be stacked, it would still need the same checks if the number present becomes zero.
     
  28. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    You would then need all of the functionality and variables related to Stacking an item whether the item will stack or not. Furthermore, you now need booleans such as "canStack"

    I'm not opposed to making "All items stacks". I used stacking as an example, but this extends into every aspect of the item.
    Items that can be Equipped.
    Where do Items equip to.

    I could easily end up with a huge blob of code in the Item class in an attempt to account for all possible differences an Item may have.

    On a side note: the code above did what it was intended to do... heh
    upload_2015-7-25_18-44-37.png
     
  29. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Not quite. A non stackable item is a special case of a stackable item where the maxStackQuantity == 1. You could handle every item as a stack if you liked.

    But back onto the component pattern, it's still useful to use abstract base classes or interfaces to control dependency and communication between components. You don't have too, but any other solution leads too tight coupling. In some cases tight coupling is fine, a stack component might always require an item component.

    I personally I'm souring a little on going full blown small component based design. It's primarily due to picking up an existing project with logic interlaced across seventeen components on each GameObject. Sometimes a few larger components with inspector configurable behaviour is better.
     
    NotaNaN, Slyder and GarBenjamin like this.
  30. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Well, people have already given examples on at least two different levels of abstraction for this.

    Even so, the second part of that sentence - "that nothing else can do" - is somewhat missing the point. There is always another way to get the same functionality. Heck, we could arguably write our whole game in a lower level language without all these nice features and still get the same functionality... eventually. The point is to find the easiest/fastest/most efficient/most performant/most maintainable ways to get a given job done in a given context. And with that in mind, there are times when interfaces are super handy, just in the same way that there are times when classes, inheritance, components, etc. are all super handy.
     
    NotaNaN, frosted and Kiwasi like this.
  31. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    There does become a point where coding Call of Duty in assembly means you run out of hours in your lifetime.
     
    angrypenguin likes this.
  32. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Why, does assembly not support copy and paste?

    #3:30amBURN
     
    the_motionblur and Kiwasi like this.
  33. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    Nice! I had an ongoing project built in Unity 4 that is not a candidate for upgrading to 5 and so I missed out on the whole 5 launch and small details like this. I do have it now though and started a personal project as a means to come to terms with everything new.
     
  34. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    This is totally correct. Even when you have created an interface for some or other logic , there could be shared implementation logic for all class's that use the interface and then a base class or abstract class comes into play perfectly.

    Here is a practical example , when building pinball tables I have 3 different objects that are "lights"

    1. Actual Unity lights
    2. Objects that have a additive shader that is manipulated
    3. Materials that have their emission manipulated.

    So you create an interface for these 3 different objects like IEmissionObject.

    The way I then code these objects has some shared implementation , firstly I use 2 value objects / data transfer objects instead of having the fields in the class itself. These vo's are injected via two methods and the code in each of these methods would not differ between the three objects , so they are perfect examples of base class/abstract class methods.

    eg..

    Code (csharp):
    1.  
    2. public abstract EmissionObjectBase : IEmissionObject {
    3.  
    4.     protected EmissionObjectParams nonSequencedParams;
    5.     protected EmissionObjectParams sequencedParams;
    6.  
    7.  
    8.  
    9.     public void SetNonSequenceParams(EmissionObjectParams newNonSequenceParams){
    10.         nonSequencedParams = newNonSequenceParams;
    11.         if (sequencedParams != null){
    12.         if (sequencedParams.objectState ==            EmissionObjectParams.EmissionObjectStates.ANIMATION_COMPLETED) {
    13.             ApplyParams(nonSequencedParams);
    14.         }
    15.       }else{
    16.            ApplyParams(nonSequencedParams);
    17.       }
    18.  
    19.     }
    20.  
    21.     public void SetSequenceParams(EmissionObjectParams newSequenceParams){
    22.         sequencedParams = newSequenceParams;
    23.         ApplyParams(sequencedParams);
    24.      
    25.     }
    26.  
    27.     public virtual void ApplyParams(EmissionObjectParams paramsToApply){
    28.         // different implemetation for different type of emission objects handled here in concrete override
    29.  
    30.     }
    31.  
    32.  
    33. }
    34.  
    35.  
     
    Last edited: Jul 26, 2015
  35. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    So if I had a GameObject with Components "Item" and "PickUp" attached to it, how would I handle inventory collections. Anything I attach "PickUp" on would be picked up, but without coupling between PickUp and Item, how would I store this GameObject in some inventory collection?

    With coupling I would just RequireComponent (typeof(Item)) and store a reference to the Item component inside PickUp, but doesn't that kind of defeat the purpose of components? At that point, I might as well put all of the PickUp logic inside of the Item class.

    Furthermore, without using Tags, how would I generalize the "Use()" functionality? Is this where interfaces come into play? When I push E, I would like to try to "Use()" whatever object is hit, and then process some item specific logic. In this case PickUp would look like...

    EDIT: Thinking of this further (while on the crapper) I think PickUp logic should just be inside the Item class since all Items and only items are Picked Up. I can then use an interface IUse on Item to handle player interaction.

    Code (csharp):
    1.  
    2. public class PickUp: MonoBehaviour, IUse {
    3. Item itemRef;
    4.  
    5. public void Use() {
    6.      PickUp();
    7. }
    8.  
    9. public void PickUp() {
    10.      //pickup logic
    11. }
    12. }
    13.  
     
    Last edited: Jul 26, 2015
  36. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    Just like @angrypenguin mentioned dont forget about using all the features of the language you are using.. OOP and component based programming are all just a paradigm , in the famous OOP design pattern book by the gang of 4 they stress programming towards an interface and not an implementation , this is to get a good base structure, but interfaces alone is just the start, after that come various design patterns and most of these structures have base / abstract classes and various functionality is achieved in concrete classes normally via at least one level of inheritance and using method overrides.

    In my example code above there is an interface, then an abstract class and then the different light objects would extend this class and override the virtual method "ApplyParams" to perform specific implementations. The ket point here is that the external code that use my interfaced objects dont know about or need to know about the different implementations , they only know to trust being able to call the interfaced methods.

    You also need to consider that you can implement many interfaces in one class and also that inheritance respects interfaces as well.
     
  37. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    I do not want to derail thread into Component discussion, but I do think interfaces and components could be used well together in some cases perhaps.Hopefully someone could point me in the right direction with this:

    Easy to understand implementation of Component based design: Player.
    Player has various Components that function individually and on their own. None of the components care about the other components. (ie HungerComponent, HealthComponent, ThirstComponent, etc...)

    More complex scenario that I cannot understand how you would decouple as components. Feels like spaghetti code as inheritance or component design.
    Items (independent gameobjects)
    • Different items interact with Character in different ways. Food -> HungerComponent
    • Used through the UI (Canvas)
    InventoryController (child of Character stores held items)
    UIController (child of Character...controls the UI (canvas)
    Canvas (independent gameobject...Items are used in the UI by Character)

    How is it even possible to implement this without spaghetti
     
    Last edited: Jul 26, 2015
  38. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    I think you are underestimating what spaghetti code looks like. Most of what you're talking about is architectural, so graph it out. Draw up a class diagram, and chart out what communicates where. The times something needs to grab and receive from other classes continuously is when you have problems.
     
  39. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    Thanks for clearing this up. This forum has the tendency to make me completely question my ability at times lmao.

    After drawing up a diagram, it really isn't very complicated.

    UIController gets item list from InventoryController.
    UIController adds and removes ItemButtons from the Canvas scrollview.
    ItemButtons point to the Item they are created for.
    Item alters some component on Character on use depending on the Item.

    It's just a big circle. The Character object actually does not need to be aware of anything that happens in the sequence.
     
  40. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Be wary of circular dependencies. They can be difficult to work with.
     
  41. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    I don't like using interfaces because of performance concerns and most of the stuff I do is very specific. Inheriting from a class is more performant and feels more comfortable. There are times to use interfaces, however, and when those times come one definitely shouldn't shy away from them.
     
  42. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I thought the use case for interfaces was when you didn't need variables, because inheritance was the worse performing of the two lol.
     
  43. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    It probably depends. Using interfaces does save you constructor calls as there's no base class to have to construct, though worrying about that would be overoptimization. Method calls are slightly slower in interfaces, but the difference is negligible. Also, it's possible to add methods to base classes without affecting children (depending on the modifiers) but if you add something to an interface you'll always have to add a matching item to everything that implements an interface as it breaks the "contract" otherwise and results in compile time errors. There are pros and cons to both.

    Just to add a little substance, this benchmark here shows the difference to be in the range of 1 nanosecond, so definitely not something that should factor into your decision on which to use:
    http://www.dotnetperls.com/interface-virtual-performance
     
    Tomnnn likes this.
  44. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Yeah... I wouldn't worry about call performance unless I intended to be calling it many times per tick. And if I need to worry about that kind of performance I typically resort to fundamentally different approaches - data flow based design rather than any form of OO. I mean, if that level of performance is important I don't want to be worrying about how fast calls are, I want to be not making calls in the first place, using one method to operate on all of the data at once and having the data stored such that it can be accessed efficiently for that use case.
     
    GarBenjamin and Kiwasi like this.
  45. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Oh. Nope, so far my interfaces have been a sort of "usable" interface I stick on things. Doors, switches, items, etc.

    Very interesting point. I acknowledge how minor the performance differences are, I'm just trying to pick a good philosophy so I can justify my choices :p
     
  46. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Yeah, I've used some pretty expensive systems in the past for this kind of thing and even on old, low end, mobile devices they've never come up as being worth optimising. Also consider stuff like how Unity calls methods on MonoBehaviours, and how SendMessage and such work - plenty of projects ship using these things. Look at better performing alternatives, but only where it actually matters.
     
    Kiwasi likes this.
  47. Slyder

    Slyder

    Joined:
    Oct 17, 2013
    Posts:
    270
    Maybe you could help me flesh this out. I am trying to consider ways to build a decoupled dynamic component based system using interfaces. While not a proper UML class diagram, the below image illustrates the foundation of the use case of "consuming" an Item. With this system, any combination of "IItemConsumer" controllers could be added to an Object to control how they can consume Items.

    1. InventoryController can PickUp() Items and Add them to itemList.
    2. UIController toggles the Canvas and populates a ScrollView of "ItemButtons" from invRef.itemList.
    3. OnClick() of ItemButton, selectedItem is set to ItemButton.itemRef. ActionPanel is displayed with appropriate list of options based on interfaces.
    4. On click of ActionConsume Button, some component in character should Try to consume the Item.

    Notes:
    • InventoryController is self-cleaning, removing all null Items from itemList in Update().
    • Item stack handling fucntions are self-destructing, Destroying the item when stackQty < 1;
    • Items are unaware of Character or the UI, therefore, consumption of Item must be routed through some other Controller. Such as an iteration through consumers or passing consumers as a parameter to Item.

    In this case, we have an Item that should increase calories in HungerController (if exists), hydration in ThirstController (if exists), and then reduce stackQty by 1, but only if at least one of the consumers is able to process.

    While this seems more difficult to design up front, I think it is a design that is easier to modify and maintain.
    In theory, there may be many other controllers that Items interact with in different ways, such as Health, Debuffs, Injuries.

    NOTE: I am almost certainly over-complicating this because I am doing it as a learning experiment. My primary concerns are with communication handling between components in component based design.


    upload_2015-7-27_9-17-59.png
     
    Last edited: Jul 27, 2015
  48. derf

    derf

    Joined:
    Aug 14, 2011
    Posts:
    356
    Sort of what I was driving towards, I agree that there are times where a developer will want to "combine" elements together in some fashion whether that be in multiple inheritance or interface implementing interfaces. For example IBreakable and IRepairable are probably OK to implement into a "parent" interface to than link just that parent into a base class to get access to the methods to break and repair objects that share those methods like crates, potion bottles, furniture, doors, etc.

    Personally I feel far more comfortable having each interface as its own "element" and implement each one I need in a base or abstract class, UNLESS it is needed such as the IDisposable interface example, where I will have 2 or more interfaces being implemented into a "parent" interface; but I have not had such a need for such an implementation.

    Dustin's post about SDK's, is one example where you will find yourself writing custom interfaces for your DLL for a customer or client where you will probably be implementing IDisposable, IComparable, etc. into your own interface.

    I just have not seen such an implementation like that in a general development (I do mostly web apps with some console) or game scripting for Unity.
     
    Dustin-Horne likes this.
  49. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yep, and in my day to day I do a tremendous amount of service oriented development. Since we are very heavily unit tested (over 90% code coverage) we need to be able to also fake / stub our APIs because we're only interested in testing the logic, not the actual service call (the service itself has its own unit tests).

    So as an examply, we have an IProxyFactory<T> with a GetProxy definition. The only thing our service share in common is that they are services. Each has it's own impelementation of IProxyFactory<T> which gives you back the appropriate proxy and our unit tests fake out the service so it doesn't make any remote calls. The other nice side effect of our architecture is that we have primarily WCF services since it is an internal enterprise application, however there are some things that are better suited for REST as they will have some external endpoints and/or deal with file streaming differently. However, our APIs for our REST services also implement IProxyFactory<T> and are available as NuGet packages (internally). As a developer, when you inject and use one of the services you have no idea whether it is REST or WCF as it is injected, instantiated and executed exactly the same way (except under the hood where the factory does the actual instantiation). It brings consistency to our services as there's only one way to consume them regardless of host.
     
  50. venuscles

    venuscles

    Joined:
    Jul 27, 2015
    Posts:
    4
    From my understanding of point, I'd say the strategy design pattern is a great use of interfaces. I thought the use case for interfaces was when you didn't need variables, because inheritance was the worse performing of the two lol.
     
    Last edited: Aug 13, 2015