What are the pros and cons of using interfaces in Delphi?

前端 未结 9 1566
既然无缘
既然无缘 2021-01-31 17:21

I have used Delphi classes for a while now but never really got into using interfaces. I already have read a bit about them but want to learn more.

I would like to hear

相关标签:
9条回答
  • 2021-01-31 17:55

    There are some SUBTLE downsides to interfaces that I don't know if people consider when using them:

    1. Debugging becomes more difficult. I have seen a lot of strange difficulties stepping into interfaced method calls, in the debugger.

    2. Interfaces in Delphi come with IUnknown semantics, if you like it or not, you'r stuck with reference counting being a supported interface. And, thus, with any interfaces created in Delphi's world, you have to be sure you handle reference counting correctly, and if you don't, you'll end up with leaks. When you want to avoid reference counting, your only choice is to override addref/decref and don't actually free anything, but this is not without its own problems. I find that the more heavily interface-laden codebases have some of the hardest-to-find access violations, and memory leaks, and this is, I think because it is very difficult to combine the refcount semantics, and the default delphi semantics (owner frees objects, and nobody else does, and most objects live for the entire life of their parents.).

    3. Badly-done implementations using Interfaces can contribute some nasty code-smells. For example, Interfaces defined in the same unit that defines the initial concrete implementation of a class, add all the weight of interfaces, without really providing proper separation between the users of the interfaces and the implementors. I know this isn't a problem with interfaces themselves, but more of a quibble with those who write interface-based code. Please put your interface declarations in units that only have those interface declarations in them, and avoid unit-to-unit dependency hell caused by glomming your interface declarations into the same units as your implementor classes.

    0 讨论(0)
  • 2021-01-31 17:55

    The only case when we had to use interfaces (besides COM/ActiveX stuff) was when we needed multiple inheritance and interfaces were the only way to get it. In several other cases when we attempted to use interfaces, we had various kinds of problems, mainly with reference counting (when the object was accessed both as a class instance and via interface).

    So my advice would be to use them only when you know that you need them, not when you think that it can make your life easier in some aspect.

    Update: As David reminded, with interfaces you get multiple inheritance of interfaces only, not of implementation. But that was fine for our needs.

    0 讨论(0)
  • 2021-01-31 17:56

    Adding to the answers few more advantages:

    1. Use interfaces to represent the behavior and each implementation of a behavior will implement the interface.
    2. API Publishing: Interfaces are great to use when publishing APIs. You can publishing an interface without giving out the actual implementation. So you are free to make internal structural changes without causing any problems to the clients.
    0 讨论(0)
  • 2021-01-31 18:00

    Extra note on Cons: Performance

    I think many people are too blithely dismissing the performance penalty of interfaces. (Not that I don't like and use interfaces but you should be aware of what you are getting into). Interfaces can be expensive not just for the _AddRef / _Release hit (even if you are just returning -1) but also that properties are REQUIRED to have a Get method. In my experience, most properties in a class have direct access for the read accessor (e.g., propery Prop1: Integer read FProp1 write SetProp1). Changing that direct, no penalty access to a function call can be significant hit on your speed (especially when you start adding 10s of property calls inside a loop.

    For example, a simple loop using a class

    for i := 0 to 99 do
    begin
      j := (MyClass.Prop1 + MyClass.Prop2 + MyClass.Prop3) / MyClass.Prop4;
      MyClass.Update;
      // do something with j
    end;
    

    goes from 0 function calls to 400 function calls when the class becomes an interface. Add more properties in that loop and it quickly gets worse.

    The _AddRef / _Release penalty you can ameliorate with some tips (I am sure there are other tips. This is off the top of my head):

    • Use WITH or assign to a temp variable to only incur the penalty of one _AddRef / _Release per code block
    • Always pass interfaces using const keyword into a function (otherwise, you get an extra _AddRef / _Release occurs every time that function is called.
    0 讨论(0)
  • 2021-01-31 18:11

    All I can think of for now:

    Pros:

    • Clear separation between interface and implementation
    • Reduced unit dependencies
    • Multiple inheritance
    • Reference counting (if desired, can be disabled)

    Cons:

    • Class and interface references cannot be mixed (at least with reference counting)
    • Getter and setter functions required for all properties
    • Reference counting does not work with circular references
    • Debugging difficulties (thanks to gabr and Warren for pointing that out)
    0 讨论(0)
  • 2021-01-31 18:12

    Interfaces solves a certain kind of issues. The primary function is to... well, ...define interfaces. To distinguish between definition and implementation.

    When you want to specify or check if a class supports a set of methods - use interfaces.

    You cannot do that in any other way.

    (If all classes inherits from the same base class, then an abstract class will define the interface. But when you are dealing with different class hierarchies, you need interfaces to define the methods thy have in common...)

    0 讨论(0)
提交回复
热议问题