Scala Best Practices - enosis-dev/FoodBuy GitHub Wiki
- Remove Option from variable names, it makes the names un-necessary long. For example: "activeMOGDistributorInclusionRuleOption" should be "activeMOGDistributorInclusionRule". See more: http://stackoverflow.com/questions/11887181/scala-naming-convention-for-options
- Do not inclue package names in class name. So if we have a package "Query.Builder" then the classes or objects under it should not require to have the package name as suffix. So, "ActiveMOGDistributorInclusionQueryBuilder" should be named as "ActiveMOGDistributorInclusion".
- Do not make varaible names unnecessarily long. Use your judgement while naming variables. Sometimes vairables usage can be easily identified from code context so need to make them long. Such as the name "activeMOGDistributorInclusionQueryBuilderFilterResult" should be "activeMOGDistributorInclusionResult".
- Do not keep extra new-lines in the code, unless it helps make the code easy to read. Still use new-line sparingly.
- Resolve all IDEA(the intellij scala ide) warnings unless the warnings are unfounded. Most of the time heading IDEA warnings lead to better code.
- Use named arguments only if
- We are passing constant values not variable, such as foo(x = 6, y = 7)
- If arguments are more than 4
- If arguments are less than or equal to 4 but arguments context can not be easily understood from the names of the parameters.
- If there are nullable fields in the arguments then always use named arguments.
- So this is an overkill: purchaseHistoryService.filterPurchaseHistory( purchaseHistoryInputTables = purchaseHistoryInputTables, rules = rules)
-
Don't introduce braces for simple statements: http://twitter.github.io/effectivescala/#Formatting-Braces
-
While declaring variables specify types if it can not be inferred from the right side
var x = getX()
Here we are getting the value of x from getX(). in this case it is better to explicitly define the type of x.var x: X = getX()
But for cases like this:var x = Seq(2, 3, 4)
There is no need to specify type explicitly. The type is easily understandable from the right side assignment. -
Have a look at this: https://github.com/alexandru/scala-best-practices.
-
Always add implementation details in as a note for complex business logic. This will help future code maintainer and also you when you return to this code block at later period of time to understand what is done and why it is done in this way. Please see more: http://stackoverflow.com/a/5619704. For example:
/** * Find Distributor keys for valid MOG * <p> * Implementation Details: * Add the * </p> * @param distributorLevelDistributors * @param distributorLevels * @param managedOrderGuides * @return */ private def getChildDistributorKeys( distributorLevelDistributors: DataFrame, // Relation between distributor and its level distributorLevels: DataFrame, // contain the distributor level hierarchy managedOrderGuides: DataFrame): DataFrame = {}
-
Continuing from the above point, always mention details parameter description in functions. For example: in query builder we pass a lot of parameters. Please give a short description on the parameter values such as whether it a dataframe containing all Customers or it is the input customers coming from rules.
-
Do not introduce trait unless it is adding some value. Such as ModuleService trait. It is doing nothing for now.
-
Always use enum for string comparisons with rather than comparing with hard coded strings.