Design to interfaces or Design to introspections

Marco Leise via Digitalmars-d digitalmars-d at puremagic.com
Fri Apr 7 06:30:00 PDT 2017


Am Fri, 07 Apr 2017 11:51:10 +0000
schrieb سليمان السهمي (Soulaïman Sahmi)
<sahmi.soulaimane at gmail.com>:

> […]
> 
> Then I stumbled upon DIP84, which reminded me of the other GoF' 
> principle "Program to an interface, not an implementation".
> And I started wondering why would I ever write code like this:
> 
>      auto someAlgorithm(SomeInterface obj) { /* ... */ }
> 
> When I can do this:
> 
>      auto someAlgorithm(I)(I obj) if(isSomeInterface!I) { /* ... 
> /* }
> 
> or more generically:
> 
>      auto someAlgorithm(I)(I obj)
>      if(satisfiesInterface!(I, SomeInterface, SomeOtherInterface 
> /*... etc */)
>      { /* body ... /* }
> 
> This would be a modern design to introspection? that goes with
> the modern design by introspection.
> […]
> 
> What do you think.

Running the same algorithm on class and struct instances is a
much desired feature, especially where programmers tend to
fall into two camps where one mostly uses classes and the
other mostly uses structs.
But reasons for using one over the other slip into the concept
of one-function-to-rule-them-all as well. And there is more to
consider:

- Interfaces variables hold references to the data, while for
  structs you have to explicitly add "ref" to the argument or
  else the algorithm will work on a (shallow) copy.
- Wrapping structs in interfaces and using interfaces
  exclusively results in only on instance of the algorithm
  ending up in the executable instead of one per each class
  and struct type, which helps with things like executable
  size, instruction cache hits and debug symbol size and
  readability.
- Some forms of licensing break when using templates in the
  public API of libraries. Two examples:
  A proprietary software company sells programming libraries.
  They need to keep their source code private to prevent theft,
  but if their API used templates they'd have to provide
  sources for them and any templates used inside of them.
  On the other hand a GPL licensed open source library - to be
  usable in a proprietary project - must ensure that none of
  its code gets compiled into the target application. Again
  templates would break that.

Then there are other general considerations in favor of
interfaces or templates.

- Template methods are not virtual functions that you can
  override in a child class.
- Calling virtual methods on interfaces is slower (on some
  architectures more than others)[1] and there is no static
  introspection to decide some code paths at compile time.
  (Devirtualization is a hot topic.)
- Templates increase complexity for the compiler and runtime.
  There have been a few subtle issues in the past, for example
  symbol name length explosion[2] and object files containing
  old code in separate compilation scenarios[3].

[1] http://eli.thegreenplace.net/2013/12/05/the-cost-of-dynamic-virtual-calls-vs-static-crtp-dispatch-in-c
[2] http://forum.dlang.org/post/efissyhagontcungoqkx@forum.dlang.org
[3] https://issues.dlang.org/show_bug.cgi?id=9922

-- 
Marco



More information about the Digitalmars-d mailing list