Java Forum / General / May 2007
small java exercise
ros - 03 Apr 2007 10:48 GMT Hi,
I am working on this exercise and would be thankful if you folks comment on it.
The requirement was as follows:
Create a MovieRating class that contains a private map with rating as the key and minimum age as the value, populate this map when the class is instantiated. Also include a method which takes two parameters, rating and age and checks the minimum age in the map and returns true or false to indicate whether or not a human with the specified age is allowed to watch a movie with the specified rating.
My attempt is pasted below. I get a compiler error that says that I have a missing return statement in getStatus. The return statements that I have are in the if/else block. How can I solve this issue? Also I am not sure about the Map?
Thanks Ros
import java.util.HashMap; import java.util.Map;
public class MovieRating {
private Map humanMap = new HashMap();
public MovieRating(){ humanMap.put("G", 18); humanMap.put("PG", 16); }
public boolean getStatus(String rating, int age){
int minAge; minAge = Integer.getInteger((String) humanMap.get("PG"));
if (age < minAge ){ return false; } else if (age >= minAge){ return true; }
}
}
Ingo R. Homann - 03 Apr 2007 11:05 GMT Hi,
> public class MovieRating { > [quoted text clipped - 20 lines] > > } Several issues. In the first step I would do it like this:
public class MovieRating { private int g=18; // perhaps also 'static final'? private int pg=16;// perhaps also 'static final'? public boolean getStatus(int age) { return age>=pg; } }
In the second step - I suppose that's what you want to do - you can take into account the parameter 'rating'. After all, I think it could be better like this (it all depands on the rest of your architecture and your requirenments):
public class MovieRating { private int age; public MovieRating(int age) { this.age=age; } public boolean getStatus(int age) { return age>=this.age; } }
Ciao, Ingo
vishist - 03 Apr 2007 11:37 GMT > Hi, > [quoted text clipped - 45 lines] > > } Ros: You also may want to try this,
import java.util.HashMap; import java.util.Map;
public class MovieRating {
private Map humanMap = new HashMap(); public MovieRating(){ humanMap.put("G", new Integer(18)); humanMap.put("PG", new Integer(16)); }
public boolean getStatus(String rating, int age){
Integer ratingAge = (Integer)humanMap.get(rating); if(ratingAge != null) { int minAge = ratingAge.intValue(); if (age < minAge ){ return false; } else{ return true; } } return false; } }
The problem with your code is that you are trying to 1. add basic data types to map (Map takes only references to Objects) 2. the "if/else if" conditions has no "else" condition. For the compiler, it doesn't know whats the default return is going to be in case if/elseif fails 3. Also, you have hardcoded the rating in access function.
Once you got this working, I guess you may want to add additional condition checks for non-null method arguments.
V.
bcr666 - 03 Apr 2007 20:51 GMT > public boolean getStatus(String rating, int age){ > [quoted text clipped - 11 lines] > return false; > } I am a big believer in one exit point for a method, so I would do the following
public boolean getStatus(String rating, int age) { boolean value = false;
Integer ratingAge = (Integer)humanMap.get(rating); if(ratingAge != null) { int minAge = ratingAge.intValue(); value = (age >= minAge); }
return value; }
Patricia Shanahan - 03 Apr 2007 22:46 GMT >> public boolean getStatus(String rating, int age){ >> [quoted text clipped - 14 lines] > I am a big believer in one exit point for a method, so I would do the > following Why one exit point per method?
[I used to believe that, but most of the logical reasons I can articulate are covered by try-finally. I'm curious about whether there is a better reason I'm missing.]
Patricia
bcr666 - 16 May 2007 13:20 GMT > Why one exit point per method? > [quoted text clipped - 3 lines] > > Patricia Maybe it is my opinion, but It makes it easier to debug, and it is easier to change later on without breaking it or introducing errors.
Lew - 16 May 2007 14:00 GMT >> Why one exit point per method? >> [quoted text clipped - 6 lines] > Maybe it is my opinion, but It makes it easier to debug, and it is > easier to change later on without breaking it or introducing errors. I disagree. The single-exit anal retention makes it harder to debug, and harder to change later on, especially when it forces you into ridiculous levels of nesting and extraneous conditionals, not to mention the introduction of superfluous "retVal" variables. I'd stick with Patricia's insights; she's one of the god(desse)s of Java.
Seriously, Patricia - you provide some of the sharpest, most succinct, to-the-point and informative posts on the topic that there are.
Ignore her advice at your peril. (Not that she's infallible, but I have yet to find her in error in this forum.)
 Signature Lew
Patricia Shanahan - 16 May 2007 20:14 GMT >>> Why one exit point per method? >>> [quoted text clipped - 18 lines] > Ignore her advice at your peril. (Not that she's infallible, but I have > yet to find her in error in this forum.) BLUSH! And thanks. However, two points:
1. In this case, I am not so much giving advice as asking for insight. Are there advantages in Java to pushing for single exit that outweigh the cost of making the code more complicated, for example by requiring a "retVal"? If so, what are they?
I believe that there is a significant gain in ease of debug and change for languages without try-finally or equivalent. I am just not convinced for Java.
2. Even when I am giving advice, I really want anyone who is interested in the topic and not convinced by my arguments to question and challenge what I am saying. Maybe I'll get to learn something that way.
Patricia
Stefan Ram - 16 May 2007 22:34 GMT >In this case, I am not so much giving advice as asking for >insight. Are there advantages in Java to pushing for single >exit that outweigh the cost of making the code more >complicated, for example by requiring a "retVal"? If so, what >are they? The usual benefits of »structured programming«.
- With a single exit at the end, if I would want to add a call to be done once before the method exits, I would add it in front of this exit point. Otherwise, one would need to find all exit points and add this call in front of each one.
- A kind of »referential transparency« of blocks. By this (ignoring parameters and return values for simplicity), a methode declaration
m(){ ... { ... } ... }
can always be refactored to
m1(){ ... } // = the »{ ... }« block from above
m(){ ... m1(); ... }
Thus, a block can always be replaced by a call to this block after it has been given a name by a method declaration. This is not possible anymore, when this block contains an exit (»return«).
- Improved readability. In
{ ... { ... } f(); ... }
I know that »f();« will be executed whenever the whole block is executed if the block is written according to structured programming rules. I do not have to analyze the inner block to make this assertion. When jump-statements, like »return;« are allowed, one can not make such assertions with the same ease.
Once I have read that in certain C++ implementations multiple returns can speed up a function, which would be slowed down by an enforcement of the single-exit rule. This would be one of the cases, where I would refrain from enforcing a single exit: If code needs to be optimized for runtime speed. In general, I like and apply the single-exit rule.
Patricia Shanahan - 16 May 2007 23:18 GMT >> In this case, I am not so much giving advice as asking for >> insight. Are there advantages in Java to pushing for single [quoted text clipped - 9 lines] > to find all exit points and add this call in front of > each one. My question is specific to Java, so I could wrap the multi-exit code in a try-finally and do the call in the finally block. This used to be one of the most convincing arguments, but I'm not sure it still applies.
> - A kind of »referential transparency« of blocks. By this > (ignoring parameters and return values for simplicity), [quoted text clipped - 11 lines] > block after it has been given a name by a method > declaration. Not always, in Java, given the lack of call-by-reference:
m(){int x=0; int y = 0; ... { ... x = 5; y = 20; ... } ... }
cannot be refactored as above without changing the handling of x and y. Passing them as parameters does not get the changed values back to the surrounding block.
And one of the standard techniques for obtaining a single exit function involves using an extra outer block variable, modified at each logical exit point, to represent the return value.
> > This is not possible anymore, when this block contains [quoted text clipped - 13 lines] > like »return;« are allowed, one can not make such > assertions with the same ease. I'm not convinced the single exit rule does always aid readability. In some cases, for example, I think getting one or two special cases completely out of the way before starting the main work leads to more readable code. It makes it easier to be sure that nothing else in the method needs to handle the special cases, and that the special case decision will not be overridden later on.
This is especially the case for recursive methods.
int factorial(int n){ if(n < 0){ throw something; } if(n == 0){ return 1; } return n * factorial(n-1); }
int factorial(int n){ int fact; if(n < 0){ throw something; } if(n == 0){ fact = 1; }else{ fact = n * factorial(n-1); } return fact; }
I think the multi-exit version makes it easier to identify the base case and be sure its handling is non-recursive.
Note that I am not denying the existence of many methods for which the single exit version will be the most readable version, and should be used. I just feel that there are cases in which multiple exit is clearer than single exit, and that multiple exit should be used in those cases.
Possibly the difference is whether it is more important to be sure some code is always executed, or to be sure some code is not executed in particular cases.
Patricia
Stefan Ram - 17 May 2007 05:18 GMT >My question is specific to Java, so I could wrap the multi-exit >code in a try-finally and do the call in the finally block. By this finally-block you re-introduce a single exit point: This single exit point of the wrapped code now is the end of the finally block. So this wrapped code does not count as multi-exit code, it is single-exit code again.
>This is especially the case for recursive methods. >int factorial(int n){ [quoted text clipped - 9 lines] > return fact; >} Just for the records, I might write this as:
int factorial_( final int n ){ return n == 0 ? 1 : n * factorial_( n - 1 ); } int factorial( final int n ){ if( n < 0 )throw ...; return factorial_( n ); }
Patricia Shanahan - 17 May 2007 06:09 GMT >> My question is specific to Java, so I could wrap the multi-exit >> code in a try-finally and do the call in the finally block. [quoted text clipped - 3 lines] > the finally block. So this wrapped code does not count as > multi-exit code, it is single-exit code again. Looking at it that way, I would argue that try-finally makes the multi-exit to single-exit refactoring trivial.
Many of the familiar arguments for single-exit amount to preemptive avoidance of ever having to do that refactoring. Without try-finally, it really is something that should be avoided if possible.
Patricia
Lew - 16 May 2007 22:35 GMT Lew wrote:
>> Ignore her advice at your peril. (Not that she's infallible, but I >> have yet to find her in error in this forum.)
> BLUSH! And thanks. However, Note that when I suggest that one ignores your advice at peril, it doesn't mean that I endorse uncritically /following/ your advice. One should carefully consider anyone's input, particularly those known to be knowledgeable, but that confers no obligation to follow it afterward.
 Signature Lew
Martin Gregorie - 16 May 2007 22:52 GMT >>>> Why one exit point per method? >>>> [quoted text clipped - 25 lines] > the cost of making the code more complicated, for example by requiring a > "retVal"? If so, what are they? I tend to end up with a single-exit solution, but than I also tend to lard my code fairly liberally with debugging statements (and multi-valued debugging switches). I find that this is generally easier to set up and works better with a single exit. This is a language-agnostic position on my part: I use the same approach in any language. It was proven in IDMS/COBOL systems, carried through to C and now to Java.
I should add that I don't go to this trouble merely to debug the methods in a particular class, but do it this way because I find the tracing useful as I add successive classes and hierarchies of classes to a complex process. It continues to be useful when system testing starts to integrate intercommunicating processes.
Last but not least, it remains useful in debugging live code: a well-thought out tracing system can, for instance, help to distinguish between a user who didn't type what (s)he thought (s)he typed when entering data and a genuine bug or to diagnose problems if the data feed from an upstream system changes in unexpected ways.
> I believe that there is a significant gain in ease of debug and change > for languages without try-finally or equivalent. I am just not convinced > for Java. I don't find much difference, but then my philosophy is to restrict throwing exceptions to potentially fatal situations. I generally do not use them to signal expected non-fatal conditions such as end of file in the grounds that the higher level classes must detect and act on them without undue contortions, tangled logic or data loss.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
Patricia Shanahan - 16 May 2007 23:28 GMT ...
>> I believe that there is a significant gain in ease of debug and change >> for languages without try-finally or equivalent. I am just not convinced [quoted text clipped - 5 lines] > the grounds that the higher level classes must detect and act on them > without undue contortions, tangled logic or data loss. try-finally does not require any use of exceptions. It just provides a way of having the finally block run on completion of the try block.
I thought single exit was a very good idea when I was programming in assembly languages and later in C. Is it a good idea in Java, or just a habit?
Patricia
Lew - 17 May 2007 01:14 GMT > try-finally does not require any use of exceptions. It just provides a > way of having the finally block run on completion of the try block. > > I thought single exit was a very good idea when I was programming in > assembly languages and later in C. Is it a good idea in Java, or just a > habit? Very interesting discussion. What I like about Patricia's suggestion is a sense of flexibility - she seems to express a bias for single-exit structure, but violates that principle when there is a compelling argument that another way is clearer.
This is one of those areas where I would leave it to the practitioner, if everyone is thinking as carefully as the respondents in this thread. Arguments in both directions were founded on the same basic principles of code clarity and maintainability. Whichever decision you make is likely to be elegant for some values of elegant, if you work from such sound first principles.
If I were reviewing, say, Martin's or Patricia's code, I would not ding either for the decisions they described here. Both would be based on intelligent goals and clear thinking; the difference is a matter of style at that point.
At some threshold one must recognize that coding is an art, and some rules should not become repressive. There is room for individual style.
 Signature Lew
Martin Gregorie - 17 May 2007 12:37 GMT > I thought single exit was a very good idea when I was programming in > assembly languages and later in C. Is it a good idea in Java, or just a > habit? Good question. As you say, it is a very good strategy in C and assembler. It mostly works for me in Java though, as I said earlier, its mainly conditioned by my tracing philosophy. I much prefer using trace statements to a debugger and always leave tracing in production code.
I frequently start off writing a class with multi-exit methods for the same reasons that you give but often switch and rewrite them as single exit after a few methods have been written and it becomes obvious that an exit tracing capability would be useful. Exit tracing is a real pain for multi-exit methods and does a good job of obscuring the logic. I realize this is probably the mark of insufficient preliminary thought but at least I typically make the switch early in the process of coding the class, so relatively little code needs to be restructured.
I prefer to trace the exit from a method rather than entry to it. This allows a trace file to contain one line per method called while still showing the method name, arguments and return value. Of course, if the method is large and complex then increasing the trace detail level should trace its entry and (possibly) still higher detail levels would trace the internals. The latter tends to comes out in the wash if things are organized so the trace detail level approximates the method call depth in the program.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
Lew - 17 May 2007 13:24 GMT > Good question. As you say, it is a very good strategy in C and > assembler. It mostly works for me in Java though, as I said earlier, its > mainly conditioned by my tracing philosophy. I much prefer using trace > statements to a debugger and always leave tracing in production code. I trust you use a logging package in order not to create trouble for the production code. I really hope you don't use System.out for your traces.
Otherwise, I would certainly ding such code in a review.
 Signature Lew
Martin Gregorie - 17 May 2007 15:40 GMT > I trust you use a logging package in order not to create trouble for the > production code. I really hope you don't use System.out for your traces. So far all my Java code has been stand-alone executables and I have used stderr for tracing. In this situation sending it to the system logger or to a dedicated logging process is overkill: redirecting stderr to a file is sufficient. However, all tracing is handled by a utility class, so sending it elsewhere would involve a simple change to one method within a dedicated class.
> Otherwise, I would certainly ding such code in a review. I'd agree with you if I was dealing with a multi-process system.
In a complex, multi-process system I might configure the system logger to send my tracing info to a private log file. However, its more likely that I'd use a custom logging process, partly for portability and partly because that allows multiple copies of the system to keep their logging output separate.
My current project offers yet another possibility. The main process will be run as a cron task, so the best place to send error reports or tracing is to stderr. Crond automatically collects all output from stdout and stderr and e-mails it to the sysadmin. Problem solved. As a bonus there's no additional code needed to analyze or rotate logs.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
Lew - 17 May 2007 16:20 GMT > I'd agree with you if I was dealing with a multi-process system. > [quoted text clipped - 9 lines] > stdout and stderr and e-mails it to the sysadmin. Problem solved. As a > bonus there's no additional code needed to analyze or rotate logs. All of these are good ideas. Your analysis proves once again the triumph of thought over dogma.
Both you and Patricia apply a variety tools to the situation, be it runtime logging or tracing, profiling (as in Patricia's hill-climbing heuristics example), or development-time debug statement-stepping with variable watches. Neither seems to think that any one tool or technique is the be-all and end-all of every related problem. Thoughtful analysis seems to inform the choices.
Like the heuristic algorithm, programs represent local maxima of value to a problem's solution. It is likely an untenable problem to prove that any given program represents the absolute maximum value to a problem's solution.
I endorse the use of System.err for traces and the like. I do think logging calls are of low enough coding overhead to justify their use even in fairly small programs. Their main advantage there is the ability to turn them on and off without rebuilding an app, allowing a maintainer to zero in on problems only when they occur and virtually eliminate logging overhead otherwise.
But to insist that logging is the only solution would be to let dogma win over thought.
 Signature Lew
Patricia Shanahan - 17 May 2007 15:51 GMT >> I thought single exit was a very good idea when I was programming in >> assembly languages and later in C. Is it a good idea in Java, or just a [quoted text clipped - 22 lines] > are organized so the trace detail level approximates the method call > depth in the program. Sounds like a very different approach to debug from mine. I tend to collect information not just for a specific problem, but to answer a specific question about the problem. It is possible that all exits from some method would be the key information, but just as likely that I would need to know about uses of a particular path inside the method.
I do sometimes want access to data from a normally running program, without having a specific problem to debug. For example, one of my programs uses a hill climbing heuristic that can reach a local optimum. I often want to review its behavior. I supported that with logging calls at points in the code where the information I need is most conveniently available. I don't think any of them are method exits.
Patricia
Martin Gregorie - 17 May 2007 21:07 GMT >>> I thought single exit was a very good idea when I was programming in >>> assembly languages and later in C. Is it a good idea in Java, or just a [quoted text clipped - 25 lines] > > Sounds like a very different approach to debug from mine. Maybe not that different. I suspect that an OO purist could easily throw rocks at my class decomposition, but one result is that most of my methods are fairly small and linear. If a method is becoming large and complex it gets refactored into a set of private methods and the hierarchic tracing levels adjusted so that higher debug levels will cause the private methods to be traced. This way I don't get deluged with low level tracing detail if I don't need to see it.
> I tend to > collect information not just for a specific problem, but to answer a > specific question about the problem. It is possible that all exits from > some method would be the key information, but just as likely that I > would need to know about uses of a particular path inside the method. The way that I use debugging levels more or less maps onto this.
Another neat idea that I first saw in the depths of George 3 is to continually generate tracing, but put the result into a circular buffer. If a fatal error occurs the buffer gets dumped in trace event sequence. Its useful for solving problems in long running processes without burying yourself in debugging output, but is only suitable for processes that don't carry much context over from one logical piece of input to the next.
> I do sometimes want access to data from a normally running program, > without having a specific problem to debug. For example, one of my > programs uses a hill climbing heuristic that can reach a local optimum. > I often want to review its behavior. I supported that with logging calls > at points in the code where the information I need is most conveniently > available. I don't think any of them are method exits. Yes, I do that too when needed. In addition, when performance and/or memory use is critical I'll instrument the programs in the system so that its easy to follow performance over time. Performance data might get written to a database, if the system uses one, or to a log file. Either way the system would almost certainly include a performance analysis program.
A good (non-Java) example of this occurred a while back when I was away from home and paying for my phone usage. I made sure ppp was logging session stats and wrote a pair of gawk programs to extract ppp session details from the log and consolidate them into a session diary so they could be easily reconciled with the phone bill.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
tjmadden1128@gmail.com - 17 May 2007 15:59 GMT > ... > >> I believe that there is a significant gain in ease of debug and change [quoted text clipped - 15 lines] > > Patricia Habit, for me. In on C project I was working on long ago, the setjmp/ longjmp was wrapped in macros to resemble TRY/CATCH/FINALLY. So a return in the middle of the macros would corrupt the return stack, and the program would go to undefined places. At that point, it was a hard and unbreakable rule. But I hate complex if/else if/else constructs more, so if you are doing something like that just to maintain a single exit point, I'd ding it.
I've never tried, but what would happen if a return was done inside a try/finally block?
public class Foo { private int pg=13; private int r = 18; public boolean Rating(int age) { try { if (age > r) { return true; } } finally { return false; } } }
Contrived example: not real code.
Lew - 17 May 2007 16:27 GMT > I've never tried, but what would happen if a return was done inside a > try/finally block? [quoted text clipped - 13 lines] > > Contrived example: not real code. For this we turn to the JLS, ss. 14.20.2: <http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.20.2>
> A try statement with a finally block is executed by first executing the try block. Then there is a choice: > > * If execution of the try block completes normally, then the finally block is executed, and then there is a choice: > o If the finally block completes normally, then the try statement completes normally. > o If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S. The finally return supersedes the try return.
 Signature Lew
Lew - 17 May 2007 16:30 GMT > I've never tried, but what would happen if a return was done inside a > try/finally block? [quoted text clipped - 13 lines] > > Contrived example: not real code. For this we turn to the JLS, ss. 14.20.2: <http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.20.2>
> A try statement with a finally block is executed by first executing the try block. Then there is a choice: > ... > * If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice: > o If the finally block completes normally, then the try statement completes abruptly for reason R. > o If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded). The finally return supersedes the try return.
 Signature Lew
tjmadden1128@gmail.com - 17 May 2007 16:34 GMT > ... > try-finally does not require any use of exceptions. It just provides a [quoted text clipped - 5 lines] > > Patricia For me, habit. I worked a long time on a C app with setjmp/longjmp put in TRY/CATCH/FINALLY macro constructs. If a developer did a return inside of the macros, the return stack was corrupted. I hate convoluted if/else logic worse, though, so I am not completely against multiple exit points. But something like this would not be good IMHO, even though it works as I would expect:
public class EarlyExit {
private final int ageForPG = 13; private final int ageForR = 18;
public boolean oldEnough(int age) { try { if (age > ageForR) { System.out.println("Old enough"); return true; } } finally { if (age < ageForPG) { System.out.println("Go away, kid, ya bother me!"); return false; } } System.out.println("How old are you again?"); return false; }
public static void main(String[] args) { EarlyExit test = new EarlyExit(); test.oldEnough(16); test.oldEnough(21); test.oldEnough(10); }
}
How old are you again? Old enough Go away, kid, ya bother me!
Tim
printdude1968@gmail.com - 17 May 2007 21:26 GMT On May 17, 12:34 pm, "tjmadden1...@gmail.com" <tjmadden1...@gmail.com> wrote:
> > ... > > try-finally does not require any use of exceptions. It just provides a [quoted text clipped - 49 lines] > > Tim I thought that the "try...finally" construct was used more for handling exceptions. I've never seen it used as an alternate to the if...else construct. Is this the intention of your code or am I reading it wrong? Why are you using the try...finally like that?
Lew - 17 May 2007 22:20 GMT > I thought that the "try...finally" construct was used more for > handling exceptions. I've never seen it used as an alternate > to the if...else construct. Is this the intention of your code or am > I reading it wrong? Why are you using the try...finally > like that? tjmadden1128 was showing an example of what to avoid.
try ... finally is not only for exceptions. The catch block is not required if there is a finally block.
A legitimate use of try ... finally is to guarantee to clean up resources such as connections.
<snippet> Connection cxn = getConnection(); if ( cxn == null ) { throw new RuntimeException( "oops!" ); } try { int result = doSomethingUseful( cxn ); if ( result == 0 ) { return; } result = doSomethingElseUsful( cxn ); if ( result < 0 ) { throw new RuntimeException( "drat!" ); } return; } finally { close( cxn ); } </snippet>
 Signature Lew
tjmadden1128@gmail.com - 18 May 2007 15:33 GMT On May 17, 2:26 pm, "printdude1...@gmail.com" <printdude1...@gmail.com> wrote:
> On May 17, 12:34 pm, "tjmadden1...@gmail.com" <tjmadden1...@gmail.com> > wrote: [quoted text clipped - 4 lines] > I reading it wrong? Why are you using the try...finally > like that? Just as a simple example, and I was curious as to how it would work. Lew then pointed me to where the spec says what should happen. Situations where I might use it is as Lew also posted, to ensure that a database or socket connection or open file is closed. I would not use it in place of an if/else construct, unless it really made code clearer by replacing a bunch of nested if/else's. Even then, I'd think long and hard on it.
Tim
Chris Smith - 18 May 2007 20:25 GMT > I thought single exit was a very good idea when I was programming in > assembly languages and later in C. Is it a good idea in Java, or just a > habit? Among those who read my code, I'm somewhat famous for radically rooting out and removing any repetition (or, as my detractors would say, "consistency" :), so my answer is definitely biased by this. I find that the single-exit-per-block rule prohibits certain abstractions that I find useful. Once specific example is that when implementing equals methods, I often find that the following pattern best expresses the logic of the routine:
public boolean equals(Object o) { if (...) return false; if (...) return false; if (...) return false;
return true; }
I can't find any way to write this that sticks to one exit point and expresses the concept anywhere near as clearly, without writing an if condition that's many lines long and blocks me from naming the results of intermediate computations with local variables.
I would do this in other languages as well, though, even without the try/finally construct. If I want something to happen when a function completes, then I'd write:
someWrapper() { theRealFunction(); postprocess(); } theRealFunction() { ... }
The only time I've really run into a major conflict about this is with someone who wanted to add debug logging statements throughout the code. I simply don't do that. I've learned to like AOP (despite still believing it should be very rarely used in production) because it saves me from having to do something that I find so utterly hideous as sprinkling print statements throughout my code for debug logging.
So I'm definitely a little outside the mainstream, but that's my perspective.
 Signature Chris Smith
Daniel Pitts - 16 May 2007 21:35 GMT > >> Why one exit point per method? > [quoted text clipped - 21 lines] > -- > Lew I also find that avoiding multiple exit points leads to variable reuse, which is a far worse practice. Actually, I think that it makes sense for a method to possible have multiple exit points, as long as it only has one entry point :-) Can you imagine debugging a method who's entry point could be in one of three places?
Lew - 16 May 2007 22:33 GMT > I also find that avoiding multiple exit points leads to variable > reuse, which is a far worse practice. Actually, I think that it makes > sense for a method to possible have multiple exit points, as long as > it only has one entry point :-) Can you imagine debugging a method > who's entry point could be in one of three places? Imagine? I can remember. I used to work on systems that allowed multiple entry points in a routine. I agree that single entry point is much nicer.
 Signature Lew
Patricia Shanahan - 16 May 2007 20:17 GMT >> Why one exit point per method? >> [quoted text clipped - 6 lines] > Maybe it is my opinion, but It makes it easier to debug, and it is > easier to change later on without breaking it or introducing errors. Can you explain why?
Thanks,
Patricia
printdude1968@gmail.com - 17 May 2007 02:43 GMT > >> public boolean getStatus(String rating, int age){ > [quoted text clipped - 22 lines] > > Patricia Having come from a procedural language background, I was always taught 5 rules that could not be broken: 1) Single Entry Point 2) Single Exit Point 3) No GOTO's allowed 4) No self-modifying code. 5) One procedure, one function
Having been trying to learn Java, I am now of the opinion that one can still write well structured programs yet not be regimented by the above rules, more over numbers 1 and 2. I found this site http://ivan.truemesh.com/archives/000611.html which appears to agree with me. And just to quote a section of the above site,
Longer functions that use the "single exit point" rule can get really convoluted and difficult to understand. Having a function return as soon as it can improves the clarity because it improves the "locality" of the code.
ros - 03 Apr 2007 23:58 GMT > > Hi, > [quoted text clipped - 88 lines] > > V. Thank you so much Vishist for the help. It makes sense. Ros
Daniel Pitts - 16 May 2007 21:31 GMT > Hi, > [quoted text clipped - 45 lines] > > } if (age < minAge) isn't true, then age >= minAge MUST be true, so after for it again doesn't make sense so what you're really trying to do is if (age < minAge) { return false; } else { // age >= minAge return true; }
Also, when the difference in outcome of an if/else statement is only a boolean value, you can replace the if/else with just the boolean value. So you end up with this: // return true if the age is acceptable. return age >= minAge;
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|