On Dec 30, 2007, at 1:42 AM, Zach D. wrote:
and embedding those design ideas into your specs.
The fact is that you are going to spend time on designing, testing and
implementing anyways. It is a natural part of software
development. You cannot develop software without doing these
things. The challenge is to do it in a way that better supports the
initial development of a project as well as maintenance and continued
development.
I certainly didn’t mean to imply that you shouldn’t do any design or
testing. If I had to guess at my coding style versus the average
RSpec user, based on what’s been said in this thread, I’d guess that
I do about as much writing of tests/specs, and probably spend less
time designing. But there is certainly such a thing as overdesigning,
as well, right? I’m always trying to find the right amount, and I
suspect that “the right amount” can vary somewhat in context.
explicit, because of the limits of implicity knowledge team members
can get from one another through everyday conversation, etc.
This argument doesn’t pan out. First, it’s highly unlikely that
the same developers are on a project for the full lifetime of the
project. Second, this fails to account for the negative impact of bad
code and design. The negative impact includes the time it takes to
understand the bad design, find/fix obscure bugs and to extend with
new features or changing to existing ones.
Again, I did not say “if you have a small team you don’t have to do
any design at all.” I said that perhaps if you have a much smaller
team you can spend a little less time on design, because implicit
knowledge is much more effectively communicated.
Are you disagreeing with this point? Are you saying that two software
projects, one with four developers and the other with forty, will
ideally spend the exact same percentage of time thinking about
modeling, designing, etc.?
accounts for these.
I wasn’t saying that some businesses needs never change. The point I
was trying to make is in that some sorts of businesses and companies,
change happens more often, and can be expected to happen more often
based on past experience.
The challenge is to write code that is not chaotic, and to learn to do
it in a way that allows the code to be more meaningful and that
enhances
your ability to develop software rather then hinder it.
I wonder if part of the disconnect here depends on terminology. Some
might see “chaos” as a negative term; I don’t. There are plenty of
highly chaotic, functional systems, both man-made and natural.
Ecosystems, for example, are chaotic: They have an order that is
implicit through the collective actions of all their agents. But that
order is difficult to understand, since it’s not really written down.
I guess that’s what I’m trying to express when applying the word
“chaos” to code: It functions for now, but perhaps the way it works
isn’t as expressive as it could be for a newcomer coming to the code.
Another thing I’d express is that I find a codebase to assymetrical,
in terms of how much specification each individual piece needs. I
find it surprising, for example, when people want to test their Rails
views in isolation. I write plenty of tests when I’m working, but I
try to have a sense of which pieces of code require a more full
treatment. I’ll extensively test code when the cost/benefit ratio
makes sense to me, trying to think about factors such as:
- how hard is it to write the test?
- how hard is the code, and how many varied edge cases are there that
I should write down?
- are there unusual cases that I can think of now, that should be
embodied in a test?
cost: Spec code has a maintenance cost as well. If I can get the same
understand what I need to do. When I understand what I need to do I
test drive my development. Now different rules apply for when you use
mocks. In previous posts in this thread I pointed out that I tend to
use a branch/leaf node object guideline to determine where I use mocks
and when I don’t.
My understanding of a spike is to write code that explores a problem
that you aren’t certain is solvable at all, given a certain set of
constraints. That’s not the lack of understanding I’m talking about:
I’m more addressing code that I know is easily writeable, but there
are a number of issues regarding application design that I haven’t
worked out yet. I’d rather write a test that encapsulates only the
external touchpoints – submit a form, receive an email, click on the
link in the email – and leave any deeper design decisions to a few
minutes later, when I actually begin implementing that interaction.
There’s another kind of “not understanding” that’s also relevant
here: A “not understanding” due to the fact that you don’t have all
the relevant information, and you can’t get it all now. For example:
You release the very first iteration of a website feature on Monday,
knowing full well that the feature’s not completed. But the reason
you release it is because on Wednesday you want to collect user data
regarding this feature, which will help you and the company make
business decisions about where the feature should go next.
while and look for it. It’s got to be somewhere in my apartment, and
the whole thing’s not even that big.
Two things about this bothers me. One, this implies that from the
get-go it is ok to leave crap around an application code base.
Well, not to belabor the analogy, but: It’s not “crap”. If it’s in my
apartment, I own it for a reason. I may not use it all the time, it
may not be the most important thing in my life, but apparently I need
it once in a while or else I’d throw it away. I may not spend all my
time trying to find the optimal place to put it, but that doesn’t
mean I don’t value it. I just might value it less than other things
in my apartment.
program for my customer. And where I find the ideals clashing with
that goal I will abandon the ideals. Knowing this, parts of my
application may be clutter or imperfect, but I am ok with this and so
is my customer – he/she has a running application.
"
That’s probably close to what I’m trying to say. But in a broader,
philosophical sense, I’m okay with the fact that my code is never
going to be perfect. Not at this job, not at any other job. In fact I
don’t know if I’ve ever met anybody who gets to write perfect code.
We write code in the real world, and the real world’s far from
perfect. I suppose Wabi Sabi comes into play here.
To bring it back to mocks: It seems to that mocks might play a role
in your specs if you were highly focused on the design and
interaction of classes in isolation from all other classes, but
understanding that isolation involves having done a decent amount of
design work – though more in some cases than in others. But if you
were living with code that was more chaotic/amorphous/what-have-you,
prematurely embedded such design assumptions into your specs might do
more harm than good.
I do, incidentally, use mocks extensively in a lot of code, but only
in highly focused cases where simulating state of an external
resource (filesystem, external login service) seems extremely
important. Of course, that usage of mocks is very different from
what’s recommended as the default w/ RSpec.
Francis H.