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