Hi Mark: thank you for the explanation. You found a good refinement of the Terminal Buffer Rule. -- Karl KL>Your strategies are written in a good style KL>and seem to be reused a few times. KL>I noticed some violations of the Terminal-Buffer rule. KL>Maybe you were concerned with the number of extra classes? Right, I started off religiously following the TB rule, but was daunted by the explosion of classes. Also extracting the real value out of a buffer class entails violating the Law of Demeter (e.g. get_foo().get_buffer().get_value()) or writing lots of ity-bity inline traversals. In either case you get significant code bloat which slows down the build process and impacts productivity. I started breaking the TB rule for attributes that I didn't anticipate navigating to directly in a traversal, i.e. they are not key classes in a strategy. This yields an immediate productivity gain without incuring much risk of inflexible code in the future. Regards - Mark Janney From dougo@ccs.neu.edu Fri Dec 12 10:30:56 1997 To: Karl Lieberherr Cc: Mark_Janney-P26816@email.mot.com, com3360@ccs.neu.edu, dem@ccs.neu.edu Subject: Re: refinement of Terminal Buffer Rule > Right, I started off religiously following the TB rule, but was > daunted by the explosion of classes. I'm curious as to how many more classes you would have had to use. In demjava, for instance, I only have 10 buffer classes, which is a small fraction of the total number of classes. > Also extracting the real value out of a buffer class entails > violating the Law of Demeter > (e.g. get_foo().get_buffer().get_value()) This shouldn't be necessary; you should only have to do get_buffer().get_value() from whatever class has the terminal buffer as a part. I don't view this as a violation of the LoD, but the one you give clearly is and shouldn't be necessary. Again, I'd like to see specific examples if you believe otherwise. > or writing lots of ity-bity inline traversals. In either case you > get significant code bloat which slows down the build process and > impacts productivity. I don't think you need traversals to get the values from buffer classes, but it depends on whether you view what I have above as a violation of the LoD. What I usually do instead, though, is use the buffer class *as if it were a terminal class* (except that it can be traversed to, which is an important distinction), and pass it around in place of the actual terminal class; I only get the value out when I absolutely need it (e.g. when I need to convert it to a string to pass to some Java library function, or when I need to add two numeric buffer-class objects-- these things should use methods on the buffer class, where it can all be localized). This has saved me a few times in demjava: for example, I use the ClassName buffer class all over the place, and pass it around rather than an Ident, calling toString on it when I needed to get the actual string; when I wanted to change ClassName to handle qualified class names (e.g. "java.util.Vector") I simply made it be a list of Idents, rather than a single Ident, and changed toString to concatenate the list with periods. This was practically the only thing I had to change in my whole program. > I started breaking the TB rule for attributes that I didn't anticipate > navigating to directly in a traversal, i.e. they are not key classes > in a strategy. This yields an immediate productivity gain without > incuring much risk of inflexible code in the future. What you anticipate and what actually happens are almost always different... I think there are other ways to get a "productivity gain" than compromising the maintainability of the code. --Doug