├── .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 |
--------------------------------------------------------------------------------