[Twisted-Python] twisted.positioning -- Interface, or class with method stubs?

Laurens Van Houtven lvh at laurensvh.be
Mon Aug 10 07:46:32 EDT 2009


> Have you read this?
>
> http://glyph.twistedmatrix.com/2009/02/explaining-why-interfaces-are-great.html

Yep, I have (and just read it again).  I think I get it, sort of, kind
of, but I don't think I'll really understand it until it all comes
together.

>> The thing is, t.p.nmea.NMEAAdapter needs to (at least, I think so)
>> implement all of the methods of t.p.ipositioning.IPositioningProvider,
>> because people will subclass t.p.nmea.NMEAAdapter and override the
>> corresponding (stub) methods.
>
> I don't think this is the case.  NMEAAdapter implements INMEAReceiver.  It
> should take an IPositioningProvider as an argument somewhere, not implement
> that interface itself.

Ah, that makes much more sense, indeed. I'm guessing that people
should be allowed to connect multiple such providers, instead of just
one? Otherwise I could always implement one that takes multiple such
providers as *its* argument later of course.

> A user implementing a position-aware application should be encouraged as
> strongly as possible to avoid any NMEA-specific junk in their application
> until it comes time to connect the app logic (IPositioningProvider) to the
> actual device spitting out NMEA data.  After all, they're not going to be
> able to easily make use of cell-tower positioning information if their
> application class is hard-coded to subclass NMEAAdapter.

That makes even more sense.

>> In order to get all of the stub methods implemented (otherwise people
>> using the class need to implement *every* method, which is dumb, since a lot
>> of people won't care about things like GPS climb),
>
> The general sentiment here is right, despite the terminology problem I
> pointed out: somewhere, a user is going to implement an IPositioningProvider
> and it's quite likely that they won't want to implement every method.  So
> let's assume there's going to be a BasePositioningProvider which stubs out
> many of these methods or unifies / simplifies them.
>
>> I would basically be copying every line of the body of the interface into
>> the t.p.nmea.NMEAAdapter.
>
> Not quite.  For one thing, your method declaration lines will have a 'self'
> in BasePositioningProvider, and in IPositioningProvider they won't.  (I
> notice that this is not currently the case.  You should probably fix that:
> interface method definitions should never include 'self'.)

Fixed in trunk, thanks.

> Also, your methods' docstrings won't need to be as complete as those on the
> interface, since they can just say "implement L{IPositioningProvider.foo}
> to...".

> Finally, I hope most of the methods will actually have a body that has some
> implementation; some default behavior that will be useful  For example,
> remembering the last position / heading / speed / error so that
> 'positionReceived' can conveniently expect the last error received without
> implementing that method itself.  One or two might be completely stubbed
> out, but the interface can't contain any implementation.

The adapter already keeps state. I think this is necessary, because of
the way NMEA fragments information in sentences. I'm not sure how that
implementation would work though -- wouldn't people that care about
position end up overriding that method, hence making the non-stub
useless?

>> This sounds like a dumb idea.
>
>
> Let's assume the worst case: BasePositioningProvider has absolutely no
> default behavior besides a no-op.  The level of duplication we're talking
> about here is this:
>
>     def positionReceived(self, latitude, longitude):
>     def positioningErrorReceived(self, positioningError):
>     def headingReceived(self, heading):
>     def headingErrorReceived(self, headingError):
>     def magneticHeadingReceived(self, magneticHeading):
>     def altitudeReceived(self, altitude):
>     def altitudeErrorReceived(self, altitudeError):
>     def speedReceived(self, speed):
>     def speedErrorReceived(self, speedError):
>     def climbReceived(self, climb):
>     def climbErrorReceived(self, climbError):
>
> In other words, the duplicated code in question will be considerably shorter
> than the body of the message you composed to fret about code duplication,
> and way shorter than my response :-). This doesn't really seem excessive,
> considering that there's no duplication of functionality (the interface only
> specifies behavior, the base class implements it), only duplication of text.

Okay, I'll implement that class, expect it in trunk soon :-)

thanks for your response
Laurens



More information about the Twisted-Python mailing list