Groovy, to Infinity and Beyond - Groovy/Grails eXchange 2009
Groovy Powered Clean Code
Transcript of Groovy Powered Clean Code
![Page 1: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/1.jpg)
GROOVY POWERED CLEAN CODE
Noam Tenne
![Page 2: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/2.jpg)
$WHOAMI
Developing on the JVM for the past 13 years
codefresh.io
Altogether standup guy
@NoamTenne
blog.10ne.org
![Page 4: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/4.jpg)
CODEFRESH.IOBuild your services as Docker images(You don’t even need a Dockerfile)
![Page 6: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/6.jpg)
“Writing clean code is what you must do in order to call yourself a
professional.”
–Robert C. Martin
http
://w
ww.
amaz
on.co
m/d
p/01
3235
0882
/ref=
cm_s
w_r
_tw
_dp_
GuZ
2wb1
ZS9G
XP
![Page 7: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/7.jpg)
WHICH ONE IS YOUR CODE REVIEW?
![Page 8: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/8.jpg)
IS THIS YOUR REFACTORING SESSION?
![Page 9: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/9.jpg)
MEANINGFUL NAMES
def myItemArrayList = []
![Page 10: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/10.jpg)
FUNCTIONS
breedDogAndPutItThroughAstronautTrainingAndSendItToSpace()
![Page 11: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/11.jpg)
COMMENTS
//Construct object, obviouslydef object = new Obvious()
![Page 12: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/12.jpg)
OBJECTS VS. DATA-STRUCTS
planetSmasher.getPlanetContext().planet = "Earth"planetSmasher.smash()
![Page 13: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/13.jpg)
ERROR HANDLING
catch (Exception e) { //noop}
![Page 14: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/14.jpg)
TESTS
//TODO: Write tests
![Page 15: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/15.jpg)
![Page 16: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/16.jpg)
HUMANS
![Page 17: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/17.jpg)
![Page 18: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/18.jpg)
<ENTER GR8BEER>
![Page 19: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/19.jpg)
WHAT MAKES GROOVY CLEAN?
![Page 20: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/20.jpg)
NATIVE JSON SUPPORT
![Page 21: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/21.jpg)
ScriptEngineManager sem = new ScriptEngineManager();ScriptEngine jse = sem.getEngineByName("javascript"); String script = "Java.asJSONCompatible(" + json + ")"; Object rawJsonObject = javascriptEngine.eval(script);Map contents = (Map) rawJsonObject;
![Page 22: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/22.jpg)
Nashorn?
![Page 23: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/23.jpg)
import groovy.json.JsonSlurper
… def contents = new JsonSlurper().parse(json)
![Page 24: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/24.jpg)
JSON/MARKUP BUILDERS
![Page 25: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/25.jpg)
String html = "<html>";html += "<head>";html += "<title>Noam's guide to Copenhagen</title>";html += "</head>";...html += "</body>";html += "</html>";
![Page 26: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/26.jpg)
![Page 27: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/27.jpg)
new MarkupBuilder(it).html {head {
title("Noam's Guide To Copenhagen")}body {
...}
}
![Page 28: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/28.jpg)
DocumentBuilderFactorydocFactory = DocumentBuilderFactory.newInstance();DocumentBuilder docBuilder =docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();Element rootElement = doc.createElement("gah");doc.appendChild(rootElement);
![Page 29: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/29.jpg)
![Page 30: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/30.jpg)
![Page 31: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/31.jpg)
def xml = new MarkupBuilder()xml.guide(type:"guide"){
title("Noam's Guide To Copenhagen")}
![Page 32: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/32.jpg)
![Page 33: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/33.jpg)
def json = new JsonBuilder()def root = json {
title "Noam's Guide To Copenhagen"}json.toString()
![Page 34: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/34.jpg)
CHECKED EXCEPTIONS
![Page 35: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/35.jpg)
private void readTheStream() {
URI.create("gr8conf.eu").toURL().openStream();
}
throws IOException
![Page 36: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/36.jpg)
private void readTheStream() {
URI.create("gr8conf.eu").toURL().openStream();
}
![Page 37: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/37.jpg)
WHAT MAKES GROOVY REALLY CLEAN?
![Page 38: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/38.jpg)
import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader;… Reader isr = new InputStreamReader(it);
![Page 39: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/39.jpg)
![Page 40: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/40.jpg)
def isr = new InputStreamReader(it);
![Page 41: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/41.jpg)
![Page 42: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/42.jpg)
DEFAULT IMPORTS
import java.lang.*import java.util.*import java.io.*import java.net.*import groovy.lang.*import groovy.util.*import java.math.BigIntegerimport java.math.BigDecimal
![Page 43: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/43.jpg)
import org.slf4j.*import groovy.util.logging.Slf4j@Slf4jclass GroovyDoge { public static void main(String[] args) { log.info "Wow! Much Groovy! So Log!" } }
![Page 44: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/44.jpg)
AST TRANSFORMATION
1. Initialization2. Parsing3. Conversion4. Semantic Analysis 5. Canonicalization6. Instruction Selection7. Class Generation8. Output9. Finalization
![Page 45: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/45.jpg)
List list = []assert list instanceof java.util.ArrayListlist.plus([])
![Page 46: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/46.jpg)
REGISTERED META METHODS
POGO Metaclass
MetaclassRegistry
![Page 47: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/47.jpg)
REGISTERED META METHODS
![Page 48: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/48.jpg)
def fileContents = Paths.get('/path/to/file').text
![Page 49: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/49.jpg)
EXTENSION MODULESclass MyExtension { public static String asString(Integer target) { ... }}
![Page 50: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/50.jpg)
EXTENSION MODULESclass MyExtension { public static String asString(Integer target) { ... }}
Register the class with a descriptor in META-INF/services
![Page 51: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/51.jpg)
EXTENSION MODULESclass MyExtension { public static String asString(Integer target) { ... }}
Register the class with a descriptor in META-INF/services
![Page 52: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/52.jpg)
EXTENSION MODULESclass MyExtension { public static String asString(Integer target) { ... }}
Register the class with a descriptor in META-INF/services
1337.asString()
![Page 53: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/53.jpg)
SCRIPTS
def message = "Much script! Wow! So code!"println message
![Page 54: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/54.jpg)
SCRIPTSimport org.codehaus.groovy.runtime.InvokerHelperclass DogeScript extends Script { def run() { def message = "Much script! Wow! So code!" println message } static void main(String[] args) { InvokerHelper.runScript(DogeScript, args) }}
![Page 55: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/55.jpg)
SCRIPTS
![Page 56: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/56.jpg)
LANGUAGE
![Page 57: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/57.jpg)
QUESTIONS?
![Page 58: Groovy Powered Clean Code](https://reader031.fdocuments.in/reader031/viewer/2022013005/58edb0be1a28ab57088b46df/html5/thumbnails/58.jpg)
TAK!