Forums

Forums (http://www.abandonia.com/vbullet/index.php)
-   Programming (http://www.abandonia.com/vbullet/forumdisplay.php?f=25)
-   -   Object-Oriented alternative to switch statements? (http://www.abandonia.com/vbullet/showthread.php?t=27855)

The Fifth Horseman 15-09-2011 04:44 PM

Object-Oriented alternative to switch statements?
 
Not long ago, an application I sent in hope of getting an internship as a programmer has been rejected. Among the issues they listed with the program I made for their test assignment was "Use of switch statements instead of an object-oriented approach".
This doesn't make any sense to me - either I'm missing something which should be obvious, or I really don't know what that is supposed to be. Can someone enlighten me?

KrazeeXXL 16-09-2011 02:57 PM

Quote:

Originally Posted by wikipedia
In computer programming, a switch, case, select or inspect statement is a type of selection control mechanism that exists in most imperative programming languages such as Pascal, Ada, C/C++, C#, Java, and so on. It is also included in several other types of languages. Its purpose is to allow the value of a variable or expression to control the flow of program execution via a multiway branch (or "goto", one of several labels). The main reasons for using a switch include improving clarity, by reducing otherwise repetitive coding, and (if the heuristics permit) also offering the potential for faster execution through easier compiler optimization in many cases.

I know some very good programmers and had some courses myself in all kinds of different languages. And from what I heard, "GOTO" and stuff like this is frowned upon in their little "world". For them it's probably the worst thing you could ever do to a program. I guess it's some programmers quirk. They say this isn't classy programming. So, if you write programs this way, you won't belong to their elitist club and they will hate on you.

This might sound a bit harsh, but I'm not kidding. It's definitely the truth.


Programmers like all kinds of loops, pointers and stuff like this. So you might focus a bit more on those things.

I hope this helped.

Japo 16-09-2011 05:33 PM

We can hardly venture anything if we don't see the particular code (the relevant fragment). All object-oriented languages have of course flow control statements, and couldn't do without them, including switch in particular, the ones I can think of right off the bat. I've never heard their usage be controversial (like goto, which I don't think is controversial any longer), they're actually absolutely necessary.

My first guess would be that in that particular case, there was something already in place that would have been more appropriate than your code. That's why I don't think anyone can judge this without seeing the code.

If what you wanted is only to get a value of another type, depending on the value of the switch variable (as opposed to performing other side-effect actions depending), you may want to set up a hash table (example). But that's only better than a switch statement if it can be set up once and used many times, or if the code is cleaner. At any rate hash tables aren't even particular to object-oriented languages or paradigms.

More in general, one of the characteristics of the object-oriented paradigm is data hiding and separation between interface and implementation, thus reducing the impact and cost of implementation changes. But again I can't venture further without seeing the code.

The Fifth Horseman 16-09-2011 05:46 PM

1 Attachment(s)
Quote:

I hope this helped.
Unfortunately, that doesn't help any.

I know what a switch statement is. I had very specific reasons for using them where I did so. What I'm not getting is what the heck was I supposed to use instead of them in the situation I'm talking about, because apparently there is some alternative I'm not aware of which the company I applied at would prefer me to use instead.

While I do agree that Goto is a bad idea anywhere outside assembly programming, it's not the same thing as Switch. Using Goto, you basically kick the flow of logic out of the window and do whatever the hell you want.
Switch is functionally the same as a series of if/else if conditional statements comparing one variable to a set of pre-defined possible values and executing specific chunks of code depending on which one it is. Using Switch makes the resulting code slightly clearer and helps avoid errors which may occur when using a long series of if/else if statements (and then good luck hunting down which of half a dozen or more conditions you made a typo in).
In the case we're talking about, I used switch statements exactly to branch the logic in scenarios such as handling hotkeys - one common input, number of different - usually short - branches depending entirely on what that input is.
Quote:

We can hardly venture anything if we don't see the particular code (the relevant fragment).
Sure. The entire thing is in attachment. It was coded on a 72-hour deadline starting when the specs arrived in my e-mail inbox (which I discovered 3 hours later).

jonh_sabugs 16-09-2011 09:04 PM

From my experience, using GOTO's outside of assembly is a deadful approach. It has nothing to do with elitism, it's part of software engineering/quality theory, whereas reading and otherwise analysing execution flow becomes really painful in a goto-filled mess. All in all, I learned to never ever use it in my own codes.

About the object-oriented 'approaches' versus switch statements things, I think what they probably meant was using some kind of inheritance for key handling. After reading the code, I find this rather unfair really, since keyboard handling would be annoying to implement in such fashion.

I am no expert in C#, I usually implement in C/C++ and Java, but usually an alternative to switch is have the many elements as specific objects, extending some super class, so you only need to call the appropriate (overloaded) method in each one. However you get these object from the API in this case, and I can't see how you could effectively implement this. Another more object-oriented alternative is to build a class, backed by a hashtable or something, which would provide you dynamically (and quicker) the methods (or objects) for each possible key.

Well, I am thinking this on-the-fly here, so it's just some ideas of what they could be expecting. Maybe the idea was to evaluate your grasp on inheritance, or they were simply being asses.

Hope this helps shed some light on the issue.

EDIT: Dunno If I sounded otherwise, but switch statements are perfectly acceptable in OO programming, under certain circunstances.

KrazeeXXL 16-09-2011 10:54 PM

Well, I think some lead programmer just didn't like the style on how you approached things.

When I build a new team, I usually look for ppl who complete it. So, when I find someone who codes in a way I like, I pick him ofc.

You can't do anything when someone doesn't like your code/style.

Quote:

Originally Posted by jonhsabugs
I am no expert in C#, I usually implement in C/C++ and Java, but usually an alternative to switch is have the many elements as specific objects, extending some super class, so you only need to call the appropriate (overloaded) method in each one. However you get these object from the API in this case, and I can't see how you could effectively implement this. Another more object-oriented alternative is to build a class, backed by a hashtable or something, which would provide you dynamically (and quicker) the methods (or objects) for each possible key.

I'd sign that.

Some well meant advice:
You have to show ppl that you're versatile with your programming skills. So it's not a plus to focus just in one single direction.

While you might've found a good solution (from the state of your own overall-programming-experience at this time), it can't hurt to look on other solutions for the same problem, too. You have to broaden your own horizon.

Some things might look good for you today but you might laugh (or whine) in a couple of years when you look back at them again. ;)

edit: effin' grammar (again and again)

Japo 17-09-2011 05:55 PM

I think Jon got the alternative right (polymorphism, as the Wikipedia suggests); but after looking at the code the switches that made me think immediately of a clear alternative were not the ones in MainWindow.MainWindow_KeyDown(), but in MainWindow.Draw().

You could have defined a class for each drawing tool, all of them implementing one single interface, which defined for example handlers for the Control.MouseDown and so events (intended for the PictureBox MainWindow.Canvas). Polymorphism enters: you would store the currently selected tool in a variable whose type be this interface, but depending on the selected tool, changing at run-time, it would actually reference objects of different classes (all of them implementing the same interface).

When the user changes the tool you only have to re-assign this variable. When the events happen, you don't need any switch; they call the handlers that are abstract methods of this interface variable, so the code that is actually run depends on the actual class of the object representing the currently selected tool, referenced by the variable.

Besides the switch in MainWindow.Draw() wasn't shallow, there was some code shared by "Pencil" and "Eraser", and some by the rest. You can do that with inheritance, instead of the tool classes implementing the event handling interface directly, making Pencil and Eraser inherit from one abstract class and the rest from another, both of which implement the all-inclusive tool interface.

If you should need some implementation or fields to be shared by all the tool classes, you can turn that interface into an abstract class. The only difference between an interface and an abstract class is that an interface can't have any implementation (all the members of an interface are implicitly abstract, without the need of the abstract keyword), but a class may implement any number of interfaces, whereas it may inherit one single class, abstract or not. Both interfaces and abstract classes may not be instantiated themselves, only their inheriting/implementing non abstract classes. An abstract class may have both abstract and non-abstract members, and the latter may be virtual or not.

Whether this would be advantageous over your solution, Horseman you're best to judge. But probably they preferred that only to make you show off what you know. Anyway it would be unfair and dogmatic, unless it was included in the requirements they sent you (for example, "try to show us your OO skills). (Being dogmatic about programming paradigms is so last decade...)
__________________

About goto, what I meant that the controversy is over, is not exactly that goto is considered anathema any longer, I think. As little as the goto statement is or should be used, actually languages designed very recently do include it (C#, D). BUT all of them of course forbid goto to a location outside of the current scope; that is, you can't use it for example to jump from the middle of one function to the middle of another--as if that would make any sense, even in the case any language bothered to implement such a crazy possibility, violating of the concepts of scope and call stack.

And that's the reason why goto was anathema a long time ago. It was when structured programming was invented, allowing you to pack your code in new things called functions, and to control flow with fors and whiles. Before then (assembly languages and other unstructured early "high-level" languages), programmers were used to have practically only goto available to control flow. Each program was a single continuous stream of "spaghetti code", with goto jumps hither and thither. And when one of these people already expert with these techniques learned new structured languages like C, or new more structured versions of existing languages like Fortran or Basic, they would tend to continue using the same techniques they already knew, until they learned better. And so teachers had to label goto with a big DON'T when talking to people used to have nothing else.

Of course you can make the equivalent of a for or while loop with goto, the same that you can make a for with a while, but you should not, because of readability, because the moment you see a for loop you're supposed to know how it behaves without the need to track everything inside beforehand.

But that's also why I think this debate is not current any longer. People learning to program nowadays aren't liable to make spaghetti, and they will probably use any other flow control statement before thinking of goto. I don't think there's any other reason why goto is bad, even though I can hardly think of a situation where it would be appropriate, specially since most languages have both while and do-while loops. But as I said, modern languages did choose to support it.

jonh_sabugs 17-09-2011 06:09 PM

Just a side note: it's always possible to replace a GOTO with more elegant code, so, you should always avoid it.

The Fifth Horseman 17-09-2011 06:32 PM

Thanks, guys. Should have realised that this was it. :)
Quote:

Some things might look good for you today but you might laugh (or whine) in a couple of years when you look back at them again.
Usually that happens for me a day or two later. "OH GOD, DID I REALLY... ?" :p Hindsight is always 20:20, even more so when you have time to actually think about what you did instead of using the most direct approach you can think of. :D

Japo 17-09-2011 07:10 PM

Mind you Horseman, I only thought of the polymorphism alternative because the answer to your application told me to. :P

Quote:

Originally Posted by jonh_sabugs (Post 434069)
Just a side note: it's always possible to replace a GOTO with more elegant code, so, you should always avoid it.

We should probably split the goto discussion. :D

One of my points is that nobody who learned to program after the 1970s is likely to use too many gotos, or any at all. To be honest, I never use goto in practice. And I really don't know a lot, but here's what I googled in a moment. I haven't read it whole, but there may be a consensus that goto is never necessary or desirable if a language provides full flow control, including for example true exception handling and breaking from loops and nested loops; when a language does not provide any given flow control device, gotos might actually be the best and most elegant and legible substitute.

http://en.wikipedia.org/wiki/Goto

http://david.tribble.com/text/goto.html

Quote:

Examples T-2 and N-1 demonstrate that Dijkstra's maxim can be achieved provided that the programming language provides a reasonable set of control structures that can serve in place of simple goto statements.

Examples E-1 and N-2 demonstrate the corollary to this, that if a programming language does not provide reasonably powerful flow control structures, there are programming problems that can be solved reasonably well only by resorting to the use of goto statements.

[...]

Dijkstra's belief that unstructured goto statements are detrimental to good programming is still true. A properly designed language should provide flow control constructs that are powerful enough to deal with almost any programming problem. By the same token, programmers who must use languages that do not provide sufficiently flexible flow control statements should exercise restraint when using unstructured alternatives. This is the Tao of goto: knowing when to use it for good and when not to use it for evil.
From Mr. Linux's mouth (concerning C):
http://kerneltrap.org/node/553

From Steve McConnell, the author of Code Complete:
http://www.stevemcconnell.com/ccgoto.htm

http://www.u.arizona.edu/~rubinson/c...d_Harmful.html

http://dx.doi.org/10.1145/356635.356640


The current time is 06:24 PM (GMT)

Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.