├── .gitignore ├── README.md ├── css └── README.md ├── html └── README.md └── java ├── README.md ├── android └── README.md └── spring └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | atlassian-ide-plugin.xml 3 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | THIS PROJECT IS DISCONTINUED — USE AT YOUR OWN RISK 2 | 3 | It has been a fun and great project but it's time for us to move on. Check out our recent work that we are doing with Scala and follow us on Github and Twitter for new and exciting open source projects. Thanks for your continuing support. If you wish to take on maintenance of this library please contact us through the issue tracker. 4 | 5 | coding-guidelines 6 | ================= 7 | -------------------------------------------------------------------------------- /css/README.md: -------------------------------------------------------------------------------- 1 | # CSS Coding Standards 2 | 3 | The purpose of the 47 Degrees CSS Coding Standards is to create a collaboration baseline; helpful for scenarios where many people are creating, modifying, and contributing CSS to the same project. The end goal is unity, consistency, and the notion that a single entity created the outputted code. 4 | 5 | This is a living document. The authors grow wiser with each passing day. 6 | 7 | ## Table of Contents 8 | 9 | 1. [General](#section-general) 10 | 2. [Comments](#section-comments) 11 | 3. [Format](#section-format) 12 | 4. [Selectors](#section-selectors) 13 | 5. [Properties](#section-properties) 14 | 6. [Media Queries](#section-media-queries) 15 | 16 | 17 | ## 1. General 18 | 19 | * All code, regardless of who touches it, should look like a single person created it. 20 | * All culprits who ignore the aforementioned rule will be docked one pint of beer. 21 | 22 | 23 | ## 2. Comments 24 | 25 | Well documented CSS is like a double rainbow; you just have to smile. We have all fallen victim to undocumented code from others; even being guilty of being too lazy to add our own comments to code. The mental statement "I'll add it later" is the precursor to "WTF, what is going on here". Let's avoid that. 26 | 27 | To alleviate the ho-hum repetitive nature of entering properly formatted comments, configure your text editor (use your Editor Snippets or [TextExpander](http://smilesoftware.com/TextExpander/)). 28 | 29 | * Use a Table of Contents (TOC) at the top of the document. 30 | * Add a hashtag `#` to the opening section title e.g. `#Header`. 31 | * Keep line-lengths short e.g. 50 columns. 32 | * Comments are *good*. Go crazy with them. 33 | * Use comments to break up CSS code logical sections 34 | 35 | **Table of Contents:** 36 | 37 | ```css 38 | /* Table of Contents 39 | ================================================== 40 | #Section-1 41 | #Section-2 */ 42 | ``` 43 | 44 | **Section Comments:** 45 | ```css 46 | /* #Section-1 47 | ================================================== */ 48 | 49 | .selector-1 { 50 | background: #fff; 51 | color: #333; 52 | } 53 | 54 | .selector-2 { 55 | background: #fff; 56 | color: #333; 57 | } 58 | 59 | /* #Section-2 60 | ================================================== */ 61 | 62 | .selector-3 { 63 | display: inline-block; 64 | } 65 | 66 | .selector-4 { 67 | background: #fff; 68 | color: #333; 69 | } 70 | ``` 71 | 72 | 73 | ## 3. Format 74 | 75 | The first step to authoring consistent stylesheets begins with solid document structure and coding conventions. 76 | 77 | * Indent each property with tabs, not spaces. Preference is tabs. 78 | * One selector per line in multi-selector rulesets. 79 | * Include a single space before the opening curly brace. 80 | * Place the closing curly brace in the same column as the first character of the ruleset. 81 | * Include a single space after the colon of a declaration. 82 | * Shorthand lowercase hex values (e.g. `#fff` not `#FFFFFF`). 83 | * Use single or double quotes consistently. Preference is double quotes (e.g. `content: "";` not `content: ''`). 84 | * Separate rulesets with *one* blank line. 85 | * Separate sections with *two* blank lines (e.g. two blank lines after the last ruleset before entering a new section comment). 86 | 87 | **Correct:** 88 | 89 | ```css 90 | .selector-1, 91 | .selector-2 { 92 | background: #fff; 93 | color: #333; 94 | } 95 | ``` 96 | 97 | **Incorrect:** 98 | 99 | ```css 100 | .selector-1, .selector-2 { background: #FFFFFF; color: #333333; } 101 | ``` 102 | 103 | 104 | ## 4. Selectors 105 | 106 | Broad selectors are too easy to abuse and will likely result in head-banging frustration. Broad selectors (e.g. `nav a {}`) may be efficient in the interim, but likely to require overriding properties farther down the cascade. Careful planning can prevent such scenarios. Use your best judgment. 107 | 108 | * Use lowercase words separated by hyphens. Avoid underscores or camelcase formatting. *This may be unavoidable due to 3rd party scripts which inject CSS.* 109 | * We are humans, not robots. In addition to descriptive comments, selectors may be used to describe elements (e.g. `.lead-testimonial p {}` instead of `.boxed p {}`). 110 | * Double quotes for attribute selectors (e.g. `input[type="text"]` not `input[type='text']`). 111 | * Avoid over-qualified selectors (e.g. `.container {}` not `div.container{}`). 112 | 113 | **Correct:** 114 | 115 | ```css 116 | .top-nav { 117 | margin: 0; 118 | } 119 | 120 | input[type="text"] { 121 | line-height: 1.2em; 122 | } 123 | ``` 124 | 125 | **Incorrect:** 126 | 127 | ```css 128 | .topNav { /* Avoid camelcase */ 129 | margin: 0; 130 | } 131 | 132 | .top_nav { /* Avoid underscores */ 133 | margin: 0; 134 | } 135 | 136 | ul.top-nav { /* Avoid over-qualification */ 137 | margin: 0; 138 | } 139 | 140 | .tp-nv-r { /* Avoid robot speak */ 141 | margin: 0; 142 | } 143 | 144 | input[type=text] { /* Missing double quotes around attribute */ 145 | line-height: 1.2em; 146 | } 147 | ``` 148 | 149 | 150 | ## Properties 151 | 152 | There is no true right or wrong method for property ordering, but given the oppotunity, who wouldn't attempt to instill a certain logical sense of order? Meaningful & semantic trumps random chaos. Try to order properties within rulesets using the following guide: 153 | 154 | 1. Display 155 | 2. Position 156 | 3. Box Model 157 | 4. Colors & Typography 158 | 5. Other 159 | 160 | CSS3 or vendor prefixed properties would fall under *Other*. 161 | 162 | **Example:** *Inline comments for reference only* 163 | 164 | ```css 165 | .navigation li { 166 | /* Position */ 167 | position: absolute; 168 | z-index: 1; 169 | /* Box Model */ 170 | padding: 10px; 171 | /* Colors & Typography */ 172 | background: #333; 173 | color: #fff; 174 | } 175 | ``` 176 | 177 | Order vendor prefixed properties longest to shortest (e.g. `-webkit-*` to `unprefixed`). For multi line editing, align values with spaces. 178 | 179 | **Preferred:** 180 | 181 | ```css 182 | .my-button { 183 | -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.3); 184 | -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.3); 185 | box-shadow: 0 1px 2px rgba(0,0,0,0.3); 186 | } 187 | ``` 188 | 189 | **Not Preferred:** 190 | 191 | ```css 192 | .my-button { 193 | -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.3); 194 | -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.3); 195 | box-shadow: 0 1px 2px rgba(0,0,0,0.3); 196 | } 197 | ``` 198 | 199 | 200 | ## Media Queries 201 | 202 | Media queries allow for responsive layout changes for varying screen sizes, yet degrade gracefully for older browsers. Old browser = no fun responsive layout. 203 | 204 | * Prefer media queries be grouped and at the end of the stylesheet. 205 | * Indent rulesets one level within each media query section. 206 | 207 | The following breakpoints serve as reference only and *are not all* required for responsive projects. 208 | 209 | ```css 210 | /* #Media Queries 211 | ================================================== */ 212 | 213 | /* Smaller than standard 960 (devices and browsers) */ 214 | @media only screen and (max-width: 959px) { 215 | /* Selectors here */ 216 | } 217 | 218 | /* Tablet Portrait size to standard 960 (devices and browsers) */ 219 | @media only screen and (min-width: 768px) and (max-width: 959px) {} 220 | 221 | /* All Mobile Sizes (devices and browser) */ 222 | @media only screen and (max-width: 767px) {} 223 | 224 | /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ 225 | @media only screen and (min-width: 480px) and (max-width: 767px) {} 226 | 227 | /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ 228 | @media only screen and (max-width: 479px) {} 229 | ``` -------------------------------------------------------------------------------- /html/README.md: -------------------------------------------------------------------------------- 1 | # HTML Code Guide 2 | 3 | This page will serve as a reference for HTML code snippets. This is a living document. Updates will appear whenever code is refactored and suitable to share as reference. -------------------------------------------------------------------------------- /java/README.md: -------------------------------------------------------------------------------- 1 | # Java Coding Standards 2 | 3 | The purpose of the [47 Degrees](http://47deg.com) Java Coding Standards is to create a collaboration baseline; helpful for scenarios where many people are creating, modifying, and contributing to the same project. The end goal is unity, consistency, and the notion that a single entity worked on the project. 4 | 5 | Java applications developed at *47 Degrees* should follow the [Code Conventions for the Java Programming Language](http://www.oracle.com/technetwork/java/codeconv-138413.html) 6 | 7 | *47 Degrees* uses the Java Programming Language and Java Related Technologies in different scenarios and applications. As a norm *47 Degrees* follows industry standards and notifying of any deviation of this document from these standards will be welcomed. 8 | 9 | **Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)* 10 | 11 | - [Java Coding Standards](#java-coding-standards) 12 | - [0. Rebel](#0-rebel) 13 | - [1. General](#1-general) 14 | - [2. Comments](#2-comments) 15 | - [3. Copyrights](#3-copyrights) 16 | - [3.1. Open Source](#31-open-source) 17 | - [3.2. Propietary - Not Open Source](#32-propietary---not-open-source) 18 | - [3.3. 3rd Parties](#33-3rd-parties) 19 | - [4. Good Practices](#4-good-practices) 20 | - [4.1. Design for interfaces](#41-design-for-interfaces) 21 | - [4.2. Define Application Layers.](#42-define-application-layers) 22 | - [4.3. Avoid multiple return statements](#43-avoid-multiple-return-statements) 23 | - [4.4. Boolean comparisons](#44-boolean-comparisons) 24 | - [4.5. for loops Vs for-each loops](#45-for-loops-vs-for-each-loops) 25 | - [4.5. String concatenation](#45-string-concatenation) 26 | - [4.6. Exceptions](#46-exceptions) 27 | - [4.7. Collections](#47-collections) 28 | - [4.8. Raw types](#48-raw-types) 29 | - [4.9. Use of final](#49-use-of-final) 30 | - [4.10. Name return values result](#410-name-return-values-result) 31 | - [4.11. Consider setters and getters for field access](#411-consider-setters-and-getters-for-field-access) 32 | - [4.12. Know your Java](#412-know-your-java) 33 | - [5. Design Patterns](#5-design-patterns) 34 | - [5.1. Abstract Factory](#51-abstract-factory) 35 | - [5.2. Factory method](#52-factory-method) 36 | - [5.3. Lazy Delegate Wrapper](#53-lazy-delegate-wrapper) 37 | - [5.4. Singleton](#54-singleton) 38 | - [5.5. Enums](#55-enums) 39 | - [5.6. Private Helpers](#56-private-helpers) 40 | - [6. Other Java Technologies](#6-other-java-technologies) 41 | - [7. Active enforcement](#7-active-enforcement) 42 | 43 | ## 0. Rebel 44 | 45 | Do NOT blindly obey these guidelines, use them where they make sense. 46 | 47 | ## 1. General 48 | 49 | * All code, regardless of who touches it, should look like a single person created it. 50 | * All culprits who ignore the aforementioned rule will be docked one pint of beer. 51 | 52 | ## 2. Comments 53 | 54 | Well documented Java code is as awesome as a [pizzokie](http://www.urbandictionary.com/define.php?term=pizzokie). We have all fallen victim to undocumented code; even being guilty of ignoring proper comments for our own code. Let's try and stop doing that. 55 | 56 | At *47 Degrees* comments in Java files should be written as [Doc Comments for the Javadoc Tool](http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html). 57 | 58 | **Correct:** 59 | 60 | ```java 61 | /** 62 | * Returns a user object that can be stored in the data store. 63 | * The name argument must be alphanumeric. 64 | *

65 | * This method always creates a new user, whether or not a user 66 | * with the same name already exists. 67 | * 68 | * @param name the name given to a new user 69 | * @return the newly created user 70 | * @see OtherClassOfInterest 71 | */ 72 | public User createUser(String name) { 73 | User user = new User(); 74 | user.setName(name); 75 | return user; 76 | } 77 | ``` 78 | 79 | **Incorrect:** 80 | 81 | ```java 82 | // creates a user 83 | public User createUser(String name) { 84 | User user = new User(); // a new user is always created 85 | user.setName(name); 86 | return user; 87 | } 88 | ``` 89 | 90 | ## 3. Copyrights 91 | 92 | All Java files should contain the appropiate copyright notice at the beginning of the file. 93 | 94 | ### 3.1. Open Source 95 | 96 | Open Source code written in *47 Degrees* that is open source is commonly released under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) and must be as follows. 97 | 98 | ```java 99 | /* 100 | * Copyright (C) {year} 47 Degrees, LLC 101 | * http://47deg.com 102 | * hello@47deg.com 103 | * 104 | * Licensed under the Apache License, Version 2.0 (the "License"); 105 | * you may not use this file except in compliance with the License. 106 | * You may obtain a copy of the License at 107 | * 108 | * http://www.apache.org/licenses/LICENSE-2.0 109 | * 110 | * Unless required by applicable law or agreed to in writing, software 111 | * distributed under the License is distributed on an "AS IS" BASIS, 112 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 113 | * See the License for the specific language governing permissions and 114 | * limitations under the License. 115 | */ 116 | ``` 117 | 118 | ### 3.2. Propietary - Not Open Source 119 | 120 | Code owned and written for 47 Degrees not for open sourced projects must be as follows. 121 | 122 | ```java 123 | /* 124 | * Copyright (C) {year} 47 Degrees, LLC 125 | * http://47deg.com 126 | * hello@47deg.com 127 | * All rights reserved 128 | */ 129 | ``` 130 | 131 | ### 3.3. 3rd Parties 132 | 133 | Code owned and written for 3rd parties should be formatted in the following way. 134 | 135 | ```java 136 | /* 137 | * Copyright (C) {year} {3rdPartyName} 138 | * {3rdPartUrl} 139 | * All rights reserved 140 | * Developed for {3rdPartyName} by: 141 | * 142 | * 47 Degrees, LLC 143 | * http://47deg.com 144 | * hello@47deg.com 145 | */ 146 | ``` 147 | 148 | ## 4. Good Practices 149 | 150 | Good practice are a must at *47 Degrees*. Code is periodically reviewed for both machines and humans to ensure code quality meets standards within the company. 151 | 152 | Pay special attention to the most common style errors... 153 | 154 | * classes too long 155 | * methods too long 156 | * little or no javadoc comments 157 | * swallow exceptions 158 | * multiple *return* statements 159 | * Overuse of arrays in place of collections 160 | * too much or no whitespace 161 | 162 | In the spirit of providing a guideline to avoid some of these errors and create better code the below listed points are cases with examples that should be considered at 47 Degrees. 163 | 164 | ### 4.1. Design for interfaces 165 | 166 | **Correct:** 167 | 168 | ```java 169 | /** 170 | * Defines the contract for the user related operations 171 | * @see User 172 | */ 173 | public interface UserService { 174 | } 175 | 176 | /** 177 | * Implements the UserService connecting and saving the user to the database 178 | * @see UserService 179 | */ 180 | public class LocalUserServiceImpl implements UserService { 181 | } 182 | ``` 183 | 184 | **Incorrect:** 185 | 186 | ```java 187 | /** 188 | * Does not implements the UserService but connects and saves the user to the database 189 | * @see UserService 190 | */ 191 | public class UserService { 192 | } 193 | ``` 194 | 195 | **Correct:** 196 | 197 | ```java 198 | public List getFriends(User user) { 199 | } 200 | ``` 201 | 202 | **Incorrect:** 203 | 204 | ```java 205 | public ArrayList getFriends(User user) { 206 | } 207 | ``` 208 | 209 | ### 4.2. Define Application Layers. 210 | 211 | **Correct:** 212 | 213 | ```java 214 | /** 215 | * User interface or API response (Serialized to JSON or used in view technologies such as JSP) 216 | */ 217 | public class UserResponse { 218 | 219 | private String name; 220 | 221 | public UserResponse(User user) { 222 | setName(user.getName()); 223 | } 224 | 225 | public String getName() { 226 | return this.name; 227 | } 228 | 229 | public void setName(String name) { 230 | this.name = name; 231 | } 232 | 233 | } 234 | 235 | /** 236 | * Handles UI interaction and communication to services (Servlets, Spring MVC Controllers, Android activities, Tapestry pages...) 237 | */ 238 | public class UserController { 239 | 240 | private UserService userService; 241 | 242 | public UserResponse onCreateUserFormSubmit(String name) { 243 | User user = userService.createUser(name); 244 | return new UserResponse(user); 245 | } 246 | 247 | } 248 | 249 | /** 250 | * Implements business logic (Spring Bean Services) 251 | */ 252 | public interface UserService { 253 | 254 | User createUser(String name); 255 | 256 | } 257 | 258 | /** 259 | * Implements the UserService 260 | * @see UserService 261 | */ 262 | public class LocalUserServiceImpl implements UserService { 263 | 264 | private PersistenceAdapter persistenceAdapter; 265 | 266 | public User createUser(String name) { 267 | User user = new User(); 268 | user.setName(name); 269 | persistenceAdapter.save(user); 270 | return user; 271 | } 272 | 273 | } 274 | 275 | /** 276 | * Entity that gets persisted to the data store 277 | */ 278 | public class User { 279 | 280 | private String name; 281 | 282 | public String getName() { 283 | return this.name; 284 | } 285 | 286 | public void setName(String name) { 287 | this.name = name; 288 | } 289 | 290 | } 291 | 292 | /** 293 | * Handles persistence (DAO, Cassandra Persistence Adapters, JPA Persistence Adapters) 294 | */ 295 | public interface PersistenceAdapter { 296 | 297 | void save(Object object); 298 | 299 | } 300 | ``` 301 | 302 | **Incorrect:** 303 | 304 | ```java 305 | /** 306 | * Donwloads and sorts the interwebs, all in one method 307 | */ 308 | public class MagicClass { 309 | void doMagic(Object... args) { 310 | //5000 lines here 311 | } 312 | } 313 | ``` 314 | 315 | ### 4.3. Avoid multiple *return* statements 316 | 317 | Multiple *return* statements are hard and time consuming to debug. 318 | 319 | **Correct:** 320 | 321 | ```java 322 | public class StringUtils { 323 | 324 | public static boolean isEmpty(String string) { 325 | return string == null || "".equals(string.trim()); 326 | } 327 | 328 | } 329 | 330 | or 331 | 332 | public class StringUtils { 333 | 334 | public static boolean isEmpty(String string) { 335 | boolean empty = false; 336 | if (string == null) { 337 | empty = true; 338 | } else if ("".equals(string.trim())) { 339 | empty = true; 340 | } 341 | return empty; 342 | } 343 | 344 | } 345 | ``` 346 | 347 | **Incorrect:** 348 | 349 | ```java 350 | public class StringUtils { 351 | 352 | public static boolean isEmpty(String string) { 353 | if (string == null) { 354 | return true; 355 | } else if ("".equals(string.trim())) { 356 | return true; 357 | } 358 | return false; 359 | } 360 | 361 | } 362 | ``` 363 | 364 | ### 4.4. Boolean comparisons 365 | 366 | Mirroring the natural language "if the current state is not active" rather than "if active is not the current state" 367 | 368 | **Correct:** 369 | 370 | ```java 371 | !active 372 | ``` 373 | 374 | **Incorrect:** 375 | 376 | ```java 377 | active == false 378 | ``` 379 | 380 | ### 4.5. *for* loops Vs *for-each* loops 381 | 382 | When itereating over iterable elements where the current index in the iteration is not important for-each loops are preffered. 383 | 384 | **Correct:** 385 | 386 | ```java 387 | for (String name: names) { 388 | doSomething(name); 389 | } 390 | ``` 391 | 392 | **Incorrect:** 393 | 394 | ```java 395 | for (int i = 0; i < names.length; i++) { 396 | doSomething(names[i]); 397 | } 398 | ``` 399 | 400 | ### 4.5. *String* concatenation 401 | 402 | Avoid the use of + or += to concatenate strings. Use java standards designed for that purposes such as String.format, StringBuilder, etc. 403 | 404 | **Correct:** 405 | 406 | ```java 407 | log.debug(String.format("found %s items", amount)); 408 | ``` 409 | 410 | **Incorrect:** 411 | 412 | ```java 413 | log.debug("found " + amount + " items"); 414 | ``` 415 | 416 | ### 4.6. Exceptions 417 | 418 | Don't swallow exception, catch those you can recover or do something about, let the rest reach their destination 419 | 420 | **Correct:** 421 | 422 | ```java 423 | try { 424 | do(); 425 | } catch (SomethingWeCanHandleException ex) { 426 | log.error(ex); 427 | notifyUser(ex); 428 | } finally { 429 | cleanUp(); 430 | } 431 | ``` 432 | 433 | ```java 434 | public void doSomething() throws SomethingSomeoneElseCanHandleException { 435 | } 436 | ``` 437 | 438 | **Incorrect:** 439 | 440 | ```java 441 | try { 442 | do(); 443 | } catch (Throwable ex) { 444 | log.error(ex); 445 | } 446 | ``` 447 | 448 | ```java 449 | try { 450 | do(); 451 | } catch (SomethingWeCanHandleException ex) { 452 | //do nothing 453 | } 454 | ``` 455 | 456 | ### 4.7. Collections 457 | 458 | Use the right collections for the right task. 459 | 460 | **Duplicates** 461 | 462 | * Allows duplicates: [List](http://docs.oracle.com/javase/6/docs/api/java/util/List.html) 463 | * Does Not Allow Duplicates: [Set](http://docs.oracle.com/javase/6/docs/api/java/util/Set.html), [Map](http://docs.oracle.com/javase/6/docs/api/java/util/Map.html) 464 | 465 | **Implementations Iteration Order** 466 | 467 | * [HashSet](http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html) - undefined 468 | * [HashMap](http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html) - undefined 469 | * [LinkedHashSet](http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html) - insertion order 470 | * [LinkedHashMap](http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html) - insertion order of keys 471 | * [ArrayList](http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html) - insertion order 472 | * [LinkedList](http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html) - insertion order 473 | * [TreeSet](http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html) - ascending order (Comparable / Comparator) 474 | 475 | ### 4.8. Raw types 476 | 477 | Avoid using raw types when using classes that support generics. 478 | 479 | **Correct:** 480 | 481 | ```java 482 | List people = Arrays.asList("you", "me"); 483 | ``` 484 | 485 | **Incorrect:** 486 | 487 | ```java 488 | List people = Arrays.asList("you", "me"); 489 | ``` 490 | 491 | ### 4.9. Use of *final* 492 | 493 | When implementing services and classes that are more than javabeans or objects to transfer data between layers make sure you use the 'final' keyword to communicate your intention regarding subclassing, use of constants and values that once set should be immutable. 494 | 495 | ```java 496 | public final class ThisShouldNeverBeExtended { 497 | ... 498 | } 499 | 500 | public final neverOverrideThisMethod() { 501 | } 502 | 503 | private final int thisFielfValueWillNeverChangeOnceSet; 504 | 505 | final int thisLocalVariableValueWillNeverChangeOnceSet = 0; 506 | 507 | ``` 508 | 509 | ### 4.10. Name return values *result* 510 | 511 | Consider using 'result' as the name for the returned variable. This eases the pain when debugging and increases code legibility. 512 | 513 | ```java 514 | public Object doSomething() { 515 | Object result = null; 516 | if (something) { 517 | result = new Object(); 518 | } 519 | return result; 520 | } 521 | ``` 522 | 523 | ### 4.11. Consider setters and getters for field access 524 | 525 | Within the same class consider using getters and setter to access fields values to ensure lazy initialization and other intended logic implemented in getters and setters is always applied. 526 | 527 | **Correct:** 528 | 529 | ```java 530 | public void changeName(String name) { 531 | setName(name); 532 | } 533 | ``` 534 | 535 | **Incorrect:** 536 | 537 | ```java 538 | public void changeName(String name) { 539 | this.name = name; 540 | } 541 | ``` 542 | 543 | ### 4.12. Know your Java 544 | 545 | Spend some time getting to know the [core packages](http://docs.oracle.com/javase/6/docs/api/overview-summary.html) that are already part of the SDK and avoid reinventing the wheel. 546 | 547 | 548 | ## 5. Design Patterns 549 | 550 | Consider the use of common design patterns. 551 | 552 | ### 5.1. Abstract Factory 553 | 554 | Creates or gets an object without knowledge of its implementations, minimizing the refactoring effort and keeping implementations well defined and isolated into their classes. 555 | 556 | ```java 557 | public interface PersistenceAdapter { 558 | ... 559 | } 560 | 561 | public interface CassandraPersistenceAdapter extends PersistenceAdapter { 562 | ... 563 | } 564 | 565 | public interface JPAPersistenceAdapter extends PersistenceAdapter { 566 | ... 567 | } 568 | 569 | public class HibernateJPAPersistenceAdapterImpl implements JPAPersistenceAdapter { 570 | ... 571 | } 572 | 573 | public class HectorCassandraPersistenceAdapterImpl implements CassandraPersistenceAdapter { 574 | ... 575 | } 576 | 577 | //Obtains the current runtime impl for the persistence adapter. 578 | PersistenceAdapter persistenceAdapter = getPersistenceAdapter(); 579 | persistenceAdapter.save(user); 580 | ``` 581 | 582 | ### 5.2. Factory method 583 | 584 | Use static factory methods in objects where you may not create a new instance every time or you can return a subtype of the declared return type 585 | 586 | ```java 587 | Calendar.getInstance(); 588 | ``` 589 | 590 | ### 5.3. Lazy Delegate Wrapper 591 | 592 | When coding classes that represent response objects utilized in Views or other parts of the system where a subset of the properties may not be used consider the use of lazy wrappers with delegates keeping in mind the Serialization requirements. 593 | 594 | ```java 595 | public class UserResponse { 596 | 597 | private User delegate; 598 | 599 | public UserResponse(User delegate) { 600 | this.delegate = delegate; 601 | } 602 | 603 | public String getName() { 604 | return delegate.getName(); 605 | } 606 | 607 | } 608 | ``` 609 | 610 | ### 5.4. Singleton 611 | 612 | Use a singleton to represent a service class where there should be a single instance in the whole system. 613 | There is usually no need for implementing this pattern manually in web and backends where instances are managed by Spring or other IOC container. 614 | 615 | ```java 616 | public class Earth { 617 | 618 | private static Earth instance = new Earth(); 619 | 620 | private Earth() { 621 | } 622 | 623 | public static Earth getInstance() { 624 | return instance; 625 | } 626 | 627 | } 628 | ``` 629 | 630 | ### 5.5. Enums 631 | 632 | Constrain arguments by using type safe enumerations. 633 | 634 | **Correct:** 635 | 636 | ```java 637 | public enum Options { 638 | YES, NO 639 | } 640 | ``` 641 | 642 | **Incorrect:** 643 | 644 | ```java 645 | String yes = "YES"; 646 | String no = "NO"; 647 | ``` 648 | 649 | 650 | ### 5.6. Private Helpers 651 | 652 | Consider private helper methods to break down complex flows and long methods into more readable code. 653 | 654 | **Correct:** 655 | 656 | ```java 657 | public void downloadUrlContents(String url) { 658 | checkIfHostIsReachable(url); 659 | saveContentsToFile(url); 660 | } 661 | ``` 662 | 663 | **Incorrect:** 664 | 665 | ```java 666 | public void downloadUrlContents(String url) { 667 | ... complex code to see if a host is reachable 668 | ... complex code to turn the remote response into bytes and then serialize to disk 669 | } 670 | ``` 671 | 672 | ## 6. Other Java Technologies 673 | 674 | Other Java related technologies along with their specific coding guidelines covered as subsets of this document can be found at: 675 | 676 | * [Spring](java/spring/) 677 | * [Android](java/android/) 678 | 679 | ## 7. Active enforcement 680 | 681 | Java developers at *47 Degrees* are expected to use tools that enforce some of these good practices and quality code in general. 682 | The de facto standard at 47 degrees for coding Java applications is the IDE [IntelliJ IDEA](http://www.jetbrains.com/idea/). Developers that want to further improve their code and have many of the guidelines in this document auto enforced may use [QAPlug](http://qaplug.com/) enabled as plugin within IDEA. 683 | In order to organize methods based on their visibility and name we use [Rearranger](http://plugins.intellij.net/plugin/?id=173). The latest company template to rearrange methods in classes is available for download in this project's [Download](https://github.com/47deg/coding-guidelines/downloads) section 684 | 685 | *47 Degrees* unapologetically favores the use of [IntelliJ IDEA](http://www.jetbrains.com/idea/) and other [products in the Jetbrains family](http://www.jetbrains.com/products.html) as standard tools for coding Java, ObjectiveC and other programming languages utilized at 47 Degrees. -------------------------------------------------------------------------------- /java/android/README.md: -------------------------------------------------------------------------------- 1 | # Android Coding Standards 2 | 3 | The purpose of the [47 Degrees](http://47deg.com) Android Coding Standards is to create a collaboration baseline; helpful for scenarios where many people are creating, modifying, and contributing to the same project. The end goal is unity, consistency, and the notion that a single entity worked on the project. 4 | 5 | This document, expected to be followed by any developers at 47 Degrees, is a subset and complement to the [Java Coding Standards](../). 6 | 7 | **Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)* 8 | 9 | - [Android Coding Standards](#android-coding-standards) 10 | - [1. Naming Conventions](#1-naming-conventions) 11 | - [1.1. Common Resource Files](#11-common-resource-files) 12 | - [1.2. Java Packages & Class Names](#12-java-packages--class-names) 13 | - [1.3. Resource Names](#13-resource-names) 14 | - [1.4. String Resources](#14-string-resources) 15 | - [1.5. Style Resources](#15-style-resources) 16 | - [1.6. Dimen Resources](#16-dimen-resources) 17 | - [2. Conventions for devices 7 inches](#2-conventions-for-devices-7-inches) 18 | 19 | ## 1. Naming Conventions 20 | 21 | Developers should pay special attention to these naming conventions as they differ from those in the standard Java Coding Conventions. 22 | 23 | ### 1.1. Common Resource Files 24 | 25 | The folder *values* will have different files that will store information for our project. 26 | Some of the most common files and their name are 27 | 28 | * **colors.xml**: Colors used in the application 29 | * **config.xml**: Stores information to configure our project (ex. keys for services, urls, etc) 30 | * **dimen.xml**: Dimensions used in application (ex. action bar height , paddings, etc) 31 | * **strings.xml**: Localizable strings 32 | * **plurals.xml**: Plurals. Contains references to strings.xml 33 | * **arrays.xml**: Arrays. Contains references to strings.xml 34 | 35 | ### 1.2. Java Packages & Class Names 36 | 37 | An android App should generally follow the following package structure 38 | 39 | * **com.company.product.android** 40 | - **activities**: All Activities with the word Activity pre-fixed by the Activity name: *[Name]*Activity e.g. MainActivity 41 | - **adapters**: All Adapters with the word Adapter pre-fixed by the Adapter name: *[Name]*Adapter e.g. UserListAdapter 42 | - **services**: All Services including API clients and other persistence related services e.g. UserService 43 | - **components**: All reusable components utilized in Activity and Fragments e.g. UserProfileComponent 44 | - **dialogs**: All Fragment Dialogs with the word Dialog pre-fixed by the dialog name: *[Name]*Dialog e.g. DeleteAccountConfirmationDialog 45 | - **fragments**: All Fragments with the word Fragment pre-fixed by the Fragment name: *[Name]*Fragment e.g. UserMapLocationFragment 46 | - **utils**: All cross package utilities with the word Utils pre-fixed by the Utility name: *[Name]*Utils e.g. StringUtils 47 | 48 | ### 1.3. Resource Names 49 | 50 | The following structure should be followed when naming resoures. 51 | 52 | **group** _ **type** _ **name** _ *[state]* _ *[suffix]* 53 | 54 | * **Group**: Application area or screen. If the resource is used in different parts of applications 'common' should be used instead. e.g. actionbar, menu, media, popup, footer, audio, etc. 55 | * **Type**: Resource Type. e.g. background, icon, button, textfield, list, menuitem, radiobutton, checkbox, tab, dialog, title, etc. 56 | * **Name**: Descriptive name as to what the resource is about. e.g. play, stop. 57 | * **State**: (Optional): The optional state of a parent resource. e.g. A button could be in 'normal', 'pressed', 'disabled' and 'selected'. A checkbox could be 'on' or 'off'. These resources should NEVER be used directly in layout but rather as state selectors. 58 | * **Suffix**: (Optional): An arbitrary suffix that helps to further identify a property of the resource. e.g. bright, dark, opaque, layer. 59 | 60 | Below are some examples of properly named resources. 61 | 62 | * common_background_app 63 | * audio_icon_play_on 64 | * common_icon_preferences 65 | * actionbar_button_send (XML resource) 66 | - action_button_send_normal 67 | - action_button_send_pressed 68 | - action_button_send_disabled 69 | 70 | ### 1.4. String Resources 71 | 72 | String resources placed in xml resources files such as strings.xml, config.xml, etc. are named following the same convention as Java naming conventions for variables and fields. CamelCase with the first letter lowercased. 73 | 74 | Below are some examples of properly named string identifiers. 75 | 76 | * serverApiUrl 77 | * phoneNumber 78 | * services 79 | * url 80 | 81 | ### 1.5. Style Resources 82 | 83 | String resources placed in styles.xml are named in CamelCase. 84 | The following structure should be followed when naming style resoures. 85 | 86 | **[Group]TypeName[Suffix]** 87 | 88 | * **Group** (Optional): Application area or screen. e.g. actionbar, menu, media, popup, footer, audio. 89 | * **Type**: Resource Type. e.g. Background, Icon, Button, Textfield, List, MenuItem, RadioButton, Checkbox, Tab, Dialog. 90 | * **Name**: Descriptive name as to what the resource is about. e.g. play, stop. 91 | * **Suffix**: (Optional): An arbitrary suffix that helps to further identify a property of the resource. e.g. Bright, Dark, Opaque, Layer. 92 | 93 | Below are some examples of properly named string identifiers. 94 | 95 | * ButtonSend 96 | * ActionBarButtonBack 97 | * ListTitle 98 | 99 | ### 1.6. Dimen Resources 100 | 101 | Dimens resources placed in dimen.xml. The following structure should be followed when naming dimentions. 102 | 103 | **property** _ **default** _ **group** _ **type** _ **name** 104 | 105 | * **property**: Type of property reference. e.g. font_size, padding, margin, height, width. 106 | * **default** (Optional): Write "default" if is a general dimen. 107 | * **group** (Optional): Application area or screen. e.g. action_bar, menu, popup, wizard. 108 | * **type** (Optional): Type of resource. e.g. button, title, text, edittext. 109 | * **name** (Optional): Only if is necessary. 110 | 111 | Below are some examples. 112 | 113 | * padding_default 114 | * font_size_action_bar_button 115 | * height_default_action_bar 116 | 117 | We should have some dimension in all projects by default. These are: 118 | 119 | * padding_default 120 | * margin_default 121 | * font_size_default_button 122 | * font_size_default_title 123 | * font_size_default_text 124 | * height_default_action_bar 125 | * font_size_default_action_bar 126 | 127 | ## 2. Conventions for 7" devices 128 | 129 | 7" devices require a special treatment. The problem is that these devices usually use "mdpi" as default density. 130 | 131 | These are the consideration to follow when targeting apps in these devices 132 | 133 | * Copy hdpi drawables to "drawable-sw600dp-mdpi". 134 | * Create a new dimensions file for this screens. The file "dimen.xml" will be in the "values-sw600dp-mdpi" folder. Usually the dimensions will be at 150%. All fonts sizes should be in dimen.xml file as well. 135 | -------------------------------------------------------------------------------- /java/spring/README.md: -------------------------------------------------------------------------------- 1 | # Spring Coding Standards 2 | 3 | The purpose of the [47 Degrees](http://47deg.com) Spring Coding Standards is to create a collaboration baseline; helpful for scenarios where many people are creating, modifying, and contributing to the same project. The end goal is unity, consistency, and the notion that a single entity worked on the project. 4 | 5 | This document, expected to be followed by any developers at 47 Degrees, is a subset and complement to the [Java Coding Standards](../). 6 | 7 | **Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)* 8 | 9 | - [Spring Coding Standards](#spring-coding-standards) 10 | - [1. Configuration](#1-configuration) 11 | - [2. Services](#2-services) 12 | - [3. AOP](#3-aop) 13 | - [4. Spring MVC](#4-spring-mvc) 14 | - [4.1. API's](#41-apis) 15 | - [4.2. Webapps](#42-webapps) 16 | 17 | 18 | ## 1. Configuration 19 | 20 | Spring is the de facto IOC container used at *47 Degrees* for Java server side applications. 21 | Both XML and annotation based configurations are being used. 22 | [XML configuration](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html) is favored for those services and beans that have not originally been annotated with either [@Component](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Component.html), [@Service](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Service.html), [@Controller](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Controller.html)... or that require certain depedencies that are easier to wire via xml. 23 | [Annotations](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-annotation-config) are preffered for Services in local packages and default Service interface implementations for applications that use package scanning to wire and discover the application context. 24 | 25 | ## 2. Services 26 | 27 | Spring services should always be implementations of a Service interface that hides the implementations details when being used in other services dependencies. 28 | Consider the following requirements. 29 | 30 | * The application needs a UserService to manipulate User model beans. 31 | * The User service should hide any dependencies it has in other services or 3rd party technologies. 32 | * The service implementation could be replaced at runtime via Abstract Factories or Injection through service id qualifiers. 33 | 34 | **Correct:** 35 | 36 | ```java 37 | /** 38 | * Defines the contract for the user related operations 39 | * @see User 40 | */ 41 | public interface UserService { 42 | 43 | /** 44 | * Persists a user 45 | * 46 | * @param user the user to be persisted 47 | */ 48 | void save(User user); 49 | 50 | } 51 | 52 | /** 53 | * Implements the UserService utilizing the Persistence Adapter for storage persistence 54 | * @see UserService 55 | */ 56 | @Service 57 | public class LocalUserServiceImpl implements UserService { 58 | 59 | /** 60 | * A storage independent façade for object persistence 61 | */ 62 | @Autowired 63 | private PersistenceAdapter persistenceAdapter; 64 | 65 | /** 66 | * Persists a user 67 | * 68 | * @param user the user to be persisted 69 | */ 70 | @Override 71 | public void save(User user) { 72 | persistenceAdapter.persist(user); 73 | } 74 | 75 | } 76 | ``` 77 | 78 | **Incorrect:** 79 | 80 | ```java 81 | /** 82 | * Utilizes the Persistence Adapter for storage persistence 83 | * @see UserService 84 | */ 85 | @Service 86 | public class UserService { 87 | 88 | /** 89 | * A storage independent façade for object persistence 90 | */ 91 | @Autowired 92 | private PersistenceAdapter persistenceAdapter; 93 | 94 | /** 95 | * Persists a user 96 | * 97 | * @param user the user to be persisted 98 | */ 99 | public void save(User user) { 100 | persistenceAdapter.persist(user); 101 | } 102 | 103 | } 104 | ``` 105 | 106 | ## 3. AOP 107 | 108 | [Spring AOP](http://static.springsource.org/spring/docs/3.0.x/reference/aop.html) is extensively used in server side Java based projects at *47 Degrees*. 109 | Developers should be aware that their method classes and method invokations may be decorated, intercepted, validated and that their service runtime instances may be [proxied](http://static.springsource.org/spring/docs/3.0.x/reference/aop.html#aop-understanding-aop-proxies). This is necessary to implement some of the AOP design patterns that are provided by Spring to such as [Security](http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/access/annotation/Secured.html), [Transactions](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations), Logging, Events, etc. 110 | 111 | The [AspectJ Annotation](http://static.springsource.org/spring/docs/2.5.5/reference/aop.html#aop-ataspectj) style is preffered over other AOP flavors. 112 | 113 | You can find AOP patterns in use across many layers. 114 | 115 | **Security:** 116 | 117 | ```java 118 | @Override 119 | @Secured(SecureRoles.ADMIN) // enforces method access to only admins 120 | public void save(User user) { 121 | ... 122 | } 123 | } 124 | ``` 125 | 126 | **Transactions:** 127 | 128 | ```java 129 | @Override 130 | @Transactional // creates, opens and closes a transaction around this method invokation 131 | public void save(User user) { 132 | ... 133 | } 134 | } 135 | ``` 136 | 137 | **Events** 138 | 139 | ```java 140 | @Override 141 | @EventListener(Events.ON_USER_SAVE_REQUEST) // notifies this method whenever other service invokes eventService.publish(Events.ON_USER_SAVE_REQUEST, user); 142 | public void save(User user) { 143 | ... 144 | } 145 | } 146 | ``` 147 | 148 | **Logging** 149 | 150 | ```java 151 | @Logger //injects the application logger into this service implementation 152 | private Log logger; 153 | ``` 154 | 155 | ## 4. Spring MVC 156 | 157 | Spring MVC is utilized at *47 Degrees* for both building API's and Webapps. 158 | All classes exposed as Web or API controllers should include the [@Controller](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Controller.html) annotation and be configured by using the [@RequestMapping](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/web/bind/annotation/RequestMapping.html) annotations that determine which paths and variables are mapped to methods. 159 | 160 | ### 4.1. API's 161 | 162 | All API's Services should follow the same pattern described in the [Services](#2-services) section. 163 | Below is an example of an API service implementation that exposes a method at http(s)://host/api/vi1/users/{accessToken}/user/{userId}. 164 | 165 | ```java 166 | /** 167 | * Default impl for the UserAPI that maps url requests to methods 168 | */ 169 | @Controller 170 | @RequestMapping("/api/v1/users") 171 | public class UserAPIImpl implements UserAPI { 172 | 173 | @Autowired 174 | private UserService userService; 175 | 176 | /** 177 | * Fetches a user by id 178 | * This handler maps path variables to method arguments and returns a serialized representation of a UserResponse 179 | * 180 | * @param accessToken the requesting user accessToken 181 | * @param userId the id for the user being fetched 182 | */ 183 | @Override 184 | @RequestMapping(value = "/{accessToken:.+}/user/{userId}", method = RequestMethod.GET) 185 | public @ResponseBody UserResponse getAuthenticatedProfile(@PathVariable("accessToken") String accessToken, @PathVariable("userId") String userId) { 186 | User requester = userService.getAccountForToken(accessToken); 187 | User foundUser = userService.getUser(requester, userId); 188 | return new UserResponse(foundUser); 189 | } 190 | } 191 | ``` 192 | 193 | ### 4.2. Webapps 194 | 195 | Webapps controllers do not require to extend from a service interface as they are tightly coupled to the views they handle. 196 | Below is an example of an Web page implementation with its corresponding view 197 | 198 | **Controller** 199 | 200 | ```java 201 | /** 202 | * User page 203 | */ 204 | @Controller 205 | @RequestMapping("/users") 206 | public class UserAPIImpl implements UserAPI { 207 | 208 | @Autowired 209 | private UserService userService; 210 | 211 | /** 212 | * Fetches a user by id 213 | * This handler maps path variables to method arguments and dispatch to the appropiate view setting the user model variable used to render the page 214 | * 215 | * @param accessToken the requesting user accessToken 216 | * @param userId the id for the user being fetched 217 | */ 218 | @Override 219 | @RequestMapping(value = "/{userId}", method = RequestMethod.GET) 220 | public ModelAndView getAuthenticatedProfile(ModelAndView mav, @PathVariable("userId") String userId) { 221 | mav.setViewName("users"); 222 | User foundUser = userService.getUser(userId); 223 | UserResponse userResponse = new UserResponse(foundUser); 224 | mav.addObject("user", userResponse); 225 | return mav; 226 | } 227 | } 228 | ``` 229 | 230 | **View** 231 | 232 | ```jsp 233 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 234 | <%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> 235 | <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 236 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> 237 | 238 | 239 | 240 | 241 | Users 242 | 243 | 244 |

${user.firstName}
245 | 246 | 247 | ``` 248 | --------------------------------------------------------------------------------