Skip to content

Instantly share code, notes, and snippets.

@edefazio
Last active March 8, 2016 17:33
Show Gist options
  • Save edefazio/f2a21adc8024abcb7eed to your computer and use it in GitHub Desktop.
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
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