Comment On Virtually Unusable

Mike W. was fresh on a new project and looking through the code base, trying to get an understanding of the architecture and how the system does its things. I believe that "disappointment" was his official reaction upon discovering how the architects designed the system's framework. As it turns out, they were a bit uncomfortable using abstract classes; maybe some one, some day will want to create an instance of the class. And they flat out didn't like interfaces; I mean, really, who uses those things anyway? Instead, they created based classes comprised entirely of "unusable" virtual methods ... [expand full text]
« PrevPage 1Next »

Re: Virtually Unusable

2005-06-15 14:28 • by loneprogrammer
Please modify this code to include a cover sheet on all TPS reports before they go out.  Didn't you get that memo?

Re: Virtually Unusable

2005-06-15 14:39 • by Lenny
Do the chickens have large talons?

Re: Virtually Unusable

2005-06-15 14:41 • by Alex
They should have left the method block empty, which would take care of those pesky runtime exceptions as well.



Look ma - no errors!

Re: Virtually Unusable

2005-06-15 14:46 • by loneprogrammer
36399 in reply to 36396
Does virtual in C# mean the same as it does in C++?

I am pretty sure that virtual does not mean "not real."

Re: Virtually Unusable

2005-06-15 14:48 • by diaphanein
36400 in reply to 36398

I'll admit to having done similar things in ASP.Net.  This is primarily a workaround a limitation in the designer.  Basically, if your page inherits from an abstract class, the designer cannot instantiate your page, and hence no design-time support.  So, I had to do this in that situation.  I didn't go with an interface because there were methods in the class that actually had usable methods.

Re: Virtually Unusable

2005-06-15 14:50 • by smalltalker
Looks like a smalltalk developer that hasn't quite learned the local
patois. As my father likes to say, "I can write fortran in any
language'.

Re: Virtually Unusable

2005-06-15 14:51 • by purplie
I've also done this when the base class contains some common code that subclasses are supposed to include using super().





Re: Virtually Unusable

2005-06-15 14:55 • by Jason

Handle the exception and at least you have a freshly initialized MemoryStream

Re: Virtually Unusable

2005-06-15 15:04 • by Lennox
36404 in reply to 36402

I work with the developer in question.  In the original code for this class, there are only 2 methods, neither of with do anything (well, virtually speaking of course).  Also, this class isn't a base class for anything that would be used in the designer.


The real kicker is the *** DO NOT USE!! (VIRTUAL METHOD) ***  comment.  And if for some reason you did decide to use the function, not only does it throw a special exception created just for calling virtual methods, but it also creates a new memory stream.... just in case you need it.  WTF?!?


Re: Virtually Unusable

2005-06-15 15:06 • by mizhi
36405 in reply to 36404
Anonymous:

The real kicker is the *** DO NOT USE!! (VIRTUAL METHOD) *** 
comment.  And if for some reason you did decide to use the
function, not only does it throw a special exception created just for
calling virtual methods, but it also creates a new memory stream....
just in case you need it.  WTF?!?






The new memory stream is there for you to barf into... yeah...

Re: Virtually Unusable

2005-06-15 15:08 • by Jacob
36406 in reply to 36400

For this situation, you can use Conditional Directives so that you can at least get some useful compile time info when compiling in release mode:


#If DEBUG Then


Public Class MyTempClass


#Else


Public MustInherit Class MyTempClass


#End If


 


End Class


 


Use the same constructs for your methods.

Re: Virtually Unusable

2005-06-15 15:12 • by tekiegreg
I was guilty of doing something like that once, at first I had an abstract class with several built in methods.  But after awile as my coding progressed,  I kept overriding everything in my child classes, one day I looked and said "I have nothing more than an interface now." and swapped out approriately.  It can happen as coding evolves.

Re: Virtually Unusable

2005-06-15 15:13 • by Marty
Hmm, never seen that 'out' parameter modifier before.   After
doing some research on it, what the heck is the difference between
'out' and 'ref'?

Re: Virtually Unusable

2005-06-15 15:24 • by phanto
36409 in reply to 36408
out is an output only parameter, the compiler complains if you read from such a variable before you set it inside the method.



ref is basically an in out parameter compareable with pass by reference in c++

Re: Virtually Unusable

2005-06-15 15:26 • by Special
36410 in reply to 36408

Anonymous:
Hmm, never seen that 'out' parameter modifier before.   After doing some research on it, what the heck is the difference between 'out' and 'ref'?


You can pass an uninitialized variable to an out param. Try it with a ref param and you'll get a compile time error

Re: Virtually Unusable

2005-06-15 15:36 • by tiro
36412 in reply to 36397
Anonymous:
Do the chickens have large talons?




Actually, in this case they are virtual chickens.  Virtually sacrificed. 

Re: Virtually Unusable

2005-06-15 16:09 • by strongarm
so you're not supposed to use this method, because it doesn't generate the cover sheet right?

WTF does PC Load Letter mean??

Re: Virtually Unusable

2005-06-15 19:04 • by rogthefrog
Alex Papadimoulis:

    string ai_sProjectNumber,
    out System.IO.MemoryStream ao_oTpsMemoryStream
    TpsReportGeneratorException v_oException = new TpsReportGeneratorException(
    ao_oTpsMemoryStream = new MemoryStream();



Those prefixes had better not mean what I think they mean.


ao_oTpsMemorySteam = Asinine Output Object?


v_oException = Virtual Object Exception?

Re: Virtually Unusable

2005-06-15 19:21 • by clockwise
I don't quite get this one. Should the method just be empty and have MustOverride keyword (or the C++ equiv) before the function definition?

Re: Virtually Unusable

2005-06-15 19:54 • by -L
36430 in reply to 36410
Anonymous:

Anonymous:
Hmm, never seen that
'out' parameter modifier before.   After doing some research
on it, what the heck is the difference between 'out' and 'ref'?


You can pass an uninitialized variable to an out param. Try it with a ref param and you'll get a compile time error



Right. I do not know C#, but what is the rationale for being able to
pass uninitialized variables to out parameter? That sounds like a major
WTF to me...



And speaking of that, why on earth have distinct "ref " and "in out" formal
parameters? Shouldn't this decision be left to the compiler, or be
stated in more explicit form (like passing a "pointer" instead of
"ref")?



This is just off the top of my head, I don't know C#, but these things just seem strange.

Re: Virtually Unusable

2005-06-15 20:25 • by djc
36432 in reply to 36430
Another WTF:




And speaking of that, why on earth have distinct "ref " and "in out" formal
parameters? Shouldn't this decision be left to the compiler, or be
stated in more explicit form (like passing a "pointer" instead of
"ref")?




A pointer is not more explicit than ref, out, etc. When you use a
pointer no one knows if the var is in, out, or in out. They just have
to guess!



Re: Virtually Unusable

2005-06-15 23:03 • by Matt
36436 in reply to 36400
Anonymous:

I'll admit to having done similar things in
ASP.Net.  This is primarily a workaround a limitation in the
designer.  Basically, if your page inherits from an abstract
class, the designer cannot instantiate your page, and hence no
design-time support.  So, I had to do this in that
situation.  I didn't go with an interface because there were
methods in the class that actually had usable methods.





I had to do the same thing.  :(

Re: Virtually Unusable

2005-06-15 23:19 • by David
I'm sorry but I have to play dumb and say, first of all, WTF language is this in???

Re: Virtually Unusable

2005-06-16 03:04 • by Ponto
I've done something similar, and I still do not know how to do it better. I have a tree which consists of nodes of several types. Class Node is the baseclass of all node types and is responsible for the tree structure (parent, first_child, next_sibling pointers). Other nodetypes have different sets of methods.


When I traverse the tree the logic of the application gives me knowledge of the node types without asking the objects themselves. Using this information I want to call methods of the derived type without using evil casts.


The solution was to create virtual methods for nearly each needed method in the Node class and let them throw an exception when they are called. Making them abstract is not a solution because then they have to be implemented in each derived class.


However, if anyone knows a better solution, let me know.

Re: Virtually Unusable

2005-06-16 03:18 • by Welcome To The Machine
Looks like this guy didn't get the memo on the new cover sheet for TPS reports. Can someone forward him a copy? [8-|]

Re: Virtually Unusable

2005-06-16 03:21 • by Frederik
36442 in reply to 36430

Anonymous:

Right. I do not know C#, but what is the rationale for being able to pass uninitialized variables to out parameter? That sounds like a major WTF to me...

And speaking of that, why on earth have distinct "ref " and "in out" formal parameters? Shouldn't this decision be left to the compiler, or be stated in more explicit form (like passing a "pointer" instead of "ref")?


Consider this:


string fullName = "Bill Gates";
string firstName;
string lastName;
ParseName(fullName, out firstName, out lastName);


There is no reason for you to initialize firstName and lastName. If you don't pass the parameter as an out parameter, C# will complain. The method is supposed to initialize the parameters.


As opposed to:


int string x = "First";
int string y = "Second";
SwitchValues(ref x, ref y);


where you clearly want initialized variables before the method is being called.


Hope it helps

Re: Virtually Unusable

2005-06-16 03:40 • by -L
36443 in reply to 36442
Anonymous:

Anonymous:

Right. I do not
know C#, but what is the rationale for being able to pass uninitialized
variables to out parameter? That sounds like a major WTF to me...

There
is no reason for you to initialize firstName and lastName. If you don't
pass the parameter as an out parameter, C# will complain. The method is supposed to initialize the parameters.

(snip)

Hope it helps





Ah, my bad. For some reason I had my thinking reversed, thinking that
the method could pass uninitialized parameter values through out
parameter, which is not what the original author said at all.



The out behaviour Frederik describes is perfectly sensible.

Re: Virtually Unusable

2005-06-16 06:46 • by R. Stiller
36447 in reply to 36399
loneprogrammer:
Does virtual in C# mean the same as it does in C++?

I am pretty sure that virtual does not mean "not real."
Virtual
means i C# that the member function can be overridden. C++ virtuals in
C# are abstract member functions. To override a method in C# you must
mark your method as "override".

Re: Virtually Unusable

2005-06-16 07:07 • by Simon Farnsworth
36448 in reply to 36440
Anonymous:
I've done something similar, and I still do not
know how to do it better. I have a tree which consists of nodes of
several types. Class Node is the baseclass of all node types and is
responsible for the tree structure (parent, first_child, next_sibling
pointers). Other nodetypes have different sets of methods.

When I traverse the tree the logic of the application gives me
knowledge of the node types without asking the objects themselves.
Using this information I want to call methods of the derived type
without using evil casts.

The solution was to create virtual methods for nearly each needed
method in the Node class and let them throw an exception when they are
called. Making them abstract is not a solution because then they have
to be implemented in each derived class.


However, if anyone knows a better solution, let me know.




Making them abstract is exactly the solution you should be using. Ask yourself this: why is throwing an exception in buggy code better than refusing to compile it?

Alternatively, look at the Visitor Design Pattern for ideas on how to get the behaviour you want.

Re: Virtually Unusable

2005-06-16 08:39 • by John Smallberries
36453 in reply to 36436
Anonymous:
Anonymous:

I'll admit to having done similar things in
ASP.Net.  This is primarily a workaround a limitation in the
designer.  Basically, if your page inherits from an abstract
class, the designer cannot instantiate your page, and hence no
design-time support.  So, I had to do this in that
situation.  I didn't go with an interface because there were
methods in the class that actually had usable methods.






I had to do the same thing.  :(


Conditional compilation is your friend.



In C# you can use:



    // the webform designer needs to instantiate the page base classes, and doesn't work

    // when the base class is abstract. use a concrete class for dev, but switch to abstract for release.

#if DEBUG

    public class PageBase

#else

    public abstract class
PageBase

#endif

{/* class definition */}



I believe someone posted the VB equivalent further up.


Re: Virtually Unusable

2005-06-16 09:19 • by antareus
All that typing to make a runtime version of the abstract keyword (or
interfaces). What a pity. At least it creates a new MemoryStream for
you though. I like the implications of the "DO NOT USE!! (VIRTUAL
METHOD)" comment. That is, thankfully, the classes that derive from
BaseTpsReportGenerator and implement GenerateTpsReport aren't *really*
virtual, so they're okay to call. :)



The guy is using reflection though (GetType()), so it looks like someone who knows enough to really make a mess of things.

Re: Virtually Unusable

2005-06-16 09:48 • by foo
36461 in reply to 36448
>why is throwing an exception in buggy code better than refusing to compile it?



better ?



refusing to compile it means you can't go on to other things and let this sleeping



the exception sits there as a reminder for the poor developper when his apps go through it

Re: Virtually Unusable

2005-06-16 09:52 • by Ponto
36462 in reply to 36448
Anonymous:

...


Making them abstract is exactly the solution you should be using. Ask yourself this: why is throwing an exception in buggy code better than refusing to compile it?

Alternatively, look at the Visitor Design Pattern for ideas on how to get the behaviour you want.


If I make the methods abstract in the Node class and if I implement all this methods in all derived classes (which is unnecessary for most of them), then I will not get more compiler errors than I get now.

The compiler does not forbid calling abstract functions.

The compiler forces me to implement method in derived classes which are meaningless for most of them. The only thing such meaningless methods can do is throwing an exception. The same thing which is now done centralized at the base class. I do not see why the code is buggy?

Re: Virtually Unusable

2005-06-16 09:55 • by Hank Miller
36463 in reply to 36440
Anonymous:
I've done something similar, and I still do not
know how to do it better. I have a tree which consists of nodes of
several types. Class Node is the baseclass of all node types and is
responsible for the tree structure (parent, first_child, next_sibling
pointers). Other nodetypes have different sets of methods.

When I traverse the tree the logic of the application gives me
knowledge of the node types without asking the objects themselves.
Using this information I want to call methods of the derived type
without using evil casts.

The solution was to create virtual methods for nearly each needed
method in the Node class and let them throw an exception when they are
called. Making them abstract is not a solution because then they have
to be implemented in each derived class.


However, if anyone knows a better solution, let me know.




in C++ there is dynamic_cast and static_cast for these situations.





Though someone else already mentioned the visitor pattern, which looks
like an even better solution.  (I had not encountered them before,
and thus forgot about them from my GoF book)



Which to use I suppose depends on how often you need it.  If you
are only encounter this situation a couple times it might not be worth
all the code to create visitors, while if you have many situations
where you want to do something to something else that the base class
shouldn't support you use a visitor.

Re: Virtually Unusable

2005-06-16 10:07 • by Carl
This is pretty funny.  I really like the design time warning: " DO
NOT USE!! (VIRTUAL
METHOD) " and the run-time warning: an exception being thrown. 
Unfortunately it doesn't throw a compile time warning.  Chances
are,
whoever has to work with this piece of crap will go diving down through
the code and find this method and see that it's not supposed to be
used.  Why throw an exception as well?  Like there's some guy
out there
who can't figure out why his call to this method isn't doing
anything.  The other design nugget that's interesting is that this
person can't just throw an exception and be done with it, they designed
their method with an out parameter that requires it to be initialized
in the method.  So instead of just being able to throw an
exception they had to initialize the variable in order to get it to
compile.  Oops.  Probably should've spent more time at the
drawing board and less time at the keyboard.

Re: Virtually Unusable

2005-06-16 10:15 • by Ponto
36465 in reply to 36463
Anonymous:




in C++ there is dynamic_cast and static_cast for these situations.





Though someone else already mentioned the visitor pattern, which looks
like an even better solution.  (I had not encountered them before,
and thus forgot about them from my GoF book)



Which to use I suppose depends on how often you need it.  If you
are only encounter this situation a couple times it might not be worth
all the code to create visitors, while if you have many situations
where you want to do something to something else that the base class
shouldn't support you use a visitor.


As I already said, I do not want to use casts. With casts the solution is really simple. Using the visitor pattern it might work, but there is a lot of overhead - especially in code. Additionally the visitor pattern is more appropriate for extra functionality of the elements and not for the first class functionality.

Right now I think that when you do not want to use casts and want each subclass only implement a subset of all methods throwing an exception when it is called for the base class is the best way.

Re: Virtually Unusable

2005-06-16 10:45 • by Simon Farnsworth
36466 in reply to 36465
Why don't you want to use casts? dynamic_cast<> will get you the
same behaviour you've got already, as it throws an exception if the
cast is not possible, while if static_cast<> is possible, it'll
check at compile time that you're doing what you think you're doing.



I think your code qualifies as a potential WTF, simply because it's not
clear to a maintenance programmer that the method will sometimes work,
and sometimes not. A C++ programmer should be aware that
dynamic_cast<> can throw a bad_cast exception, and will thus see
what the code's up to; it's not so clear that calling a virtual
function can throw what's effectively a bad_cast exception. Further,
the overhead of RTTI shouldn't be significant compared to virtual
functions; it should be a simple tag comparison in a decent compiler.



Finally, I wasn't suggesting that you use the Visitor pattern as-is; I
was suggesting that you use the concepts of the visitor pattern to
create something without the base-class exception that still functions.

Re: Virtually Unusable

2005-06-16 12:06 • by cm5400

"DO NOT PRESS"  Whoops... "The Earth will self destruct in 30 seconds... 29... 28..."  WHY would you put do not use? and Then throw and error if it IS used?

Re: Virtually Unusable

2005-06-16 12:30 • by Mike R
36473 in reply to 36470
cm5400:

"DO NOT PRESS"  Whoops... "The Earth will
self destruct in 30 seconds... 29... 28..."  WHY would you put do
not use? and Then throw and error if it IS used?





As the user repeatedly and rapidly presses cancel: "Pressing cancel
won't change anything ... 27 ... The big red button was plainly labeled
... 26 ... and you pushed the button anyway. Enjoy your imminent ... 25
... destruction, bozo. "



I can imagine the exception gives some sort of error message "Develper,
you've called a method that you were instructed not to call. Don't do
that. It was plainly labeled, but you called it anyway."

Re: Virtually Unusable

2005-06-16 12:43 • by JohnO
36474 in reply to 36465

As I already said, I do not want to use casts.


You said that the tree structure already tells you what kind of node you have.  If that's true, then why is casting "evil?"  The two situations seem exactly the same to me in terms of how the program works except that in one case you are introducing a WTF and in the other you are using the language as intended and as 99% of competent developers would expect you to.


In your scenario, you are querying the node to determine what methods to call.  If you make a mistake, then you call the base class implementation and get a run-time exception.  In what I would consider the "standard" solution, you would query the node to determine what type to cast it to, cast it and invoke the method.  If you make a mistake you get a cast exception.  What's the benefit of what you are doing over the "standard" way?

Re: Virtually Unusable

2005-06-16 15:33 • by voyager
OMG, if you are gonna ignore all the OO features of Java why bother with Java at all!



If a student handed code like that up to me I'd fail them, imagine finding it in a real app!



BTW, it is not possible to reply to posts on this board using Camino on OS X. Made me go WTF! *mutters about the KISS principle*

Re: Virtually Unusable

2005-06-16 18:37 • by foxyshadis
36527 in reply to 36500
voyager:
BTW, it is not possible to reply to posts on this
board using Camino on OS X. Made me go WTF! *mutters about the KISS
principle*


It just wouldn't be thedailywtf without the wtf forum software. C'mon, admit it.

Re: Virtually Unusable

2005-06-17 03:02 • by enska
36536 in reply to 36432
Anonymous:
Another WTF:




A pointer is not more explicit than ref, out, etc. When you use a
pointer no one knows if the var is in, out, or in out. They just have
to guess!







const pointer.



btw, this forum's buggy. almost a WTF in itself.

Re: Virtually Unusable

2005-06-18 01:24 • by Marco
36601 in reply to 36462
Anonymous:


The compiler forces me to implement method in derived classes which are
meaningless for most of them. The only thing such meaningless methods
can do is throwing an exception. The same thing which is now done
centralized at the base class. I do not see why the code is
buggy?




If methods are meaningless for the derived classes, then you probably
didn't get your classes defined in the right way: move the "meaningless"
methods to the derived classes where they belong and you expect
actually to implement them.



If a method is "meaningful" for more than one subclass, consider
creating an intermediate base class that includes that method and from
which you derive.



Just my 2 cents.

Re: Virtually Unusable

2005-06-19 17:37 • by Ponto
36622 in reply to 36474
Anonymous:

As I already said, I do not want to use casts.


You said that the tree structure already tells you what kind of node you have.  If that's true, then why is casting "evil?"  The two situations seem exactly the same to me in terms of how the program works except that in one case you are introducing a WTF and in the other you are using the language as intended and as 99% of competent developers would expect you to.


In your scenario, you are querying the node to determine what methods to call.  If you make a mistake, then you call the base class implementation and get a run-time exception.  In what I would consider the "standard" solution, you would query the node to determine what type to cast it to, cast it and invoke the method.  If you make a mistake you get a cast exception.  What's the benefit of what you are doing over the "standard" way?



Maybe I am not doing the best thing in this situation, but there are experts who do similar things. For example Scott Meyers suggests in his "Effective C++ Third Edition" Item 27 (Minimize casting) that one solution to avoid dynamic_cast is moving such a function to the base class and leaving it empty.

The difference is, that I throw an exception when it is called for a base class. However maybe leaving it empty is the better approach.

For C++ a cast might be more WTF than such a construct.

Re: Virtually Unusable

2005-06-19 17:40 • by Ponto
36623 in reply to 36601
Anonymous:
Anonymous:


The compiler forces me to implement method in derived classes which are
meaningless for most of them. The only thing such meaningless methods
can do is throwing an exception. The same thing which is now done
centralized at the base class. I do not see why the code is
buggy?




If methods are meaningless for the derived classes, then you probably
didn't get your classes defined in the right way: move the "meaningless"
methods to the derived classes where they belong and you expect
actually to implement them.



If a method is "meaningful" for more than one subclass, consider
creating an intermediate base class that includes that method and from
which you derive.



Just my 2 cents.


Currently I do not have meaningless functions in the derived classes. However, when I make them abstract in the base class, I have to implement them in the derived classes.

Re: Virtually Unusable

2005-06-21 08:00 • by JohnO
36703 in reply to 36623

Responding a little late here -- hope you get to read this.  I am in the C pound world and can't remember the specifics of C increment, but in C#, you would just have an abstract class with virtual empty methods.  The subclass has the option of overriding but doesn't have to.  I am guessing that C++ doesn't have this?  If not, then if you take throwing the exception out of the base class implementation, then it does sound reasonable.

Re: Virtually Unusable

2005-06-23 20:00 • by bp
36951 in reply to 36396
loneprogrammer:
Please modify this code to include a cover
sheet on all TPS reports before they go out.  Didn't you get that
memo?




Hey man, I still have my stapler!

« PrevPage 1Next »

Add Comment