Contrary to formal, pure-OO thinking, I have my doubts as to the benefits of over indulgence in software re-use. I'm all for it where it makes sense, but I've come to the conclusion that there are limits to the effectiveness of the concept, and these limits are lower, and more easily breached than many people believe.

In the late 70's and early 80's, the car industry was just beginning to explore the possibilities of cost savings that could result from component re-use across product lines at both the national and international level.

The theory sounded great. All a given manufactures cars needed to have essentially the same elements. They all needed side lights for instance. The laws pertaining to size, position, brightness etc of these lights are exactly the same regardless of whether the vehicle is a small family hatchback, a luxury saloon, or a sports car. They are also pretty much the same, regardless of whether the car will be driven in the US, Europe or Africa. It therefore made sense (to the bean-counters at least:), to re-use a single design for many of these common elements across the entire range of vehicles whether they were big or small, or intended for foreign or domestic markets.

And so, briefly, there was a period where the steering column switch assemblies (lights, indicators, ignition etc.) were common between whole ranges of vehicles. Eventually, one manufacturer -- from memory it was GM, but don't quote me on that -- came up with an experimental design where this practice had been taken to its ultimate conclusion. The vehicle was a four door saloon. The front left-side door was interchangeable with the rear, right-side door, as were the front, right-side and rear, left-side doors. The same was true for the diametrically opposed pairs of door handles, indicator/ sidelight assemblies, hub/ disc-brake assemblies, MacPhearson strut assemblies. Front and rear number plates panels and lights, bumpers (fenders), bonnet and boot-lids (hood and trunk), even the front and rear screens.

Now, if your imaginations are active, you may well have a picture of a car that looks like you took the front halves of two identical vehicles and welded them together. with the result being a weird looking car that you couldn't tell whether it was coming or going. This wasn't the case. Although the front and rear screens were the same, they were mounted onto the body at different angles, the front being more steeply rakes than the rear which instantly gave the 'moving forward' stance that we are used to. The same design clues were used to differentiate between the front and rear engine/ luggage covers. The bumpers were mounted a slight different heights. And so on. The differentiation was further enhanced by such cosmetic things as putting a decorative 'grill' on the front, and a spoiler on the rear. The wheel arches had an asymmetric shape, which meant that seen in side-profile, the front and rear arches were different. They enhanced this by mounting small, dark coloured plastic inserts under the rear arches which made them look smaller. The application of a sill-skirt between the arches completed the asymmetric differentiation between front and rear.

The rear doors for example, opened from the rear as on normal cars, rather than the front. Of course this mean that to maintain the commonality between them, each door had to have mounting points on both edges. It also meant that the position of the door handles had to change between the FLS door and RRS door. This required duplicated cut outs, mounting spigots and blind nuts. Making these duplications/ alternations work required a little more effort to get right, but it wasn't too hard to do.

This increased the cost (and weight) of the individual assemblies, but this was more than compensated by the amortization of the somewhat more than half, of development costs across double the number of units as compared to somewhat less than double the development costs spread across half as many units that would have resulted from using four distinct assemblies rather than two.

As a design exercise, the experimental car was a tremendous success. Universally acclaimed at Motor Shows around the world and winning many prestigious awards for Innovation, Design and The Way of the Future, which in many ways is was. Look across the ranges of any large motor manufacturer and you will find many common subassemblies. Right up to a modern example of the Skoda Octavia, Seat Toledo, Audi A3 and even the TT, having a huge commonality with the VW Golf, but real-world experience has shown that there is a limit to the amount of commonality that can be abstracted to a common base.

The problem comes with the administration and arbitration of the disparate goals and requirements of the all the different end uses to which a sub-component or assembly may be put. The problems are fairly obvious with large, 'final assembly' sub components --like the doors above. It's fairly obvious that re-using the same doors for a low-slung sports coupé like the Audi TT and the hatchbacks listed is a problem.

It may not be so obvious that re-using the same doors across those hatchbacks, and even within a single model range is also problematic. Not many people realise that the front doors on many 3-door hatchbacks and their 5-door counterparts are frequently very different. In the 5-door variant, the function of the door is to give a single person access to a single seat that is directly adjacent to it, with the additional requirement that the two doors on each side of the vehicle fit into the space allotted to them. However, in the 3-door variants, the door has the additional purpose of allowing entry to the rear seat when the front seat has been tipped forward to give access. The absence of the rear door mean that the front doors can be longer, easing the access to the rear seat, but this has the deleterious effect that the front doors on the 3-door version will no longer fit the space allocated for them on the 5-door variety.

So, re-using large sub-assemblies on the diametrically opposed corners of the vehicle is rarely done in production vehicles, but the problems do not stop there. Even with smaller sub-assemblies, there are unique aspects and requirements for the function of the parts. Another example are the stub-axle/ suspension assemblies. Whilst the both support a wheel, front wheels have to steer, whilst rear wheels don't. One set of wheels (generally) has to accept drive shafts from the universal gear assembly, the other does not. The suspension set ups for the set of wheels at the "engine end" of the car have to cope with a different set of loads and strains to that at the other end. Whilst it is perfectly feasible to design a common assembly that is configurable to meet both sets of requirements, and this can be cheaper than designing to separate assemblies, the compromises involved in this can lead to weaknesses in the "fitness for purposes" of the assembly for either.

These can include, additional weight, additional complexity, more difficult assembly, maintenance and configuration. It can, if done badly, result in strength and effectiveness of the units in there final configurations, where the range of possible configurations has had to be limited resulting in less optimal performance under minimal loadings at the light-end, and under maximum loads at the heavy end. For your average, run-of-the-mill family saloon, these compromises may rarely show up in normal use, but the will always be occasions where the use exceeds the normal range and the compromise will result in the restricted boundaries being exceeded.

The relevance to software re-use

Hopefully, the analogy from the above will be fairly clear. Component re-use is a desirable and cost effective goal for software development, but like most things in life, moderation is warranted. It must be recognised that designing code for re-use incurs costs as well as benefits. To be re-usable, code must be designed not just with the current, pressing application in mind, but also with a view to the future uses to which it might be put. This means that the design and implementation are harder, require more time and effort, and will probably incur the penalties of extra weight and possible, reduced range.

As a component becomes used in more applications, the difficulties involved in maintaining, supporting and upgrading that component multiply with each new end use. Modifying a module to correct a bug or enhance a feature when there are two or three users is hard enough. Once you reach the point of 5 - 10, this begins to be become impossible. Testing takes longer, getting agreements takes longer, reconciling the different needs for change by one user with the needs of stability from another get harder and harder.

Re-using small routines with clearly defined functions, like the nuts and bolts on a car, is useful, productive and cost effective, but as the routine size and complexity increases, so do the problems.

Coming at the problem from the other end, deciding whether to re-use an existing component in a new design requires considerable thought and planning. Often the choices available are multiple, and the requirements, limits and costs that each choice imposes upon your new design will vary, sometimes widely. The bigger the sub-assemblies are, the larger the constraints will likely be, and the harder it becomes to get a 'good fit' between them (the subassemblies themselves) and the overall application into which you are assembling them. Nuts from one manufacturer will generally fit well with a bolt (of the appropriate size) from another, but persuading a door from a hatchback to fit a sports roadster will be considerably harder and is apt to compromise the basic design criteria for the latter.

Re-use comes with a price tag, and not all applications are either conducive to those costs, nor functionally, aesthetically or performance-wise able to bear them.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
Hooray!

Replies are listed 'Best First'.
Re: Re-use: moderation please.
by dragonchild (Archbishop) on Oct 13, 2003 at 14:29 UTC
    Component re-use, like many other catch-phrases, has been mis-used. It is very useful to have a Person class that contains a number of useful defaults to describe a person. For example, all people have a weight, a height, a hair color (with a useful value for bald and balding), an eye color, etc. However, trying to make a Person class also handle all the possibilities for Employee, Athelete, Student, Teacher, etc ... that's where component re-use gets into trouble.

    Make each component do one thing and do one thing well. Having a door that fits both a sportster and a SUV ... well ... that door isn't doing one thing - it's doing two. Now, having a door handle that goes on both doors ... maybe that makes sense. Or, using the same seat leather. Whatever.

    The point is that component re-use is a "Good Thing"(tm). Now, identifying what components are re-useable ... that's a "Hard Thing"(tm). It's also why they pay us the "big" bucks.

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Re-use: moderation please.
by liz (Monsignor) on Oct 13, 2003 at 14:38 UTC
    I think the analogy is not very accurate for two reasons:

    1. With programs, we're only interested in the "design" part of the process. What takes us less time to design a new program, is time won. We're not interested in the building of the car (compiling the program), whereas in the car business, this is one of the most important components.
    2. In most cases, we're only interested in whether the car will bring us from A to B (run as expected). We're generally not (as much) interested in how fast it does it, let alone how the car looks. For all we want, it could be a crate with four wheels, if it runs, it runs.

    So I think re-use needs to be thought of with every component you build in mind. It needs to become a second nature. And your programming language must allow you to do that: Perl 4 didn't have true local variables, so building components was a pain then, to say the least. In general I have found, that my investment in the extra time to make components, rather than finished products, has always paid off for me.

    I agree with you with regards to testing: you need a test-suite to be able to proof that new features work as expected. More importantly, you need to be able to verify that old features still work as before.

    Finally, in software it is a lot easier to get different components to fit. Whether this looks nice or not, is basically immaterial. You just need the right glue. And Perl is just that!

    Liz

      With programs, we're only interested in the "design" part of the process. What takes us less time to design a new program, is time won. We're not interested in the building of the car (compiling the program), whereas in the car business, this is one of the most important components.

      Reducing design time isn't necessarely always "good". Designing a program by doing lots of "we just cut-and-paste this and that, and fiddle a bit with the innards", gives you quick design times, but not necessarely good programs. Not considering security issues or resource usage reduces design times, but isn't good either. Neither is looking at the literature. Reducing design times can be a good thing, but not at all costs. Just like code reduce can be good, but not at all costs either.

      In most cases, we're only interested in whether the car will bring us from A to B (run as expected). We're generally not (as much) interested in how fast it does it, let alone how the car looks. For all we want, it could be a crate with four wheels, if it runs, it runs.
      We are not interested in how fast our code is? I think that performance times of programs are very important, not only for the programmer, also for the (end)user. Just look at all the threads here and other programmer forums that discuss how fast a piece of code is (or isn't).

      So I think re-use needs to be thought of with every component you build in mind.

      I don't. I find that if I do that, code tends to be overly complex, having too many hooks and parameters than necessary. I prefer code to be simple - if the need arises I can always change it for code to be reusable (which if the code is simple and modular, not to hard). For code that is be reused later on, this might be less efficient then if it was made with reuse in mind. But in my experience, that's largely compensated by not spending time making code that turns out not be reused, reusable.

      I agree with you with regards to testing: you need a test-suite to be able to proof that new features work as expected. More importantly, you need to be able to verify that old features still work as before.
      This sounds simple, but this is very, very hard. Just look at perl itself. Even with a gazillion tests run, Perl manages to unintentionally break old code for each new release.

      Just look at 5.8.1. It introduced randomized hash seeds. It reused the code that generates random numbers. Oops! Now the random number generator is seeded before the program starts running, causing forking programs to generate the same random numbers in both the parent and the child.

      Finally, in software it is a lot easier to get different components to fit. Whether this looks nice or not, is basically immaterial. You just need the right glue. And Perl is just that!
      Yeah, right. Post some code here that does "$test = `cat file`" or "system 'cp file1 file2'" and watch the people howl that it's not a "solution in Perl". For many people, appearance is important, and they don't want to see glue if it can be avoided.

      Abigail

        Reducing design times can be a good thing, but not at all costs.

        I agree. But the "not at all costs" goes for a lot of things ;-) So it was implied, at least in my mind.

        We are not interested in how fast our code is?

        Who is the "we" here? Perl Mon(k|ger)s? That's not really your average Perl programmer, is it? In my experience, people only start to worry about efficiency when they have to wait for it when they feel they shouldn't have to wait for it.

        ..if the need arises I can always change it for code to be reusable (which if the code is simple and modular, not to hard)...

        To me, that means you already have taken re-usability into account. Because you make your code modular. Many, many (bad) Perl programmers do not even do that. The simple fact that you use named parameters to subroutines, might be considered catering for re-usability in my book.

        This (needing a test-suite, ed) sounds simple, but this is very, very hard.

        Yes, but is that a reason not to build test-suites? Without the extensive test-suite that Perl has nowadays, many, many other bugs were caught before 5.8.1 was released. That the fork/srand bug wasn't spotted, was simply because no one had bothered to write a test for it in earlier versions of Perl. Even though specific code was made in earlier versions of Perl to ensure children would get different random sequences. Fortunately, tests are added to test new aspects of Perl whenever they are added to Perl nowadays (generally speaking), but one needs to remain vigilant in that aspect ;-).

        ... watch the people howl that it's not a "solution in Perl"

        I generally don't watch those people. ;-) And whether people howl in the Monastery over a piece of code, is not an indication by itself of good or bad code. "Think for yourself!" ;-)

        Liz

Styrofoam and porcelain
by delirium (Chaplain) on Oct 13, 2003 at 16:54 UTC
    This isn't necessarily what BrowserUK was talking about, but this thread reminds me of an old design argument of mine: Styrofoam and porcelain.

    Porcelain solutions are beautiful and elegant. They take a long time to make and are decorative. They are heavy. When you pour hot coffee in them and pick them up, you burn your hand. When you drop them, they break.

    Styrofoam solutions are simple. They can be cranked out by the barrelful. They are lightweight and cheap. They insulate better than porcelain, and don't break when you drop them. If you crumble one up and throw it away, and then need another one, no worries. Just grab another.

    So the question is: Is code re-use more like porcelain, or more like styrofoam? A CPAN module is like styrofoam. Easy to grab and install. Free. There are many alternative approaches to common problems on file, all ready to use.

    Proprietary code? Code your company pays you to make? I guess it would depend on the company and the author. You can go out of your way to make something elegant and beautiful, and not be aware of how fragile or insecure it is.

    Go CPAN. Go open source. Go styrofoam.

Re: Re-use: moderation please.
by johndageek (Hermit) on Oct 13, 2003 at 18:03 UTC
    Once again, we are stuck with an argument mired in reality. If complete standardization were implemented in all things, this discussion would not be necessary because we would all agree, unless of course we all disagreed in an agreed aupon standard manner.

    What is involved here is a sense of degree. Turning to the analagy thingie again: If I am makeing a salad for my wife and I, I will shred a carrot by hand, If the salad is for five to twenty people, I will get out the food processor (more standardization and expense), if the salad is to be bagged and sold in stores, I will invest in industrial shredding equipment for large scale operations(still more standardization and more expense). Even though I now own a successful salad bagging corporation, and have a food processor in my cupboard, when my wife and I want a salad, I will still shred the carrot by hand.

    Shall we compare this to programming? (even if you don't, I will). If my assigned task is to print Fred Johnson's name, my code may consist of:

    print "Fred Johnson\n";

    I might even skip strict and warnings (gasp).

    If my assigned task is to print any name that can be entered I will use an input routine, a print routine, as well as an edit routine for the user entry (yes yes, strict and warnings at this level - sigh of releif)

    If my task is to print the names of all people from an industrial mailing list, I will use the above type of code, but with more standardized options: editing options, error flagging, formatting, extended hooks into each routine and a lot of other standardized techniques.

    Why the three(actually more) levels of coding?
    Analysis of: requirements, likelyhood of change, and potential longevity of code use. The first example may be a one shot class assignment. This poses very little chance for reuse or modification. The second example might be to echo back the name entered as a part of a kiosk program. Potential change is small or specialized (oops we don't want naughty words to be displayed back - relatively basic addition - no let's not discuss all the potential pitfalls of this statement). The third example has good potential for the requirements to expand, there will be some changes to input or outtput format, and the code may be used in a production environment for a long period of time.

    Each and every program has it's own set of constraints - budget, time, paranoia, basic user expectation and so on. All levels of programming can benefit from standardization, but how much of the cost is recoverable from the usefullness of the project.

    Looking at it another way, if a game crashes under certain circumstances, I as a user will be a lot more understanding than if my life support system crashes. Why? Becuase if I lose 2 levels in a game it is irritating, if life support crashes, you are messing with my addiction to oxygen.

    Still another way:
    Look at the door to your house, what kind of lock do you have? (usual answer - lock in the door knob and for extra security there is a deadbolt).
    Why not have a retina scanning voice print recognition system with time locks and alarm system (oh and by the way, those glass covered holes in the walls must go), This is MUCH more secure and standardized.

    On an on we could go - but as in all things balance must be reached between needs, cost and ability to provide a solution.

    Thank you for bringing up a fun point for discussion!
    da geek

Re: Re-use: moderation please.
by coreolyn (Parson) on Oct 13, 2003 at 15:37 UTC

    Re-use comes with a price tag, and not all applications are either conducive to those costs, nor functionally, aesthetically or performance-wise able to bear them.

    One price not brought up in the analogy is in the maintanance and distribution of the library of re-usable code itself. In a large organization this requires a department all by itself.

Re: Re-use - freedom and creativity
by pg (Canon) on Oct 13, 2003 at 17:30 UTC

    This is one of the topics that are not black and white.

    When it is clear to everyone, that you only reuse code that is relevant, different persons would have a different idea as how relevant is relevant, even for the same person on different days would judge differently. There are lots of things in this world, we would wish that we can measure them by numbers, but unfortunately not.

    Unfortunately? Did I mean what I just said? No, I meant the opposite. We are lucky that God had allowed us space and freedom to think individually, and work in a creative way with a personal stamp on it.

Re: Re-use: moderation please.
by Nkuvu (Priest) on Oct 13, 2003 at 17:56 UTC
    I'm sorry, I couldn't get past this bit:

    The vehicle was a four door saloon.

    Saloon? As in a "place where alcoholic drinks are sold and drunk; a tavern"? No wonder the car got so many awards. :)

      Damn! I thought I had "translated" all the non-americanisms -- bumper, hood trunk et al. It never even crossed my mind that the term "saloon car" wouldn't be reocognised over there, but doing a google shows that the term turns up frequently on UK, NZ, AU, Singaporean, HonkKong(ese?), Indian web sites, and even Canadian, but very rarely (if at all) on US sites.

      I apologise. I think the nearest equivalent would be a Sedan? Basically, a conventional, four doors, 5 seats, engine up front and separate lugguage compartment (boot/trunk) in the rear.

      {sigh} So much for common languages:)


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      Hooray!

        Gee, I just made an educated guess as to what you meant even though I'd never heard of a "saloon" car. Guess that's the newspaper editor/English major in me :-)


        "Ex libris un peut de tout"

        When I read "saloon car", I was thinking of a car with "suicide doors" like the old 1960's Lincoln Continental. For anyone who doesn't know, they had 4 doors... The front two opened like you would expect with the hinge in the front of the car. The rear doors were backwards, and had the hinge to the back of the car.

        The way those cars were built, if you got into a collision, the doors get stuck shut. That is a Bad Thing(tm).

        Anyway, that was the first thing that popped into my mind. Probably because I could easily picture the front driver side door and the rear passenger side door as being the same part.

        Oknow
Re: Re-use: moderation please.
by Anonymous Monk on Oct 13, 2003 at 14:54 UTC
    Who let the analogy out? I'm sorry, but that analogy is way too long and detailed to keep my attention and convey the point (you should consider cutting it in half two times).

    PS - I do not have ADD.

      Sorry! But the real world is complex and so are the issues in software development. The 'analogy' in this case is a piece of real-world history. You may question its applicability to the world of software (as liz has), but you cannot deny it's reality.

      Simple analogies are fine for simple points, but this isn't a simple point. The purpose was not to justify that component re-use was either good or bad. It was to illustrate that it's utility varies with complexity. That, IMO, required enough detail to illustrate the transition points from useful to deleterious.

      Would you suggest that Knuth's 3 volumes should have been done in 3/4 of a volume? :)


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      Hooray!

      On the other hand, I find this analogy to be right to the point. Apart from that, it is a well written piece history that is not known by some of us. I'll go now and read more about it somewhere. :)