From: Daniel T. on
Vladimir Jovic <vladaspams(a)gmail.com> wrote:
> Daniel T. wrote:
> > Vladimir Jovic <vladaspams(a)gmail.com> wrote:
> > > Daniel T. wrote:
> > > > Vladimir Jovic <vladaspams(a)gmail.com> wrote:
> > > >
> > > > > PS In case I wasn't clear enough, here is a simple ASCI diagram:
> > > > > a -> b
> > > > > \-> c -> d
> > > > > \-> e
> > > > > \-> f
> > > > >
> > > > > The question : How to test class c, using stubs for classes
> > > > > d,e,f? An example in c++ would be perfect, but java or other
> > > > > language is ok as well
> > > >
> > > > Looking at your diagram, if 'd', 'e', and 'f' were all ints
> > > > would you be concerned with testing 'c' in isolation to them? I
> > > > think not. You can be sure that 'int' is fully tested and
> > > > functions, and you rely on that fact when testing to see that
> > > > 'c' works.
> > >
> > > Yes, off course. Doing that makes not sense.
> > >
> > > > Things aren't much different when 'd', 'e' or 'f' are classes
> > > > that you write, except that you have more work to do in order to
> > > > make sure they are fully tested before you can test 'c' properly.
> > >
> > > The problem I am facing is the unit tests are becoming more and
> > > more complex as the we go more levels down. But is there an
> > > alternative?
> >
> > I'm not sure what you mean by "levels down" do you mean d, e, and f
> > are harder to test than c, or that c is harder to test than d, e,
> > and f?
>
> If the system looks like this:
>
> a -> b -> c -> d -> .... -> x -> y
> -> ...
> -> ...
> -> ...
>
> where all these are classes, then testing a is basically the
> functionality test. But if you want to write unit tests for b or c,
> things are more complicated then for example writing for x or y.
> Unless you use mock classes.

Not at all. Your job when testing b or c is the same as when testing x
or y... make sure that each function meets its postconditions when its
preconditions hold true. The cyclomatic complexity of 'b' should be
about the same as the cyclomatic complexity of 'x'.

> > Either way, if you distributed your functionality well, no class
> > should be harder to test than any other.
>
> Might be a stupid question, but is there a metric or method to measure
> functionality distribution?

I use the number of tests necessary for thorough path test coverage.
Figure out the cyclomatic complexity of each module (class) in your
system, and try to bring them on par. Don't be dogmatic about it, but if
you have some modules that are much higher than average, those are god
classes and need to be re-distributed. Classes that are much lower are
data buckets and should probably take on more responsibility.

Here is the original paper on cyclomatic complexity:

http://classes.cecs.ucf.edu/eel6883/berrios/notes/Paper%204%20(Complexity
%20Measure).pdf

As a practical matter, you determine the cyclomatic complexity of a
class by adding the following:

+1 for each non-const member function.
+1 for each loop ('while' and 'for') in the member functions of the class
+1 for each decision ('if' and 'case') in the member functions of the
class
-1 for each exception ('throw') in the member functions of the class

Yes, you are literally counting keywords here, which makes it an easy
thing to do. Maybe you can even write a tool that does it for you.

BTW, the above assumes two things, (1) that you never put mutating state
inside a conditional and (2) that you only throw an exception when there
is a contract violation.
From: Garrett Smith on
Daniel T. wrote:
> Vladimir Jovic <vladaspams(a)gmail.com> wrote:
>> Daniel T. wrote:
>>> Vladimir Jovic <vladaspams(a)gmail.com> wrote:
>>>
>>>> PS In case I wasn't clear enough, here is a simple ASCI diagram:
>>>> a -> b
>>>> \-> c -> d
>>>> \-> e
>>>> \-> f
>>>>
>>>> The question : How to test class c, using stubs for classes d,e,f?
>>>> An example in c++ would be perfect, but java or other language is
>>>> ok as well
>>> Looking at your diagram, if 'd', 'e', and 'f' were all ints would
>>> you be concerned with testing 'c' in isolation to them? I think not.
>>> You can be sure that 'int' is fully tested and functions, and you
>>> rely on that fact when testing to see that 'c' works.
>> Yes, off course. Doing that makes not sense.
>>
>>> Things aren't much different when 'd', 'e' or 'f' are classes that
>>> you write, except that you have more work to do in order to make
>>> sure they are fully tested before you can test 'c' properly.
>> The problem I am facing is the unit tests are becoming more and more
>> complex as the we go more levels down. But is there an alternative?
>
> I'm not sure what you mean by "levels down" do you mean d, e, and f are
> harder to test than c, or that c is harder to test than d, e, and f?
>
> Either way, if you distributed your functionality well, no class should
> be harder to test than any other.
>
>>> The key to "self-containment" is that 'c' does expose its 'd', 'e'
>>> or 'f' and rely on others changing the state of them outside of
>>> itself. In other words, your aim should be a containment
>>> relationship (as defined by Riel, not the UML version of
>>> containment) wherever possible.
>> Great. Do you recommend Riel's book to improve OO design? I found this
>> on the net:
>> http://lcm.csa.iisc.ernet.in/soft_arch/OO_Design_Heuristic.htm
>> (summary of OO design from Riel)
>
> Yes, I recommend it highly.
>

I see:

| 2. Users of a class must be dependent on its public interface, but a
| class should not be dependent on its users.

What about IoC? What is wrong with depending on abstractions.


| 18. Eliminate irrelevant classes from your design.

Only classes? What about methods or even statements?

Dead code makes the code harder to read and hides bugs.

| 37. Derived classes must have knowledge of their base class by
| definition, but base classes should not know anything about their
| derived classes

NO abstract classes? If an abstract class has two methods, m1 and m2, m1
calls m2, and m2 is abstract then it must be implemented by the
subclass. That seems to violate this principle.

I agree with a lot of what is written, though it seems a bit rough.

[...]
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Daniel T. on
Garrett Smith <dhtmlkitchen(a)gmail.com> wrote:
> Daniel T. wrote:
> > Vladimir Jovic <vladaspams(a)gmail.com> wrote:

> > > Do you recommend Riel's book to improve OO design? I found this on
> > > the net:
> > > http://lcm.csa.iisc.ernet.in/soft_arch/OO_Design_Heuristic.htm
> > > (summary of OO design from Riel)
> >
> > Yes, I recommend it highly.
>
> I see:
>
> | 2. Users of a class must be dependent on its public interface, but a
> | class should not be dependent on its users.
>
> What about IoC? What is wrong with depending on abstractions.

From the book:

If a contained object is dependent on the class that contains it,
then it is not reusable. If the card reader of an automatic teller
machine has knowledge that it is contained in an ATM, then it cannot
be taken out of the ATM and used to build a security door...

When a contained object must send a message to its containing class,
then the containing class should be made more general through
judicious use of inheritance. In this way, the contained object does
not depend on the containing class, only on its base class. It is
easier to require a reuser to inherit from some abstract class than
to use a particular class (effectively ruining any chance of reuse
outside of the original domain).

In other words, there is nothing wrong with depending on abstractions,
there is something wrong with depending on concrete types.

> | 18. Eliminate irrelevant classes from your design.
>
> Only classes? What about methods or even statements?
>
> Dead code makes the code harder to read and hides bugs.

The heuristic that covers methods is: "Do not clutter the public
interface of a class with things that users of that class are not able
to use or are not interested in using." As for statements, the book is
aimed at Object-Oriented heuristics, not general programming heuristics.

Now you might wonder why two different heuristics? The answer is due to
the difference in granularity and reusability. In order for a class to
be reusable, it often must provide methods that not all users use. (For
example, there are many methods on your typical container class that may
never be used in any one particular context, or even in an entire
program, but they are used by some of their clients.) However, an
"irrelevant class" is defined in the book as a class that has only the
standard complement of methods that all classes are expected to
implement (as per heuristic 4: "Implement a minimal public interface
that all classes understand.") Such classes have (almost literally) no
functionality within any system.

> | 37. Derived classes must have knowledge of their base class by
> | definition, but base classes should not know anything about their
> | derived classes
>
> NO abstract classes? If an abstract class has two methods, m1 and m2,
> m1 calls m2, and m2 is abstract then it must be implemented by the
> subclass. That seems to violate this principle.

Here there is some confusion about what the "knowing something about"
means:

If base classes have knowledge of their derived classes, then it is
implied that if a new derived class is added to a base class, the
code of the base class will need modification.

Riel goes on to specifically address the use of polymorphism to avoid
these sorts of issues. In other words, your example does not violate
this heuristic, rather it is a method for avoiding the violation of this
heuristic.

More concretely:

class Base {
virtual void foo() = 0;
public:
void bar() {
foo();
}
};

The class above depends only on its own interface, it does not depend on
the interface, or implementation of any derived class.

> I agree with a lot of what is written, though it seems a bit rough.

The heuristics alone as a bald list do seem a bit rough, but you have to
remember there is an almost 400 page book that goes along with them.
Also, keep in mind, the book was written in 1996 when people were new to
OO. Now, some of the heuristics are things that are an ingrained part of
the community.
From: Garrett Smith on
Daniel T. wrote:
> Garrett Smith <dhtmlkitchen(a)gmail.com> wrote:
>> Daniel T. wrote:
>>> Vladimir Jovic <vladaspams(a)gmail.com> wrote:
>
>>>> Do you recommend Riel's book to improve OO design? I found this on
>>>> the net:
>>>> http://lcm.csa.iisc.ernet.in/soft_arch/OO_Design_Heuristic.htm
>>>> (summary of OO design from Riel)
>>> Yes, I recommend it highly.
>> I see:
>>
>> | 2. Users of a class must be dependent on its public interface, but a
>> | class should not be dependent on its users.
>>
>> What about IoC? What is wrong with depending on abstractions.
>
> From the book:
>
> If a contained object is dependent on the class that contains it,
> then it is not reusable. If the card reader of an automatic teller
> machine has knowledge that it is contained in an ATM, then it cannot
> be taken out of the ATM and used to build a security door...
>


Thanks you for the clarification and elaboration.

Is the conclusion in the first sentence is strongly supported by the
rest of the paragraph?

The rest of the paragraph misses a more obvious point: Why paint
yourself into a corner with tangled design as tight coupling?

Arguments about the security door are going to seem like far fetched
theoretical paranoia to a project manager who is commissioned to a
project regarding ATM cards and won't likely have much influence.

The Card's implementation details depending will result in confusing
code in the Card. Such coupling might cause problems when a new ATM
vendor comes on the market (different host environment). Addressing
those problems is going to cost money and having everybody in a mad
scramble trying to make things work in the new version or make of the
ATM when it is released.

This sort of thing is unfortunately too common with javascript for the
web. Programs are often tied to proprietary (mis)features of a
particular host environment (browser).

Then when "it doesn't work", you end up seeing code like:

| <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" >

The sad thing is that most of the "cross browser" javascript libraries
that you'll see suffer from these avoidable problems.

Implementation code is also often tied with details of a javascript
library. The jQuery javascript library, for exmaple, provides methods
that are very complicated and loosely defined. When they change, it
tends to "not work" for the user going through an upgrade.

> When a contained object must send a message to its containing class,
> then the containing class should be made more general through
> judicious use of inheritance. In this way, the contained object does
> not depend on the containing class, only on its base class. It is
> easier to require a reuser to inherit from some abstract class than
> to use a particular class (effectively ruining any chance of reuse
> outside of the original domain).
>

OK.

> In other words, there is nothing wrong with depending on abstractions,
> there is something wrong with depending on concrete types.
>

Right.

>> | 18. Eliminate irrelevant classes from your design.
>>
>> Only classes? What about methods or even statements?
>>
>> Dead code makes the code harder to read and hides bugs.
>
> The heuristic that covers methods is: "Do not clutter the public
> interface of a class with things that users of that class are not able
> to use or are not interested in using."


Right.

As for statements, the book is
> aimed at Object-Oriented heuristics, not general programming heuristics.
>

OK.

> Now you might wonder why two different heuristics? The answer is due to
> the difference in granularity and reusability. In order for a class to
> be reusable, it often must provide methods that not all users use. (For
> example, there are many methods on your typical container class that may
> never be used in any one particular context, or even in an entire
> program, but they are used by some of their clients.)

Sounds cluttered.

I try to get maximum reuse out of each module. Who wants to use a module
that is largely irrelevant? Regarding code that must be downloaded
before being interpreted, certainly the user does not!

However, an
> "irrelevant class" is defined in the book as a class that has only the
> standard complement of methods that all classes are expected to
> implement (as per heuristic 4: "Implement a minimal public interface
> that all classes understand.") Such classes have (almost literally) no
> functionality within any system.
>

I see. But what if someone *is* genuinely interested in using that
interface? What if, for example, an interface is defined and then an
implementation implements all of those methods in a specific way such
that other implementations would find irrelevant? What about State or
Strategy, for that matter?

For example, an interface with a "blendTo" method that acts as a
strategy. Color transition is implemented in a way that would make no
sense to the transition for length, yet ColorTransition and
LengthTransition have identical interfaces, making them both redundant.

>> | 37. Derived classes must have knowledge of their base class by
>> | definition, but base classes should not know anything about their
>> | derived classes
>>
>> NO abstract classes? If an abstract class has two methods, m1 and m2,
>> m1 calls m2, and m2 is abstract then it must be implemented by the
>> subclass. That seems to violate this principle.
>
> Here there is some confusion about what the "knowing something about"
> means:
>
> If base classes have knowledge of their derived classes, then it is
> implied that if a new derived class is added to a base class, the
> code of the base class will need modification.
>
> Riel goes on to specifically address the use of polymorphism to avoid
> these sorts of issues. In other words, your example does not violate
> this heuristic, rather it is a method for avoiding the violation of this
> heuristic.
>

I see. I think the problem is his terminology "no knowledge". Obviously,
a superclass that is designed to be such knows that it has a subclass (a
subclass has knowledge of its superclass should go without saying).

Reil is not capable of describing exactly what it is that is a problem
from which he has derived his badly written principle.

A more suitable principle, IMHO:

Do not rely on implementation details or other side effects of an object
- code to the interface (as above).

> More concretely:
>
> class Base {
> virtual void foo() = 0;
> public:
> void bar() {
> foo();
> }
> };
>
> The class above depends only on its own interface, it does not depend on
> the interface, or implementation of any derived class.
>

Right. *That* makes sense.

>> I agree with a lot of what is written, though it seems a bit rough.
>
> The heuristics alone as a bald list do seem a bit rough, but you have to
> remember there is an almost 400 page book that goes along with them.
> Also, keep in mind, the book was written in 1996 when people were new to
> OO. Now, some of the heuristics are things that are an ingrained part of
> the community.

Ah, if only it were true with javascript community. Take a look at, for
example, Dojo or MooTools.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: johnzabroski on
On Mar 22, 7:40 am, Vladimir Jovic <vladasp...(a)gmail.com> wrote:
> Hello,
>
> In the article in Lahman's blog here:http://pathfinderpeople.blogs.com/hslahman/what_is_oo_development_all...
> the explanation about self-containment in OO tells this:
>
> ***
> As a practical matter that means that any object responsibility can be
> exhaustively unit tested without implementing any other object behaviors
> ***
>
> What if the system is complex, and this class handles other classes?
> What are strategies for handling this case?
>
> Since I am working in C++, I can imaging that the testing class is
> implemented as a template, where the template parameters are the classes
> that the tested class handles.
> Or, is there other way?
> This seams like a complex solution just to simplify testing.
>
> Thanks in advance.
>
> PS In case I wasn't clear enough, here is a simple ASCI diagram:
> a -> b
>    \-> c -> d
>          \-> e
>          \-> f
>
> The question : How to test class c, using stubs for classes d,e,f?
> An example in c++ would be perfect, but java or other language is ok as well

The problem here is methodological, and has nothing to do with code.

You are fundamentally abusing the static production rules of your
third generation language.

You are using an inheritance hierarchy to create a "controller tree".
In Executable UML, Balcer and Mellor emphatically state:

"The first rule of control partitioning is that you do not make
controller objects. The second rule of control partitioning is that
*you do not make controller objects.", Executable UML, page 236,
http://books.google.com/books?id=zBS0aWNjBqcC&pg=PA236&lpg=PA236&dq=The+first+rule+of+control+partitioning+is+that+you+do+not+create+controller+objects.&source=bl

It is fundamentally obvious to anyone looking at your example that you
are using object superclasses as a way to control leaf classes. What
you've effectively done is build a lattice, or house of cards, for a
software system. The reason unit testing is getting progressively
harder is that you don't actually have any real world analagous units
to test, so as you make changes to your software, you have to edit the
lattice appropriately. This requires preserving an entailment
relation through all leaf classes that ensures value paths are
steady. Technically speaking, this is fundamentally impossible to do
and will guarantee client code will break if it is using value paths
now absorbed by the new class.

Bottom line: Your software, as implemented, sucks, and is not testable
in the way OO programmers discuss testability. Kent Beck pioneered
Test-Driven Development as a way to help prevent programmers from
making such design mistakes, because testing first generally causes
programmers to steer clear of such awful designs.