one minor correction:
"I'm not saying that base classes are a bad thing - I think they're a great
thing (when done as a part of refactoring) for eliminating duplicate code
that is used between families of classes."
better said "used within a family of classes"
-----Original Message-----
From: Howard Dierking
Sent: Thursday, September 29, 2011 10:28 AM
To: [email protected]
Subject: Re: API Design
I tend to take the interface approach - here are some of my reasons:
1) I've observed that designs that structure dependencies based on concrete
(even abstract) types tend to have classes that have larger, more
fine-grained interfaces (e.g. higher coupling between components). In a
somewhat related characteristic, over time they also tend to grossly violate
the single-responsibility principle.
2) Architectures with class dependencies have a tendency to introduce
coupling to state (properties) rather than solely behavior. It doesn't have
to be this way, but in my observation, it ends up happening a lot (I suspect
this is because it *feels* more natural to work with state in classes rather
than interfaces).
3) Said architectures, for some reason (again, doesn't have to be this way)
tend to also follow a "create, configure, use" pattern, which drives me
freaking crazy based on the increased coupling and complexity that it tends
to introduce.
4) Largely because of 1 & 2 (and additionally, because many times when
coupling happens based on a property, the property is not virtual), unit
testing such architectures becomes more difficult because mocking using
simple tools and techniques becomes harder.
On the flip side, the counter argument that is most often made against
interfaces and in favor of concrete or abstract types is one of versioning.
The kind of design that is generally referenced has a concrete type which
has an interface (loose definition - just a set of methods) that is meant
for consumption internally and then a set of virtual or abstract methods
(generally named something like "OnXX") that form the "extension interface"
as I've heard it called. The idea here is that interface used internally
doesn't change and because it coordinates all the work of the extension
interface, the latter can change without breaking the internal API. This
also enables the concrete type's coordination methods to do pre/post
condition checking to enforce the contract and keep the derived type author
from having to write duplicate code (think of a gate to check for null refs
in parameters). From my POV, this last argument doesn't hold a ton of water
because I generally think this kind of pre/post condition processing is the
responsibility of whoever is calling the dependency, but that doesn't apply
in all cases and so it's something that is up for discussion/debate on a
case by case basis.
I'm not saying that base classes are a bad thing - I think they're a great
thing (when done as a part of refactoring) for eliminating duplicate code
that is used between families of classes. That said, **dependencies between
classes of different class families (or components) should be based
behavioral contracts and not on shared code** - hence, IMHO, they should be
based on interfaces.
just my 2 cents,
_howard
-----Original Message-----
From: Scott Slack
Sent: Thursday, September 29, 2011 9:49 AM
To: [email protected]
Subject: API Design
An acquaintance is designing an important API. One function takes a
Handler class. I advised him that the API should instead take any
object that implements the IHandler interface. I find that APIs that
take objects tend to force architecture (see XNA). His argument is
that you (the user of the API) are free to override any method you
like, and leave the default functions to handle everything else. My
suggestion is to provide a class that implements IHander, and we are
free to use it if we want. I would like APIs that don't spend my base
class. I know Karl has an opinion about this.
--
You received this message because you are subscribed to the Google Groups
"Seattle area Alt.Net" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/altnetseattle?hl=en.
--
You received this message because you are subscribed to the Google Groups
"Seattle area Alt.Net" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/altnetseattle?hl=en.
--
You received this message because you are subscribed to the Google Groups "Seattle
area Alt.Net" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/altnetseattle?hl=en.