Last active
March 8, 2016 17:33
-
-
Save edefazio/f2a21adc8024abcb7eed to your computer and use it in GitHub Desktop.
Examples of Alternative Styles... why Eric's Style is superior with examples with rationale
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ex.codestyle; | |
public class WhyThisFormatVersesThat | |
{ | |
/** | |
* Style Rule: There is NO SPACE between a method name, catch, for, if, statements | |
* and it's opening parenthesis | |
*/ | |
public static class OpenParen | |
{ | |
/** | |
* RIGHT | |
* | |
* METHODS (Definition AND INVOCATION) Rationale: | |
* the open parenthesis '(' is a required part of of the method | |
* defintion AND useage (the compiler checks this), so, when we | |
* define or invoke a method, it can be said that the opening | |
* parenthesis BELONGS WITH the method name, adding a space BETWEEN | |
* the methodName and the parameter list goes against the idea that | |
* things that are (physically) coupled together belong together. | |
* | |
* It is ALSO more clear when there are NESTED parenthesis if you | |
* must quickly scan over the method. | |
* | |
* STATEMENTS (if, for, while, catch) | |
* Again the compiler FORCES us to use a '(' therefore, | |
* for consistency, the statements | |
* <UL> | |
* <LI>"if(" ... | |
* <LI>"for(" ... | |
* <LI>"while(" ... | |
* <LI>"catch(" | |
* </UL> | |
* | |
*/ | |
noSpaceBetweenMethodNameAndParens( String[] parameters ) | |
{ | |
//an if should ALWAYS be (3) characters "if(", | |
if( thereIsAProblem ) | |
{ | |
//there are NO parameters, we dont need internal space | |
yoIllSolveIt(); | |
} | |
try | |
{ | |
checkOutTheHook(); | |
} | |
catch( NotRevolvesItException nrie ) | |
{ | |
myDj.revolve( it ); | |
} | |
} | |
/** | |
* WRONG | |
* extra spaces between the name and the arguments list, | |
* rather than adding clarity, add confusion by separating | |
* the method signiture which requires the parenthesis () by the Compiler | |
*/ | |
spaceBetweenMethodNameAndParens ( String[] parameters ) | |
{ | |
//this looks fine, but isnt consistent | |
if ( thereIsAProblem ) | |
{ | |
//this () looks disconnected from the methodName | |
yoIllSolveIt (); | |
} | |
try | |
{ | |
//again this looks strage whilst being compileable (what does the space represent?) | |
checkOutTheHook (); | |
} | |
catch ( NotRevolvesItException nrie ) | |
{ | |
//here, since we padded the parameters, and (internally) | |
//it seems the parameter-list is "separate" from the methodName | |
myDj.revolve ( it, playThatFunkyMusicWhiteBoy ); | |
} | |
} | |
} | |
/** | |
* Style Rule: There is no "interior padding" within Typecasts: | |
* So (String)varaible and not ( String )variable | |
* Also: there is NO SPACE between the cast () and the expression/variable | |
* being cast (Because it "works" just like a ternary operator) | |
*/ | |
public static final class Typecasts | |
{ | |
/** RIGHT | |
* Notice it is easy to spot and differentiate between | |
* an argument list ( Object someVariable ) with padding | |
* and a typecast (String)somevariable without padding | |
* we can easily scan the code and parse the difference | |
* ALSO, on a functional level, a TypeCast "Acts" like | |
* the ternary operators does (there is NO space between the) | |
* only typecasts work for Objects rather than primitives | |
*/ | |
public static void noSpaceInCastParens( Object someVariable ) | |
{ | |
String s = (String)someVariable; | |
} | |
/** | |
* WRONG | |
* here it is visually easy to mistake a typecast ( String ) | |
* ... for an argument list ( Object someVariable ) | |
* | |
* ALSO it takes more time to realize the Cast operates in the same vein | |
* as a prefix ternary operator like: --i (where the decrement operation is | |
* applied to the i variable before returning) | |
* (String)someVariable operates "like" this | |
*/ | |
public static void spaceInCastParens( Object someVariable ) | |
{ | |
String s = ( String ) someVariable; | |
} | |
} | |
/** | |
* Style Rule: There is A SPACE BETWEEN BINARY Operators ( <, >, =, &&, ||, ...) | |
* and the (2) variables / epxressions | |
* | |
* WHY: | |
* <UL> | |
* <LI>because it gives the Operator EMPHASIS (surronding it with spaces) makes it easier to read/parse | |
* <LI>because it belongs to NEITHER the LEFT variable/expression and the RIGHT variable/expression | |
* </UL> | |
*/ | |
public static class BinaryOperators | |
{ | |
/** | |
* RIGHT | |
* | |
* this "spaced out" "for" operation uses (2) binary expressions and | |
* (1) ternary | |
* Probably the most IMPORTANT thing we look at | |
*/ | |
public static void spaceBetween() | |
{ | |
if( thereAreMoreSecretsAheadOfUs && weCanMoveForward() ) | |
{ | |
letsContinue(); | |
} | |
//here the important tokens are given the approrpiate "weight" | |
// the "int i = 0"; and "i < 100" | |
for( int i = 0; i < 100; i++ ) | |
{ | |
} | |
} | |
/** | |
* This simple example is how "most" code looks for a "for" statement | |
* I think it's wrong, because everything is smooshed together... it is more | |
* "economical" as far as the total number of characters used, but other than that | |
* it requires your focussed attention to read/parse/decypher. Also note, as things | |
* become more complicated (multiple initializations separated by commas, etc.) it | |
* increase the noise | |
*/ | |
public static void noSpaceBetween() | |
{ | |
for( int i=0; i<100; i++ ) | |
{ | |
} | |
//You wouldnt do this, it just looks like ONE THING instead of an expression | |
// with a binary expression in the middle | |
if( thereAreMoreSecretsAheadOfUs&&weCanMoveForward() ) | |
{ | |
} | |
//the equality check is not given enough emphasis | |
if ( i==5 ) | |
{ | |
} | |
} | |
} | |
/** | |
* Style Rule: There is NO SPACE between a Ternary operators (-, !, ++, --, ...) | |
* and the expression/variable. | |
* <UL> | |
* <LI>"!a" is preferred to "! a") | |
* <LI>"!isfound( number )" is preferred to "! isFound( number )" | |
*/ | |
public static class TernaryOperators | |
{ | |
/** | |
* #1) RECOMMENDED WAY | |
* NO space between a TERNARY OPERATOR | |
* and the expression in following with the THIS (OPERATION) | |
* BELONGS to THIS (VARIABLE/EXPRESSION). | |
*/ | |
public static void noSpaceBetweenNotAndExpression() | |
{ | |
int i = 0; | |
int j = 0; | |
if( !( multiLineMark instanceof Delete ) ) | |
{ | |
builder.blank(); | |
} | |
i++; | |
--j; | |
} | |
/** | |
* #2 Alternatively, we can evaluate this ternary Expression | |
* BUT it reads that this NOT (!) OPERATOR is "on an island", and not | |
* "Applied" to the expressin in parenthesis | |
* | |
* also for short expressions (i++) it loks awkward | |
*/ | |
public static void spaceBetweenNotAndExpression() | |
{ | |
if( ! ( multiLineMark instanceof Delete ) ) | |
{ | |
builder.blank(); | |
} | |
i ++; | |
-- j; | |
} | |
} | |
/** | |
* In general the RULE is break AFTER an open tag so parameters | |
* are aligned (each on their own separate line indented 4 spaces) | |
*/ | |
public static class BreakingLines | |
{ | |
/** | |
* RIGHT | |
* Here we do a lineBreak AFTER the open parenthesis of the method | |
* Now each parameter is given the same "precedence" the first parameter | |
* is the name of the Frame, the next (4) are fields of the Frame | |
* | |
* Also note: by putting the "close parenthesis" on a line by itself | |
* it presents a simple "visual Closure" property | |
*/ | |
public void breakAfterMethodOpenParenthesis() | |
{ | |
return LowToHigh_LIFOStack.frame( | |
"NetflixPrize", | |
Field.range( "personId", 1, 10 ), | |
Field.range( "movieId", 1, 20 ), | |
Field.range( "rating", 1, 5 ), | |
Field.of ( "ratingDay", Day.of( "1996-01-01", "2007-12-31" ) ) | |
); | |
} | |
/** | |
* WRONG break only when necessary (be "economical") | |
* Here it is hard to parse and differentiate | |
*/ | |
public static void breakEconomy() | |
{ | |
return LowToHigh_LIFOStack.frame( "NetflixPrize", Field.range( "personId", 1, 10 ), | |
Field.range( "movieId", 1, 20 ), Field.range( "rating", 1, 5 ), | |
Field.of ( "ratingDay", Day.of( "1996-01-01", "2007-12-31" ) ) ); | |
} | |
/** | |
* RIGHT: break after parenthesis | |
* SIMPLE RULE IF YOU CANT fit the argument list on one line: | |
* <UL> | |
* <LI> Split AFTER the opening '(' (before the arguments) | |
* <LI> indent (4) spaces | |
* <LI> each parameter gets its own line | |
* </UL> | |
* | |
* Its easy at a glance to understand the structure of this (nested) method call | |
*/ | |
public static void breakAfterOpenParenthesis( BindOption bindOption ) | |
{ | |
return Tailor.toSource( | |
"example.myapp.prize", | |
LowToHigh_LIFOStack.frame( | |
"NetflixPrize", | |
Field.range( "personId", 1, 10 ), | |
Field.range( "movieId", 1, 20 ), | |
Field.range( "rating", 1, 5 ), | |
Field.of ( "ratingDay", Day.of( "1996-01-01", "2007-12-31" ) ) | |
), | |
bindOptions | |
); | |
} | |
/** | |
* WRONG | |
* tabbed over | |
* Here I tried to align the parameters AFTER the open parenthesis of the method | |
* signiture. This becomes a burden when the instance/ method name could be long | |
*/ | |
public static void breakAlignWithOpenParenthesis() | |
{ | |
/* here we run out of (horizontal) space REAL FAST */ | |
return Tailor.toSource( "example.netflix.prize", | |
LowToHigh_LIFOStack.frame( "NetflixPrize", | |
Field.range( "personId", 1, 10 ), | |
Field.range( "movieId", 1, 20 ), | |
Field.range( "rating", 1, 5 ), | |
Field.of ( "ratingDay", Day.of( "1996-01-01", "2007-12-31" ) ) | |
), | |
bindOptions); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment