@@ -25,8 +25,6 @@ We have a mix of Optional and allowing null values because GraphQL Java was orig
2525
2626We are aiming to not use Optional moving forward in order to be consistent overall.
2727
28-
29-
3028### Unit testing and dependencies
3129All tests are written in [ Spock] ( http://spockframework.org ) .
3230
@@ -80,7 +78,7 @@ Every public data class should be:
8078
8179- Immutable
8280- having a Builder class
83- - having a transform method
81+ - having a ` transform ` method
8482
8583
8684Every data class should be immutable and contain a ` public static class Builder {..} ` with a static factory method ` newFoo ` (not ` newBuilder ` ).
@@ -91,3 +89,98 @@ The class should also contain a `public Foo transform(Consumer<Builder> builderC
9189
9290Private classes should follow the same design, but they don't have to.
9391
92+ ### Default Collections idiom
93+
94+ The default pattern for using Set, Map and List is:
95+ - ` List<Foo> fooList = new ArrayList<>() `
96+ - ` Set<Foo> fooSet = new LinkedHashSet<>() `
97+ - ` Map<Foo> fooMap = new LinkedHashMap<>() `
98+
99+ By using the generic interface instead of using an implementation we are making sure we
100+ don't rely on anything impl specific.
101+ The default implementations for ` Set ` and ` Map ` should be the ` LinkedHashSet ` and ` LinkedHashMap `
102+ because it offers stable iteration order.
103+
104+ ### Stream API vs for, index loop etc
105+ Using the Stream API is ok in general, but it must kept simple. Stream maps inside
106+ maps should be avoided and the inner logic should be refactored into a method.
107+
108+ It also ok to use the traditional for loop or other constructs: sometimes it is more readable than
109+ the modern Stream API. The Stream API is not a replacement for all other loops/iterations.
110+
111+
112+ ### Maximum Indentation is two
113+ One of the most important rules is to keep the number of indentations as low as possible.
114+ In general the max number should be two. This means a for loop inside a condition is ok.
115+ A condition inside a for loop inside a for loop is not.
116+
117+ Extracting a method is the easy way out.
118+
119+ ### Early method exit
120+ Exit the method early to avoid an indentation:
121+
122+ ``` java
123+ public void foo() {
124+ if (cond) {
125+ return ;
126+ }
127+ .. . do something
128+ }
129+ ```
130+ is better than:
131+
132+ ``` java
133+ public void foo() {
134+ if (! cond) {
135+ .. . do something
136+ }
137+ }
138+ ```
139+
140+ ### Maximum line length and multi line statements
141+
142+ We don't have a strict max line length.
143+ But of course every statement should be limited. Not so much in terms of length but much more in terms
144+ of what the statement does.
145+
146+ If a statement is multiple lines long it should be broken down into the same indentation level.
147+
148+ For example this is ok:
149+ ``` java
150+ return myMap
151+ .entrySet()
152+ .stream()
153+ .map(entry - > mapEntry(entry))
154+ .collect(Collectors . toList());
155+ ```
156+ This is not ok:
157+ ``` java
158+ return fooListOfList. stream(). map(
159+ fooList - > fooList. stream()
160+ .sorted((x,y) - > sort(x,y))
161+ .map(foo - > foo. getMyProp())
162+ .collect(toList())
163+ ```
164+ It has a lambda in streams in streams. The inside stream should be extracted in a extra method and each
165+ method call should be on a new line:
166+ ```java
167+ return fooListOfList
168+ .stream()
169+ .map(this :: mapFooList)
170+ .collect(toList());
171+ ```
172+
173+ ### Every class its own file: avoid inner classes and interfaces
174+ Every class/interface should have its one file in general.
175+ Inner classes are almost never ok (especially public ones). Every class should have its own file to make it easier to read and explore the code.
176+
177+ ### Use `graphql.Assert` instead of `Objects`
178+ We maintain our own small set of Assert util methods. Don't use `Objects.requireNonNull` and others in order
179+ to be consistent.
180+
181+ ### `FooEnvironment` method arguments for public API
182+ Don't use specific arguments for interface methods but rather a `FooEnvironment` argument. This ensures future
183+ backwards compatibility when new inputs are added.
184+
185+
186+
0 commit comments