Re: Heuristic to decide between behaviour and implementation

97 views
Skip to first unread message

David Peterson

unread,
Apr 13, 2013, 11:42:14 AM4/13/13
to growing-object-o...@googlegroups.com
No-one has replied to this yet, and I can't really answer your question but a few thoughts came to mind as I read your mail.

I wonder whether the "PlantController" would be better named "Plant"? To me, the word "controller" suggests procedural thinking - i.e. rather than having a network of objects communicate with each other to get the job done, there will be some kind of central object that directs everything.

What seems to help me most to switch out of a procedural mindset is getting the vocabulary right. There are several sets of vocabulary at different levels of abstraction in different domains. The aim is for each object to collaborate with "ideal" interfaces (roles) in the same domain and same level of abstraction. Those interfaces are implemented by other domains and/or by adapters, but the object itself doesn't know or care about that.

In Java, you have to give the interfaces explicit names. In Ruby you don't have to, but it may be worthwhile to do so to help clarify what needs to be tested and when. It would also help you create a more consistent vocabulary. I noticed in one place you refer to an object as an "instrument" and in another you call it a "device". It probably doesn't matter here, but sometimes eliminating these kinds of subtle differences in vocabulary makes a big difference.

Warm regards,
David



On Monday, April 8, 2013 11:04:53 AM UTC+1, Stefano Zanella wrote:
Hello to all,
I'm new to the list and for sure not a long-time experienced developer, so feel free to let me know if I should look elsewhere for answers to my questions.
Since it's not always easy nor obvious (at least) for me to change my mind model from procedural to OO, I'm trying to define some rough heuristics to decide whether I'm "thinking" it's something that can be classified as an implementation detail or observable behavior that should be tested. Let me clarify that with an example:

Currently I have a bridge object that separates details about communication to a serial device via a 3rd party library (let's call it RS232Device) from an object that should be responsible of handling commands and responses at a more higher level (let's call it PlantController).
Let's say that I already defined by other unit tests that PlantController has a dependency on RS232Device for what concerns *sending* commands to it. Now I need to make my way back, from raw bits emitted from serial port to the plant controller.
Since code is asynchronous, a peer can receive responses by RS232Device by registering a listener to it. This is already done in main, since a previous acceptance test already set that link (Ruby code):

class Application
  instrument = RS232Device.create serial_port
  instrument.on_data method(:receive_data)    # Here Application register itself as a listener

  ...

  private

  def receive_data(data)
     # do something
  end
end

Now I need to move receive_data() to PlantController, since that fits better the SRP principle and will help making the end-to-end pass.
What I'm trying to figure out is if I need to add a test in PlantController unit suite that checks PlantController register itself as a listener to RS232Device upon creation before rewiring components.
I feel that this would be a wrong thing to do, and that feeling (that I cannot formalize yet) is in some way supported by a smell in the test that should be written. The unit test suite for PlantController is as follows:

describe PlantController
before do
  ...
  plant_controller = PlantController.new ...
end

it 'test something' do
  # setup mock
  # call PlantController method
end

To implement the above test, I would need to do something like this:

it 'listens for responses given by device' do
  device = mock
  device.expects(:on_data).at_least_once

  new_plant_controller = PlantController.new device
 
end

Here's what I feel as a smell:
- I would need to duplicate the setup code currently handled in the before() call
- I won't "trigger" anything by calling a method on PlantController, just testing against constructor

Are these considerarions suggesting that I don't need to test this code because it is a detail on how PlantController is implemented? More generally, it is possible to define "testing code on the constructor" as an heuristic to decide something should be treated as an implementation detail?

I apologize for the verbosity, hope though that I'd been clear enough and that someone has an answer to dissipate the clouds that still reside on this kind of reasoning.
Thanks,
    Stefano Zanella

Stefano Zanella

unread,
Apr 13, 2013, 12:30:43 PM4/13/13
to growing-object-o...@googlegroups.com
David,
let me thank you first for the time spent replying to the question. I really appreciate that.

Thanks for noticing the naming issues. In fact, I did spent quite a lot of time of thinking about the vocabulary; it turns out that eventually that time was not enough, given that I even managed to mix instrumentation and device.
Maybe this is partly because my understanding of the domain is still in an early phase, but surely the catch about some words suggesting procedural behavior / thinking is important; I'll take that in great care in the future (I also wonder how much being a non-native English speaker impact the process...).

For what concerns the Ruby loose restrictions, I already came to the solution of forcing myself of thinking about interface names and keeping a graph of the architecture where those names are specified.
What I'm starting to realize, however, is that I might need to choke my thinking process a bit and favor instead more "blind" action. That is because, being myself an "overthinker" by nature, I tend to strive too much for optimal design even if I don't have all the needed knowledge about the domain at the moment (incurring the risk of entering the dangerous "what if" future thinking mode). In other words, I tend to find difficult to decide when I don't know how to cope with a concept vs. I'm not trying hard enough to cope with the smells.
I wonder if any of you face the same questions and how do you counterbalance your thinking "defects".

Again, thanks for the attention and the kind response.
Best regards,
    Stefano

Steve Freeman

unread,
Apr 13, 2013, 1:49:10 PM4/13/13
to growing-object-o...@googlegroups.com
One of the things I realised while writing GOOS was that sometimes I let a little roughness creep into the code, for example not extracting a class until I was clearer about the structure. Sometimes I have to just give the code a bit of slack to see where it goes.

Of course, that's carefully controlled to avoid it getting out of hand.

S

"Ionuț G. Stan"

unread,
Apr 14, 2013, 2:02:41 PM4/14/13
to growing-object-o...@googlegroups.com
Warning, this is off-topic to this thread.

On 13/Apr/2013 20:49, Steve Freeman wrote:
> One of the things I realised while writing GOOS was that sometimes I let a little roughness creep into the code, for example not extracting a class until I was clearer about the structure. Sometimes I have to just give the code a bit of slack to see where it goes.
>
> Of course, that's carefully controlled to avoid it getting out of hand.

I'm doing the same thing, but one of the questions that emerged out of
this is how do I communicate to the next developer the next step in my
abstraction path? The next step that I'd have done if I were him/her?

Leaving things in a state where we expect some more evidence to do the
next thing or the other tells nothing about what we have envisioned (or
maybe even planned) it would be the next step.

Would it even matter? Would it add value?


> S
>
> On 13 Apr 2013, at 17:30, Stefano Zanella wrote:
>> For what concerns the Ruby loose restrictions, I already came to the
>> solution of forcing myself of thinking about interface names and keeping a
>> graph of the architecture where those names are specified.
>> What I'm starting to realize, however, is that I might need to choke my
>> thinking process a bit and favor instead more "blind" action. That is
>> because, being myself an "overthinker" by nature, I tend to strive too much
>> for optimal design even if I don't have all the needed knowledge about the
>> domain at the moment (incurring the risk of entering the dangerous "what
>> if" future thinking mode). In other words, I tend to find difficult to
>> decide when I don't know how to cope with a concept vs. I'm not trying hard
>> enough to cope with the smells.
>> I wonder if any of you face the same questions and how do you
>> counterbalance your thinking "defects".
>


--
Ionuț G. Stan | http://igstan.ro

David Peterson

unread,
Apr 14, 2013, 4:20:43 PM4/14/13
to growing-object-o...@googlegroups.com

I generally don't write comments as I consider them a code smell. But recently (in the last year) I've started writing comments explaining my thinking and possible future directions for anything I think I'll forget or that others will find useful. I've found it really helps. I've got a brain like a sieve and I was finding that I frequently ended up rewriting code I'd previously written because I couldn't remember the direction the design was going in. A real waste of time. The comments have almost completely stopped that, but they do cause a new problem: you have to resist implementing the design you're explaining in the comment.

David

--

--- You received this message because you are subscribed to a topic in the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/growing-object-oriented-software/4S5FOWeHt5U/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to growing-object-oriented-software+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Steve Freeman

unread,
Apr 14, 2013, 4:52:57 PM4/14/13
to growing-object-o...@googlegroups.com
On 14 Apr 2013, at 19:02, Ionuț G. Stan wrote:
>> Of course, that's carefully controlled to avoid it getting out of hand.
>
> I'm doing the same thing, but one of the questions that emerged out of this is how do I communicate to the next developer the next step in my abstraction path? The next step that I'd have done if I were him/her?

I'd hope to have cleaned up before handing over, or to be working with the next person already. And, of course, they might see a better solution...

> Leaving things in a state where we expect some more evidence to do the next thing or the other tells nothing about what we have envisioned (or maybe even planned) it would be the next step.
>
> Would it even matter? Would it add value?

Don't know. An alternative is to write up major issues outside the code as tasks which can then be scheduled (or not)

S

Stefano Zanella

unread,
Apr 15, 2013, 5:20:48 AM4/15/13
to growing-object-o...@googlegroups.com

S

--

---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriente...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.


If we intend this form of development mainly as a form of communication, and if the team is cohesive enough to sort-of "respect" or "agree" to certain rules in the codebase, then leaving such controlled flaws shouldn't also be a form of communication in itself? In this sense, I agree with Steve when he says that the next person could even came up with a better solution.
Maybe the point is not how to communicate the envisioned steps in a design that is not too explicit about them yet, but how to build the team so that there is a sort of common thinking process, so to make holes and flaws communicative in themselves.

My two cents (and maybe even too much idealistic, I recognize that).

Stefano

Matt Wynne

unread,
Apr 15, 2013, 5:50:10 AM4/15/13
to growing-object-o...@googlegroups.com
On 14 Apr 2013, at 21:20, David Peterson <da...@crowdsoft.com> wrote:

I generally don't write comments as I consider them a code smell. But recently (in the last year) I've started writing comments explaining my thinking and possible future directions for anything I think I'll forget or that others will find useful. I've found it really helps. I've got a brain like a sieve and I was finding that I frequently ended up rewriting code I'd previously written because I couldn't remember the direction the design was going in. A real waste of time. The comments have almost completely stopped that, but they do cause a new problem: you have to resist implementing the design you're explaining in the comment.


+1

I'm in the habit of writing TODO comments, which record things I think at the time I'd like to do, but I don't have the time / energy for right now. That might be something as vague as 'TODO: consider whether this would work better split into two clasees'.

With a team who are all in this habit (and in the habit of resolving / removing old TODOs) I've tracked the changing health of a codebase over time just by counting the number of TODO comments in the code.

You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriente...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

David Peterson

unread,
Apr 15, 2013, 6:02:41 AM4/15/13
to growing-object-o...@googlegroups.com
I've actually been using the tag FUTURE. I've reserved the tag TODO to mean "needs cleaning up". I try to keep TODOs to a minimum. Whereas FUTUREs are fine and about possible future directions, rather than the health of the design. Sometimes I use FUTURE instead of TODO for something that could be cleaned up but that I don't feel is worth the effort at the moment. I personally don't think all code needs to be beautifully designed.

By the way, I'm saying "I" because I'm working on my own and not in a team, at the moment, so I don't how these tag definitions would work with a team, but I imagine it would work the same.

David


To unsubscribe from this group and all its topics, send an email to growing-object-oriente...@googlegroups.com.

Chris Parsons

unread,
Apr 15, 2013, 6:10:19 AM4/15/13
to growing-object-o...@googlegroups.com

On 15 Apr 2013, at 11:02, David Peterson <da...@crowdsoft.com> wrote:

I've actually been using the tag FUTURE. I've reserved the tag TODO to mean "needs cleaning up". I try to keep TODOs to a minimum. Whereas FUTUREs are fine and about possible future directions, rather than the health of the design. Sometimes I use FUTURE instead of TODO for something that could be cleaned up but that I don't feel is worth the effort at the moment. I personally don't think all code needs to be beautifully designed.

I use similar sematics: currently using TODO to mean future things to think about, and FIXME to mean "clean up this soon".

If I write comments at all, they're usually verbose and multiline, and explain why I've done something slightly differently, or not written a test where I normally would have, etc. I've also taken to writing long github commit messages to capture current thinking about the domain (for example: https://github.com/alphagov/whitehall/commit/964a314)

Chris


Steve Freeman

unread,
Apr 15, 2013, 3:52:17 PM4/15/13
to growing-object-o...@googlegroups.com
I wonder if this would work best with a maximum TODO budget to stop the usual descent into chaos.

S. 

Sent from a device without a keyboard. Please excuse brevity, errors, and embarrassing autocorrections. 

Chris Parsons

unread,
Apr 16, 2013, 4:23:12 AM4/16/13
to growing-object-o...@googlegroups.com

On 15 Apr 2013, at 20:52, Steve Freeman <st...@m3p.co.uk> wrote:

I wonder if this would work best with a maximum TODO budget to stop the usual descent into chaos.

Or:

$ crontab -l
0 9 * * * TODO_COUNT=`grep -nr "TODO:" /code | wc -l` echo "You have "$TODO_COUNTS" todo(s) in your codebase" | mail whole...@example.com -s "TODO COUNT IS "$TODO_COUNT

Annoying enough? :-)

Matt Wynne

unread,
Apr 16, 2013, 4:34:49 AM4/16/13
to growing-object-o...@googlegroups.com
On 16 Apr 2013, at 09:23, Chris Parsons <chr...@rsons.org> wrote:


On 15 Apr 2013, at 20:52, Steve Freeman <st...@m3p.co.uk> wrote:

I wonder if this would work best with a maximum TODO budget to stop the usual descent into chaos.

What I did was graph (on the wall) how the number changed over time. That gave us a good idea of which direction we were heading in.

Or:

$ crontab -l
0 9 * * * TODO_COUNT=`grep -nr "TODO:" /code | wc -l` echo "You have "$TODO_COUNTS" todo(s) in your codebase" | mail whole...@example.com -s "TODO COUNT IS "$TODO_COUNT

Annoying enough? :-)

Rails actually has a built-in `rake notes` which will pull them out for you. Not a lot of people know that ;)

The distinction people are making between TODO and FUTURE is interesting. FUTURE sounds a bit like the Someday / Maybe list from David Allen's Getting Things Done. Maybe explicitly labelling it as that makes you more likely to write down and communicate what might feel like quite vague design ideas.

Steve Freeman

unread,
Apr 16, 2013, 4:36:40 AM4/16/13
to growing-object-o...@googlegroups.com
As long as you put a small lower bound in before triggering the email 

Steve Freeman

Written on a phone, so please allow for typos and short content.  

On 16 Apr 2013, at 09:23, Chris Parsons <chr...@rsons.org> wrote:

David Peterson

unread,
Apr 16, 2013, 4:55:54 AM4/16/13
to growing-object-o...@googlegroups.com
I think that's a good analogy. It helps get those design thoughts out of your head, so you know you can come back to them later on, without having to waste brain cycles trying to remember them.


--
 
---
You received this message because you are subscribed to a topic in the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/growing-object-oriented-software/4S5FOWeHt5U/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to growing-object-oriente...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages