2015-04-30

On dogma in engineering

I once had a colleague who had a higher rank than me, and who was not only unconvinced by my rational and articulate arguments for doing a certain thing in a certain way, but he concluded the discussion by stating that --and I am not paraphrasing here, this is what he actually said-- the way he wanted it done was mentioned in a book, so unless I could find a book backing up my proposal, it was to be done his way.

I did not argue with him at that time, (how can you argue with that?), but I would now like to quickly jot down my thoughts on why saying such a thing is incredibly stupid:
  • Engineering books are there for you to learn things from them, not to be taken as truth by revelation.
  • An engineering book makes (or fails to make) a point by analyzing it in detail until it is self-evident that the point holds true, not by proclaiming the point and putting the name of the author underneath it.
  • The value of an engineering book lies in providing justification for the claims that it makes, not in making the claims available as ink impressed onto paper.
  • Therefore, engineering books are supposed to help you win arguments by equipping you with valid points to bring in defense of your positions, not by playing the books as trump cards.

For all I know, you may have read the whole book and misunderstood every single bit of it, or you may be completely wrong about the applicability of the points made in the book to the particular situation that you have at hand.

So, unless you can use what you have learned from a book to reason, any insistence on things written in a book on the grounds that they are written in a book is blatantly stupid dogma.

Of course, I understand that other concerns may be at play. For example, that particular guy, having been tasked with being a team leader in a team of relatively senior engineers while being only in his early thirties, and having knowledge of the fact that he is good at his job but not stellar, he was probably insecure about the possibility of large scale project failure, in which case (so he thought) he wanted to be able to save face by claiming that he had followed "best practices", and here are the books to prove it.  Oh, the cowardice.

Wow, 5 upvotes, 10 downvotes and counting

I have this answer on programmers.stackexchange.com which, at the time of writing these words, has 5 upvotes and 10 downvotes, and in all likelihood it will continue collecting downvotes, while I adamantly refuse to remove it, standing 100% by my ideas. I am dumbfounded, as such a thing has never happened before.

Here is the programmers.stackexchange.com question:

Is it okay to have objects that cast themselves, even if it pollutes the API of their subclasses?


I have a base class, Base. It has two subclasses, Sub1 and Sub2. Each subclass has some additional methods. For example, Sub1 has Sandwich makeASandwich(Ingredients... ingredients), and Sub2 has boolean contactAliens(Frequency onFrequency).

Since these methods take different parameters and do entirely different things, they're completely incompatible, and I can't just use polymorphism to solve this problem.

Base provides most of the functionality, and I have a large collection of Base objects. However, all Base objects are either a Sub1 or a Sub2, and sometimes I need to know which they are.

It seems like a bad idea to do the following:

for (Base base : bases) {
    if (base instanceof Sub1) {
        ((Sub1) base).makeASandwich(getRandomIngredients());
        // ... etc.
    } else { // must be Sub2
        ((Sub2) base).contactAliens(getFrequency());
        // ... etc.
    }
}

So I came up with a strategy to avoid this without casting. Base now has these methods:

boolean isSub1();
Sub1 asSub1();
Sub2 asSub2();

And of course, Sub1 implements these methods as

boolean isSub1() { return true; }
Sub1 asSub1();   { return this; }
Sub2 asSub2();   { throw new IllegalStateException(); }

And Sub2 implements them in the opposite way.

Unfortunately, now Sub1 and Sub2 have these methods in their own API. So I can do this, for example, on Sub1.

/** no need to use this if object is known to be Sub1 */
@Deprecated
boolean isSub1() { return true; }

/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub1 asSub1();   { return this; }

/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub2 asSub2();   { throw new IllegalStateException(); }

This way, if the object is known to be only a Base, these methods are un-deprecated, and can be used to "cast" itself to a different type so I can invoke the subclass's methods on it. This seems elegant to me in a way, but on the other hand, I'm kind of abusing Deprecated annotations as a way to "remove" methods from a class.

Since a Sub1 instance really is a Base, it does make sense to use inheritance rather than encapsulation. Is what I'm doing good? Is there a better way to solve this problem?

Tags: java, inheritance, type-casting
asked by codebreaker