Prev: Last Call for Papers Reminder (extended): The World Congress on Engineering WCE 2010
Next: CFP CGVCVIP 2010: new date - until 29 March 2010
From: S Perryman on 29 Apr 2010 14:36 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 30 Apr 2010 02:00 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 30 Apr 2010 17:11 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 30 Apr 2010 17:22 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 30 Apr 2010 17:35
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. |