SerialPort refactoring

David Farber dfarber at numenor.com
Wed Feb 13 22:42:41 UTC 2002


<frothing>
On defaults: Why do you lose defaults? Keep 'new' if it can return some
sensible default, or create a constructor called 'default', or any other
name that makes sense *and* communicates. As it stands now, SerialPort
class>>new does neither returns a sensible default nor communicates
effectively--witness Bergel's lost week.

On combinatorial selectors: When I see combinitorial explosion of
constructors (ala HTTPSocket), the first thing that pops into my mind is
that parameter gathering is a significant activity in its own right, and
thus deserves to be in a class by itself. (XPers call this the Single
Responsibility Rule). So we need a SerialPortParameters class. 'baudRate',
'baudRate:' et al should be moved out of SerialPort and into
SerialPortParameters. Now we are left with one contructor on SerialPort
that takes a SerialPortParameters instance. And we add SerialPort>>reset:
that takes a SerialPortParameters instance as well. Having removed the
parameter getters and setters from SerialPort, we are no longer tempted to
believe that we can instantiate a SerialPort first and *then* try to set
its parameters; it is clear that we must provide the parameters first.
</frothing>

<ranting>
And quit your whining about the SerialPortParameters class. If we can't
recognize and implement the easy classes, how are we ever going to get the
harder, trickier classes right?!
</ranting>

:)

david

At 02:49 PM 2/13/02 -0700, you wrote:
>Lex Spoon wrote:
>> 
>> > If a SerialPort is not useable until its parameters have been set,
then the
>> > SerialPort code needs to be factored thusly:
>> >
>> > add
>> >   SerialPort class>>baudRate:dataBits:parityType:stopBitsType:
>> > and maybe even
>> >   SerialPort class>>openOnBaudRate:dataBits:parityType:stopBitsType:
>> > and (if you are a real purist) remove
>> >   SerialPort class>>new
>> > (ie. throw an exception or do self shouldNotImplement)
>> >
>> 
>> The downside is that you no longer get default parameters.  Thus you
>> either add lots of combinations of the instance creation method, or you
>> force everyone to use the long version even  when they only care about
>> one or two options.  Thus the opposite refactoring can make sense as
>> well: take an instance creation method with bunches of parameters, and
>> turn them into individual initialization methods.  A more extreme
>> example of this is HTTPSocket.
>
>Actually the defaults are still available. Just do
>
>SerialPort new
>
>Which implicitly calls SerialPort>>initialize
>
>The real problem, which I missed on the first pass, was the changing of
>parameters after the opening of the port. Having worked with serial
>ports often in the past I would never do that, but I can understand how
>someone might to try to do so.
>
>So... a fix that would satisfy both camps would be to add something like
>this to all of the parameter setting methods.  I'll pick on baudRate:
>
>baudRate: anInteger
>     baudRate := anInteger.
>     self resetOnOpenPort.
>
>resetOnOpenPort
>     port ifNotNil: [openPort: port].
>
>Note that openPort: closes the port before it opens it.
>
>If you wanted to prevent the user from changing the parameters to an
>open port, it would take same amount of code, but with the reopen
>approach Alexandre's code works the first time. And I can change baud
>rate or other configuration parameters on the fly.
>
>If I get any positive comments on this approach, I'll send in a
>changeset.
>
>Steve
>
>
--
David Farber
dfarber at numenor.com



More information about the Squeak-dev mailing list