From: S Perryman on
Vladimir Jovic wrote:

> S Perryman wrote:

>> From the construction/testability viewpoint, we are asking whether you
>> can construct/test thus :

>> E -> F
>> D -> E
>> C1 -> D
>> B -> C1 + C2
>> A -> B

>> where the entities on the right-hand side of the "->" are the real
>> entities, or test stubs.

> I can, but the problem (I think) is that I am using real objects for
> unit testing.

For the example I have given, are you stating that in order to do
verification of E, you are using a "real" F etc ??

If so, do you believe that to be an issue ??
Because it actually isn't.

Using E -> F as the example, the reasons that one would provide a test
stub variant of F, in order to test an implementation of E are :

1. No implementation of F is available at the time that verification of
E is to be done

2. The effort required to operate an actual implementation of F (which
could be a complex environment - hardware etc, have poor testability
etc) , has a very low ROI (time, resources etc) in terms of the actual
verification being done on E.


If none of the above apply, a real implementation of F (on the precondition
that F itself has passed its verification process) is perfectly acceptable
for use in verification of E.


>> On that basis, the "Demeter" principles are probably most appropriate.
>> These attempt to minimise the dependencies that entities have on
>> eachother.

>> You will also find that the Demeter concepts have good synergy with
>> things like dependency injection.

> That means I am on good tracks, because that is how I designed the
> system (based on the Demeter concepts).

Good.


Regards,
Steven Perryman
From: Vladimir Jovic on
S Perryman wrote:
>
> On that basis, the "Demeter" principles are probably most appropriate.
> These attempt to minimise the dependencies that entities have on eachother.
>
> You will also find that the Demeter concepts have good synergy with things
> like dependency injection.
>

Forgot to ask : what are other OO architecture design approaches?
Do you have a link with summarises all? Or at least all major?
From: johnzabroski on
On Apr 29, 4:21 am, S Perryman <a...(a)a.net> wrote:
> johnzabro...(a)gmail.com wrote:
> > On Mar 22, 7:40 am, Vladimir Jovic <vladasp...(a)gmail.com> wrote:
> > 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.
>
> Ironic, as all the examples I've ever seen presented by the test-driven
> "gurus" have appalling testability (by "testability" I use the long-
> time qualitative/quantitative definitions used by the hardware/software
> engineering communities) .
>
> Regards,
> Steven Perryman

I am not sure who your list of gurus are, but I've certainly seen at
least one "guru" admit in a public presentation that how they test
code changed over time, especially once they learned to "mock roles,
not objects."

TDD also is much harder way to do unit testing than the methodology
laid out by H.S. Lahman on his blog, but most practitioners do not
understand the simplicity of the actors model and its simplified
version for real-time embedded systems.
From: johnzabroski on
On Apr 29, 4:50 am, Vladimir Jovic <vladasp...(a)gmail.com> wrote:
> johnzabro...(a)gmail.com wrote:
>
> > 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.
>
> You got that more or less right.
>
> The good thing is that I have better confidence in unit tests, because
> they are doing more then just unit testing. Not all things are
> "emulated" (as in TDD), but the very bad side is the maintenance is
> getting harder.

I disagree, completely. You have less confidence *in your current
methodology*, and therefore abuse unit tests to do more than just test
units.

Maintenance is not simply getting harder. It is not simply that it is
harder to write correct code for new specifications, or write correct
code to amend an existing specification. It is that you have no
structural integrity whatsoever to your solution. The fact that
superclasses are controlling leaf classes means that you have no
static relationships that show the structure of your problem domain.
You have no structure chart. When the spec changes, that indicates
something has changed in one or more collaborators. The spec may
invalidate the role of a collaborator, and suggest that you need to
change the static structure of your application. By doing this
*analysis*, without writing any code, you can predict how hard
maintenance is going to be.

On the other hand, by using your current approach, you have no way to
tell your client, who is revising the spec, "Whoa, this is way out of
scope, and will cause cost-overruns if we don't negotiate; I have to
pay for Vlad Juniors babysitter."




> > 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.
>
> I know, but I am trying to improve :)
>
> What are alternatives? How to fix such architecture?

Model the problem -- I can't really give better advice without knowing
something about the problem. Chances are, if you are writing code in
a way such that superclasses are controlling leaf classes, they you
have a specification where the problem can be broken down into stages
(what you are currently using classes with arbitrary names for)

> I am looking into dependency injection, but if you know of more
> techniques and design patterns that are used in TDD, would be great if
> you share.

From: johnzabroski on
On Apr 30, 5:22 pm, "johnzabro...(a)gmail.com" <johnzabro...(a)gmail.com>
wrote:
> On Apr 29, 4:50 am, Vladimir Jovic <vladasp...(a)gmail.com> wrote:
>
>
>
> > johnzabro...(a)gmail.com wrote:
>
> > > 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.
>
> > You got that more or less right.
>
> > The good thing is that I have better confidence in unit tests, because
> > they are doing more then just unit testing. Not all things are
> > "emulated" (as in TDD), but the very bad side is the maintenance is
> > getting harder.
>
> I disagree, completely.  You have less confidence *in your current
> methodology*, and therefore abuse unit tests to do more than just test
> units.
>
> Maintenance is not simply getting harder.  It is not simply that it is
> harder to write correct code for new specifications, or write correct
> code to amend an existing specification.  It is that you have no
> structural integrity whatsoever to your solution.  The fact that
> superclasses are controlling leaf classes means that you have no
> static relationships that show the structure of your problem domain.
> You have no structure chart.  When the spec changes, that indicates
> something has changed in one or more collaborators.  The spec may
> invalidate the role of a collaborator, and suggest that you need to
> change the static structure of your application.  By doing this
> *analysis*, without writing any code, you can predict how hard
> maintenance is going to be.
>
> On the other hand, by using your current approach, you have no way to
> tell your client, who is revising the spec, "Whoa, this is way out of
> scope, and will cause cost-overruns if we don't negotiate; I have to
> pay for Vlad Juniors babysitter."
>
> > > 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.
>
> > I know, but I am trying to improve :)
>
> > What are alternatives? How to fix such architecture?
>
> Model the problem -- I can't really give better advice without knowing
> something about the problem.  Chances are, if you are writing code in
> a way such that superclasses are controlling leaf classes, they you
> have a specification where the problem can be broken down into stages
> (what you are currently using classes with arbitrary names for)
>
> > I am looking into dependency injection, but if you know of more
> > techniques and design patterns that are used in TDD, would be great if
> > you share.

Oops. I hit send too soon. Please re-read carefully, as I've
inserted sentences below from what I've written above in the last
paragraph. I should've said:

> > What are alternatives? How to fix such architecture?

Model the problem -- I can't really give better advice without knowing
something about the problem. Based on experience with this code
smell, where superclasses are pervasively controlling leaf classes, I
can *guess* what the general solution would look like, but I don't
want the general solution to be your *actual* solution. So what
follows is my analysis of the meta-problem, not the problem domain
itself.

If you are writing code in a way such that superclasses are
controlling leaf classes, then you have a Specification where the
problem can be broken down into Stages (what you are currently using
classes with arbitrary names for). If at each Stage you cannot
predict what the sequences of actions will be, then you also need a
Sequence abstraction so that each Stage is composed of Sequences. But
this analysis is not complete; you need to recursively specify what
the specification of each stage and sequence is. In other words, a
Sequence must collaborate with a SequenceSpecification and a Stage
must collaborate with a StageSpecification. A StageSpecification is
composed of SequenceSpecifications, so that when you want to reuse the
Stage, you instead focus on reusing its Specification, giving you a
degree of freedom in how to implement the Stage by taking advantage of
what the Specification *doesn't* say. This analysis will allow you to
*easily* apply parametric polymorphism on-demand at each Stage and
Sequence, as well as allow for implementation hiding.

Your current solution doesn't really allow parametric polymorphism in
a safe way, and it doesn't allow for implementation hiding since the
parent superclasses must know about their child subclasses in order to
properly control them.