Are you really using JUnit during your development?

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 | Next >

Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Robert Martin wrote:

>> 2. No precondition, postcondition, or class invariant validation
>
> I think unit tests are a better way to ensure this kind of  
> validation.  However, if you must have them in line, then put them in  
> the derived classes where they belong.

At best, unit tests verify that *my* code is not violating my
preconditions. They do nothing about verifying that *your* code is not
violating my preconditions.

Each public method cannot assume anything about where it is called from.
It is its responsibility to enforce its preconditions and guarantee its
postconditions. Each public method cannot assume anything about where it
is called from. It is its responsibility to enforce its class
invariants. Unit tests may verify that the class is behaving properly in
this fashion, but they do nothing to enforce the requirements.

--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Robert Martin wrote:
>>> Elliotte, what are the downsides of interfaces, in your opinion?
>> 1. Excess complexity
>
> They make receiving a message more complex, it's true.  They make  
> sending a message much simpler.  Or rather, they add more lines of  
> code on the receiving side; but they eliminate dependencies on the  
> sending side.  The benefit of those eliminated dependencies is very  
> powerful.
>

I'm not sure I believe the second part. In practice, replacing a
concrete-class based solution with an interface-based solution expands
the complexity for the caller. What used to require a single class now
typically requires three: a factory to create the factory, the factory
itself, and the interface you're actually trying to create. I'm not sure
you really need all that, but you need at least two pieces where you
previously needed one, and in practice three is what we usually seem to
end up with. (Think of DocumentBuilderFactory, DocumentBuilder, and
Document in JAXP/DOM for example). And of course there are still
concrete classes for each of these. We've turned what could have been
one concrete class (Document) into six separate pieces! What could have
been this:

Document doc = new Document();

is now this:

DocumentBuilderFactory factory = DocumentBuilderFactory.getInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();

I fail to see how that's simpler.

--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Cédric Beust ♔ :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 9/1/06, Robert Martin <UncleBob@...> wrote:

>
>
> > Suppose you publish an interface:
> >
> > public interface IAccount {
> >   public void processCash();
> > }
> >
> > In v2, you decide your account needs to support credit cards as
> > well, so you
> > create the following interface:
> >
> > public interface IAccount2 extends IAccount {
> >   public void processCreditCard();
> > }
>
>
> This path leads to madness.


Indeed it does, but the real world is madness itself.

Hence the popularity of this approach, because despite the added complexity
on the API developer side, it buys a lot of flexibility to the users.


I HOPE that the trick used in COM and Eclipse that you were referring

> to was:
>
>       |IAccount|    |IAccount2|
>           A              A
>           |              |
>           +------+-------+
>                  |
>               |MyAccount|
>
> (i.e. the Interface Segregation Principle) Which satisfies Elliotte's
> third point since users of IAccount do not need to know about
> IAccount2 unless they want to call processCreditCard.


The Interface Segregation Principle is nice when it can be applied, but it
doesn't respect the is-a relation, and very often, users of IAccount2 need
to use methods of IAccount on the same instance (imagine that I add a
"getAccountNumber()" on IAccount if you need an example to picture the
problem).

--
Cédric
http://testng.org


[Non-text portions of this message have been removed]



 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Parent Message unknown Re: Test-friendly, but not caller-friendly?

by unclebob :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> At best, unit tests verify that *my* code is not violating my
> preconditions. They do nothing about verifying that *your* code is not
> violating my preconditions.

Why do you worry about me?  I'll write my own unit tests, you  
concentrate on yours.  It is not your job to debug my code.

Now, maybe you are building a framework and are trying to be kind to  
the callers of that framework by giving them expressive and  
diagnostically interesting error messages.  That's fine, and if I  
were a caller I would be grateful.  I would also be grateful to see  
your unit tests since they would tell me how to call your framework  
and what to expect from it, and how NOT to get your expressive and  
diagnostically interesting error messages.


----
Robert C. Martin (Uncle Bob)  | email: unclebob@...
Object Mentor Inc.            | blog:  www.butunclebob.com
The Agile Transition Experts  | web:   www.objectmentor.com
800-338-6716                  |






[Non-text portions of this message have been removed]



 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Parent Message unknown Re: Test-friendly, but not caller-friendly?

by unclebob :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Robert Martin wrote:
>
> > [interfaces] make receiving a message more complex, it's true.  
> They make
> > sending a message much simpler. Or rather, they add more lines of
> > code on the receiving side; but they eliminate dependencies on the
> > sending side. The benefit of those eliminated dependencies is very
> > powerful.
> >
>
> I'm not sure I believe the second part. In practice, replacing a
> concrete-class based solution with an interface-based solution expands
> the complexity for the caller. What used to require a single class now
> typically requires three: a factory to create the factory, the factory
> itself, and the interface you're actually trying to create. I'm not  
> sure
> you really need all that, but you need at least two pieces where you
> previously needed one, and in practice three is what we usually  
> seem to
> end up with. (Think of DocumentBuilderFactory, DocumentBuilder, and
> Document in JAXP/DOM for example). And of course there are still
> concrete classes for each of these. We've turned what could have been
> one concrete class (Document) into six separate pieces! What could  
> have
> been this:
>
> Document doc = new Document();
>
> is now this:
>
> DocumentBuilderFactory factory = DocumentBuilderFactory.getInstance();
> DocumentBuilder builder = factory.newDocumentBuilder();
> Document doc = builder.newDocument();
>
> I fail to see how that's simpler.

It's not.  Overuse of factories is an abomination.  So *IF* I thought  
an interface would help, I would simply prefer:

Document doc = Document.newDocument();

The simplicity of interfaces vs concrete classes comes from  
dependencies.  Let's say we have some concrete class named  
MyDocument, and it has lots and lots of methods.  Users of this class  
depend on all these methods even if they don't call them.  If I make  
a change to MyDocument it can affect all the callers to the extent  
that they all have to be recompiled and redeployed.  (Yes, you can  
play the game and try to figure out whether or not the class really  
and truly needs to be recompiled, but that way lay madness.)

If I interpose one or more interfaces then suddenly the callers  
depend ONLY on the methods in the interfaces that they use; and those  
interfaces can be *very* sparse.  Even if there is only one  
interface, and that interface has all the methods of MyDocument I can  
still swap out MyDocument for some other implementation or some Mock  
implementation.  I can also add new methods to MyDocument without  
forcing recompilation and redeployment of the callers.

 From the point of view of a caller, it is much simpler to depend on  
an interface than a concrete class.


----
Robert C. Martin (Uncle Bob)  | email: unclebob@...
Object Mentor Inc.            | blog:  www.butunclebob.com
The Agile Transition Experts  | web:   www.objectmentor.com
800-338-6716                  |






[Non-text portions of this message have been removed]



 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Parent Message unknown Re: Test-friendly, but not caller-friendly?

by unclebob :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> The Interface Segregation Principle is nice when it can be applied,  
> but it
> doesn't respect the is-a relation, and very often, users of  
> IAccount2 need
> to use methods of IAccount on the same instance (imagine that I add a
> "getAccountNumber()" on IAccount if you need an example to picture the
> problem).

public void g(IAccount2 acct2) {
   int aNumber = ((IAccount)acct2).getAccountNumber();
}

----
Robert C. Martin (Uncle Bob)  | email: unclebob@...
Object Mentor Inc.            | blog:  www.butunclebob.com
The Agile Transition Experts  | web:   www.objectmentor.com
800-338-6716                  |






[Non-text portions of this message have been removed]



 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Cédric Beust ♔ :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 9/2/06, Robert Martin <UncleBob@...> wrote:

>
> > The Interface Segregation Principle is nice when it can be applied,
> > but it
> > doesn't respect the is-a relation, and very often, users of
> > IAccount2 need
> > to use methods of IAccount on the same instance (imagine that I add a
> > "getAccountNumber()" on IAccount if you need an example to picture the
> > problem).
>
> public void g(IAccount2 acct2) {
>    int aNumber = ((IAccount)acct2).getAccountNumber();


That's not what I was saying.  If you use the Interface Segregation
Principle, you can't pass an IAccount2 to someone expecting an IAccount.

Which makes this principle fairly useless in my opinion...

--
Cédric
http://testng.org


[Non-text portions of this message have been removed]



 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Robert Martin wrote:

> It's not.  Overuse of factories is an abomination.  So *IF* I thought  
> an interface would help, I would simply prefer:
>
> Document doc = Document.newDocument();

But you can't do that with an interface. At a minimum you need

Document doc = Factory.newDocument();


> The simplicity of interfaces vs concrete classes comes from  
> dependencies.  Let's say we have some concrete class named  
> MyDocument, and it has lots and lots of methods.  Users of this class  
> depend on all these methods even if they don't call them.  If I make  
> a change to MyDocument it can affect all the callers to the extent  
> that they all have to be recompiled and redeployed.  (Yes, you can  
> play the game and try to figure out whether or not the class really  
> and truly needs to be recompiled, but that way lay madness.)

In Java, if the public interface of the class doesn't change, you don;t
need to recompile clients. In fact, even if you only add things to the
public interface of the class, you don't need to recompile clients. In
fact, you only need to recompile clients if the public interface changes
in such a way that the clients need to be rewritten.

> If I interpose one or more interfaces then suddenly the callers  
> depend ONLY on the methods in the interfaces that they use; and those  
> interfaces can be *very* sparse.  

If I have a class that depends on only two methods in the library class,
then any changes beyond those two methods and the class signature itself
are irrelevant to the client, and do not require recompilation. You do
not need to interpose an interface to get this benefit. Dynamic binding
gives this to you automatically. Now in a language like C++ that links
statically, it may be a very different story. But in Java the clients
depend only on the methods in the class that they actually use. A public
change to a method the client actually uses requires rewriting and
recompilation, but so does a change to such a method in an interface.
Interfaces add nothing to this.

>  Even if there is only one  
> interface, and that interface has all the methods of MyDocument I can  
> still swap out MyDocument for some other implementation or some Mock  
> implementation.  I can also add new methods to MyDocument without  
> forcing recompilation and redeployment of the callers.

Again, if MyDocument is a class you can still add new methods to
MyDocument without  forcing recompilation and redeployment of the
callers. This has nothing to do with interfaces and everything to do
with dynamic linking. (And again, I'm talking about Java here. It can be
different in other languages.)


--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Robert Martin wrote:

> Why do you worry about me?  I'll write my own unit tests, you  
> concentrate on yours.  It is not your job to debug my code.

It is my job to make sure my code works. I can't do that if the code
that calls it violates my preconditions and class invariants. For
detailed elaboration on these points see

http://www.cafeconleche.org/XOM/designprinciples.xhtml#d0e161

--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Michael Feathers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Elliotte Harold wrote:

>Robert Martin wrote:
>
>  
>
>>Why do you worry about me?  I'll write my own unit tests, you  
>>concentrate on yours.  It is not your job to debug my code.
>>    
>>
>
>It is my job to make sure my code works. I can't do that if the code
>that calls it violates my preconditions and class invariants. For
>detailed elaboration on these points see
>
>http://www.cafeconleche.org/XOM/designprinciples.xhtml#d0e161
>
>  
>
The essence of design by contact is that you advertise what you need so
that you don't have to check.  Bertrand Meyer was trying to come up with
a set of conventions to prevent defensive programming.. the situation
where every piece of code is responsible not only for itself but for its
correct usage.  By advertising a contract, you make the preconditions,
and usage, the caller's reponsibility.

Michael Feathers
www.objectmentor.com


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Ilja Preuss-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Elliotte Harold schrieb:

> It is my job to make sure my code works. I can't do that if the code
> that calls it violates my preconditions and class invariants.

I'm confused. I always thought a precondition is something that says "if
you violate me, there is no guarantee what the code will do".

Curious, Ilja


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Ilja Preuss-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Elliotte Harold schrieb:

> In Java, if the public interface of the class doesn't change, you don;t
> need to recompile clients. In fact, even if you only add things to the
> public interface of the class, you don't need to recompile clients. In
> fact, you only need to recompile clients if the public interface changes
> in such a way that the clients need to be rewritten.

That's true, but there is no automated way to find out which clients
need to be recompiled that I know of.

Cheers, Ilja


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ilja Preuss wrote:

> I'm confused. I always thought a precondition is something that says "if
> you violate me, there is no guarantee what the code will do".

In well written code, *anything* a client does gives specified results.
In the event of a precondition violation that result will usually be an
IllegalArgumentException. It might sometimes be a NullPointerException
or something else instead, but advertising a precondition is not an
excuse for misbehavior just because you receive bad data.

--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Michael Feathers wrote:

> The essence of design by contact is that you advertise what you need so
> that you don't have to check.  Bertrand Meyer was trying to come up with
> a set of conventions to prevent defensive programming.. the situation
> where every piece of code is responsible not only for itself but for its
> correct usage.  By advertising a contract, you make the preconditions,
> and usage, the caller's reponsibility.

I think you've misunderstood Meyer. He wanted to make the checks easier
to write. He didn't think they shouldn't happen. Providing correct input
data is the client's responsibility. Recognizing when the client has not
adhered to the contract is the library's responsibility.

--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Ilja Preuss-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Elliotte Harold schrieb:

> In well written code, *anything* a client does gives specified results.
> In the event of a precondition violation that result will usually be an
> IllegalArgumentException. It might sometimes be a NullPointerException
> or something else instead, but advertising a precondition is not an
> excuse for misbehavior just because you receive bad data.

Those sound like very personal definitions of both "well written" and
"precondition" to me.

Take care, Ilja


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Michael Feathers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Elliotte Harold wrote:

>Michael Feathers wrote:
>
>  
>
>>The essence of design by contact is that you advertise what you need so
>>that you don't have to check.  Bertrand Meyer was trying to come up with
>>a set of conventions to prevent defensive programming.. the situation
>>where every piece of code is responsible not only for itself but for its
>>correct usage.  By advertising a contract, you make the preconditions,
>>and usage, the caller's reponsibility.
>>    
>>
>
>I think you've misunderstood Meyer. He wanted to make the checks easier
>to write. He didn't think they shouldn't happen. Providing correct input
>data is the client's responsibility. Recognizing when the client has not
>adhered to the contract is the library's responsibility.
>  
>
No, the point of preconditions is really to make responsibility clear.  
People often place too much emphasis on their runtime aspect.

Regardless, you can have preconditions for interfaces in Java, you just
have to document them.

Michael Feathers
www.objectmentor.com





 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Michael Feathers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Elliotte Harold wrote:

>Ilja Preuss wrote:
>
>  
>
>>I'm confused. I always thought a precondition is something that says "if
>>you violate me, there is no guarantee what the code will do".
>>    
>>
>
>In well written code, *anything* a client does gives specified results.
>In the event of a precondition violation that result will usually be an
>IllegalArgumentException. It might sometimes be a NullPointerException
>or something else instead, but advertising a precondition is not an
>excuse for misbehavior just because you receive bad data.
>  
>

Nope.  That's pretty much counter to Design by Contact.  Do you have a
copy of Meyer's Object Oriented Software Construction?  If you do, I can
point you to some text that explains it easier than I can retype it here.

Michael Feathers
www.objectmentor.com



 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Michael Feathers wrote:

>
> Nope.  That's pretty much counter to Design by Contact.  Do you have a
> copy of Meyer's Object Oriented Software Construction?  If you do, I can
> point you to some text that explains it easier than I can retype it here.
>

Yes, I do have a copy. I suspect you're referring to p. 343-344. However
you have to remember that Meyer is writing about a language in which
preconditions can be specified *and enforced* outside the body of the
method. Since Java, unlike Eiffel, does not provide extra-method
preconditions it is therefore necessary to place the verification code
in the method body. It's not ideal, but Java is not an ideal language.

Furthermore, for most cases, Meyer recommends precondition verification
by default. See pp. 394-398

--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Michael Feathers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Elliotte Harold wrote:

>Michael Feathers wrote:
>
>  
>
>>Nope.  That's pretty much counter to Design by Contact.  Do you have a
>>copy of Meyer's Object Oriented Software Construction?  If you do, I can
>>point you to some text that explains it easier than I can retype it here.
>>
>>    
>>
>
>Yes, I do have a copy. I suspect you're referring to p. 343-344. However
>you have to remember that Meyer is writing about a language in which
>preconditions can be specified *and enforced* outside the body of the
>method. Since Java, unlike Eiffel, does not provide extra-method
>preconditions it is therefore necessary to place the verification code
>in the method body. It's not ideal, but Java is not an ideal language.
>
>Furthermore, for most cases, Meyer recommends precondition verification
>by default. See pp. 394-398
>  
>
Actually, I was going to point you to p.389 where he points out that the
use of assertions is primarily methodological and a documentation aid.
Java doesn't support runtime monitoring natively, but to me that's okay,
because it isn't the most important thing.

But back to your original point: "It might sometimes be a
NullPointerException or something else instead, but advertising a
precondition is not an excuse for misbehavior just because you receive
bad data." Under DbC, it is.  Fact is, if your precondition fails or you
get a NullPointerException, there's a bug in the client.  You can have
checking enabled, or not, but checking is not error handling.  The point
of DbC is to build software robust enough so that you don't have to
write error handling code at each level.  Relevant section is 11.6
"Assertions are not an input checking mechanism."

And when you say "It is my job to make sure my code works. I can't do
that if the code that calls it violates my preconditions and class
invariants."  Most of the time, that's trying to do too much.  You'll
lapse into defensive programming.  Again, you can easily have
preconditions for interfaces, just write them as comments.

Now, the thing that I have to admit is that I like DbC but I've only
used it a couple of times in the past.  And, I used it in systems which
lapsed into a bit of defensive programming.  One was in a continuously
running system that I designed that for medical instrumentation.  It was
about 15 years ago, and we found the documentation of preconditions
useful, and the checks, but there was always that issue of what to do
when a precondition failed.  The system had to be designed so that it
couldn't go down, all we could do is log errors and patch values to keep
it running.  We had many discussions about what failure meant and
runtime recovery, and we concluded that although DbC is nice, it is
really orthogonal to those concerns.  Our recovery checking had some
overlap with our preconditions but it was not complete.  DbC is about
documentating expectations.  You write preconditions to tell people what
you expect, and if you do, you've done most of the job that DbC was
designed for.  The other thing we learned, is that if you are clever,
you can often design away preconditions and make calls less error prone.

Michael Feathers
www.objectmentor.com


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 




Re: Re: Test-friendly, but not caller-friendly?

by Elliotte Harold :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Michael Feathers wrote:

> But back to your original point: "It might sometimes be a
> NullPointerException or something else instead, but advertising a
> precondition is not an excuse for misbehavior just because you receive
> bad data." Under DbC, it is.  Fact is, if your precondition fails or you
> get a NullPointerException, there's a bug in the client.  You can have
> checking enabled, or not, but checking is not error handling.

Then maybe we agree more than we think. If checking is not error
handling, then I accept that we don't need to handle the error. Indeed,
in many cases we can't reasonably handle the error inside the method.
However, I do think that it's important not to blindly accept a bad
argument that violates a precondition and precede blindly ahead whatever
happens. It is important to fail fast (and in a controlled and
documented way via an exception) rather than let the software corrupt
itself. Martin Fowler has written extensively about this:

http://www.martinfowler.com/ieeeSoftware/failFast.pdf


> The point
> of DbC is to build software robust enough so that you don't have to
> write error handling code at each level.  Relevant section is 11.6
> "Assertions are not an input checking mechanism."

That's something very different. Meyer clearly means *user* input in
that section, and I agree with him on that. Assertions very much are an
argument/parameter checking mechanism. I don't think we're talking here
about user input, just about how two different methods from two
different code bases communicate.

> And when you say "It is my job to make sure my code works. I can't do
> that if the code that calls it violates my preconditions and class
> invariants."  Most of the time, that's trying to do too much.


Agreed. What I really should have said is something like, "It's my job
to make sure my code works, or signals an error at the earliest possible
opportunity if it can't work due to precondition violation"

--
Elliotte Rusty Harold  elharo@...
Java I/O 2nd Edition Just Published!
http://www.cafeaulait.org/books/javaio2/
http://www.amazon.com/exec/obidos/ISBN=0596527500/ref=nosim/cafeaulaitA/


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/junit/

<*> To unsubscribe from this group, send an email to:
    junit-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 


< Prev | 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 | Next >