in practice scala
play

in Practice Scala patric.fornasier@thoughtworks.com - PowerPoint PPT Presentation

in Practice Scala patric.fornasier@thoughtworks.com marc.hofer@thoughtworks.com e c n e i r e p x E Optimising IT n g i s e D Organisations Consulting Build & Release Management technology esting T Offices 2 Warning


  1. in Practice Scala patric.fornasier@thoughtworks.com marc.hofer@thoughtworks.com

  2. e c n e i r e p x E Optimising IT n g i s e D Organisations Consulting Build & Release Management technology esting T

  3. Offices 2

  4. Warning presentation Contains code examples

  5. A bit of Context about the project

  6. Why Scala ?

  7. Scala ? What is

  8. Functional Object Oriented Scala Scriptable Statically JVM- Typed based

  9. Scala Compile Byte Code JVM

  10. Benefits

  11. “Functional Programming”

  12. List<String> features = Arrays.asList("noFeature", "featureC", "featureB", "featureA"); for (String feature : features) { System.out.println(feature); }

  13. List<String> javaFeatures = Arrays.asList("noFeature", "featureC", "featureB", "featureA"); for (String feature : javaFeatures) { System.out.println(feature); } val scalaFeatures = List( "noFeature", "featureC", "featureB", "featureA") scalaFeatures foreach { println _ }

  14. val currentFeatures = List("noFeature", "featureC", "featureB", "featureA") Result: "featureA_toggle, featureB_toggle" currentFeatures.filter { _.startsWith("feature") } .sorted .take(2) ? .map { _ + "_toggle" } .mkString(", ")

  15. String result = ""; List<String> currentFeatures = Arrays.asList("noFeature", "featureC", "featureB", "featureA"); Collections.sort(currentFeatures); int i = 0, j = 0, take = 2; while(i < take && j < currentFeatures.size()) { String feature = currentFeatures.get(j++); if(feature.startsWith("feature")) { result += feature + "_toggle" + ((i++ != take) ? ", " : ""); } } currentFeatures.filter { _.startsWith("feature") } .sorted .take(2) .map { _ + "_toggle" } .mkString(", ")

  16. “Less Boilerplate”

  17. public class Property {}

  18. class Property {}

  19. public class Property { private final String key; private final String value; private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; } }

  20. class Property(key: String, value: String, default: String) {}

  21. public class Property { // ... public String getKey() { return key; } public String getValue() { return value; } public String getDefaultValue() { return defaultValue; } }

  22. class Property(val key: String, val value: String, val default: String) {}

  23. public class Property { // ... public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); } @Override public String toString() { return String.format("%s=%s", key, value); } }

  24. class Property(val key: String, val value: String, val default: String) { def changeTo(newValue: String) = new Property(key, newValue, default) def reset = new Property(key, default) override def toString = "%s=%s" format(key, value) }

  25. public class Property { // ... @Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; } }

  26. case class Property(key: String, value: String, default: String) { def changeTo(newValue: String) = Property(key, newValue, default) def reset = Property(key, default) override def toString = "%s=%s" format(key, value) }

  27. public class Property { private final String key; private final String value; private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; } public String getKey() { return key; } public String getValue() { return value; } public String getDefaultValue() { return defaultValue; } public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); } @Override public String toString() { return String.format("%s=%s", key, value); } @Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; } }

  28. case class Property(key: String, value: String, default: String) { def changeTo(newValue: String) = Property(key, newValue, default) def reset = Property(key, default) override def toString = "%s=%s" format(key, value) }

  29. case class Property(key: String, value: String, default: String) { public class Property { def changeTo(newValue: String) = Property(key, newValue, default) def reset = Property(key, default) private final String key; override def toString = "%s=%s" format(key, value) private final String value; } private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; } 45 vs 5 public String getKey() { return key; } public String getValue() { return value; } s C O L public String getDefaultValue() { return defaultValue; } public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); } @Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; } @Override public String toString() { return String.format("%s=%s", key, value); } } * ignoring blank lines

  30. “Less Boilerplate” Another Example: { Blocks }

  31. int statusCode = httpSupport.get("http://foo.com", new Block<Integer>() { public Integer execute(HttpResponse response) { return response.getStatusLine().getStatusCode()); } }); String content = httpSupport.get("http://foo.com", new Block<String>() { public Integer execute(HttpResponse response) { return EntityUtils.toString(response.getEntity()); } }); httpSupport.get("http://foo.com", new VoidBlock() { public void execute(HttpResponse response) {} }); val statusCode = get("http://foo.com") { statusCode } val content = get("http://foo.com") { toString } get("http://foo.com")

  32. “Java Compatibility”

  33. java -cp "lib/*" com.springer.core.app.Casper Scala library goes in here!

  34. val java = new java.util.ArrayList[String] val scala: Seq[String] = foo filter { ... }

  35. val log = Logger.getLogger("com.foo") log.debug("Hello!")

  36. Library JVM re-use “Gentle Learning Curve” “Java without ;”

  37. <XML-Support/>

  38. <PdfInfo hasAccess="false"> val pdfInfo = <DDSId>12345</DDSId> <ContentType>Article</ContentType> </PdfInfo> val contentType = (pdfInfo \ "ContentType").text val hasAccess = (pdfInfo \ "@hasAccess").text.toBoolean

  39. val pdfInfoList = <PdfInfoList> <PdfInfo hasAccess="false"> <DDSId>12345</DDSId> <ContentType>Article</ContentType> </PdfInfo> <PdfInfo hasAccess="true"> <DDSId>54321</DDSId> <ContentType>Book</ContentType> </PdfInfo> </PdfInfoList> case class PdfInfo(xml: NodeSeq) { val ddsId = (xml \ "DDSId").head.text val hasAccess = (xml \ "@hasAccess").head.text val contentType = (xml \ "ContentType").head.text } (pdfInfoList \ "PdfInfo") map { PdfInfo(_) }

  40. “DSL- Friendly”

  41. Levels of Testing System Functional Unit App2 App1 Integration DB App3

  42. Unit Test DSL class PropertyTest extends Spec with ShouldMatchers { it("should render key and value separated with an equals sign") { Property("shark", "fish").toString should equal ("shark=fish") } }

  43. Functional Test DSL class ForgottenPasswordPageTests extends FunctionalTestSpec with ForgottenPasswordSteps with Uris { it("should validate user email") { given(iNavigateTo(ForgottenPasswordPage)) when(iSubmitEmail("invalid@email.com")) then(iShouldSeeInvalidEmailErrorMessage) } }

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend