Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala tech talk

Yann Simon
October 07, 2013

Scala tech talk

presentation of the Scala language for Java programmers

Yann Simon

October 07, 2013
Tweet

More Decks by Yann Simon

Other Decks in Programming

Transcript

  1. public String createInvoiceName( Date invoiceDate, String invoiceId, String userId, String

    firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { // ...
  2. String newInvoiceId = invoiceCreator.createInvoiceName( new Date(), // invoiceDate "45AE-45F", //

    invoiceId "872346", // userId "abc-234", // firmId true, // directInvoice false, // firmInvoice false // electronic );
  3. public class NewInvoiceNameCommand { private final Date invoiceDate; private final

    String invoiceId; private final String userId; private final String firmId; private final boolean directInvoice; private final boolean firmInvoice; private final boolean electronic; public NewInvoiceNameCommand( Date invoiceDate, String invoiceId, String userId, String firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { this.invoiceDate = invoiceDate; this.invoiceId = invoiceId; this.userId = userId; this.firmId = firmId; this.directInvoice = directInvoice; this.firmInvoice = firmInvoice; this.electronic = electronic; } public Date getInvoiceDate() { return invoiceDate; } public String getInvoiceId() { return invoiceId; } public String getUserId() { return userId; } public String getFirmId() { return firmId; } public boolean isDirectInvoice() { return directInvoice; } public boolean isFirmInvoice() { return firmInvoice; } public boolean isElectronic() { return electronic; } }
  4. public String createInvoiceName( NewInvoiceNameCommand newInvoiceNameCommand) { // ... return "id";

    } String newInvoiceId = invoiceCreator.createInvoiceName( newInvoiceNameCommand);
  5. public class NewInvoiceNameCommand { public static class NewInvoiceNameCommandBuilder { private

    Date invoiceDate; private String invoiceId; private String userId; private String firmId; private boolean directInvoice; private boolean firmInvoice; private boolean electronic; public NewInvoiceNameCommand build() { return new NewInvoiceNameCommand( invoiceDate, invoiceId, userId, firmId, directInvoice, firmInvoice, electronic); } public NewInvoiceNameCommandBuilder withInvoiceDate(Date invoiceDate) { this.invoiceDate = invoiceDate; return this; } public NewInvoiceNameCommandBuilder withInvoiceId(String invoiceId) { this.invoiceId = invoiceId; return this; } [...] } } private final Date invoiceDate; private final String invoiceId; private final String userId; private final String firmId; private final boolean directInvoice; private final boolean firmInvoice; private final boolean electronic; private NewInvoiceNameCommand( Date invoiceDate, String invoiceId, String userId, String firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { this.invoiceDate = invoiceDate; this.invoiceId = invoiceId; this.userId = userId; this.firmId = firmId; this.directInvoice = directInvoice; this.firmInvoice = firmInvoice; this.electronic = electronic; } public Date getInvoiceDate() { return invoiceDate; } public String getInvoiceId() { return invoiceId; } public String getUserId() { return userId; } public String getFirmId() { return firmId; } public boolean isDirectInvoice() { return directInvoice; } public boolean isFirmInvoice() { return firmInvoice; } public boolean isElectronic() { return electronic; }
  6. NewInvoiceNameCommand newInvoiceNameCommand = new NewInvoiceNameCommand.NewInvoiceNameCommandBuilder() .withInvoiceDate(new Date()) .withInvoiceId("45AE-45F") .withUserId("872346") .withFirmId("abc-234")

    .withDirectInvoice(true) .withFirmInvoice(false) .withElectronic(false) .build(); String newInvoiceId = invoiceCreator.createInvoiceName(newInvoiceNameCommand);
  7. public class NewInvoiceNameCommand { public static class NewInvoiceNameCommandBuilder { private

    Date invoiceDate; private String invoiceId; private String userId; private String firmId; private boolean directInvoice; private boolean firmInvoice; private boolean electronic; public NewInvoiceNameCommandBuilder() { // default values this.directInvoice = true; this.firmInvoice = false; } public NewInvoiceNameCommand build() { return new NewInvoiceNameCommand( invoiceDate, invoiceId, userId, firmId, directInvoice, firmInvoice, electronic); }
  8. public class NewInvoiceNameCommand { public static class NewInvoiceNameCommandBuilder { private

    Date invoiceDate; private String invoiceId; private String userId; private String firmId; private boolean directInvoice; private boolean firmInvoice; private boolean electronic; public NewInvoiceNameCommandBuilder() { // default values this.directInvoice = true; this.firmInvoice = false; } public NewInvoiceNameCommand build() { return new NewInvoiceNameCommand( invoiceDate, invoiceId, userId, firmId, directInvoice, firmInvoice, electronic); } public NewInvoiceNameCommandBuilder withInvoiceDate(Date invoiceDate) { this.invoiceDate = invoiceDate; return this; } public NewInvoiceNameCommandBuilder withInvoiceId(String invoiceId) { this.invoiceId = invoiceId; return this; } public NewInvoiceNameCommandBuilder withUserId(String userId) { this.userId = userId; return this; } public NewInvoiceNameCommandBuilder withFirmId(String firmId) { this.firmId = firmId; return this; } public NewInvoiceNameCommandBuilder withDirectInvoice(boolean directInvoice) { this.directInvoice = directInvoice; return this; } public NewInvoiceNameCommandBuilder withFirmInvoice(boolean firmInvoice) { this.firmInvoice = firmInvoice; return this; } public NewInvoiceNameCommandBuilder withElectronic(boolean electronic) { this.electronic = electronic; return this; } } private final Date invoiceDate; private final String invoiceId; private final String userId; private final String firmId; private final boolean directInvoice; private final boolean firmInvoice; private final boolean electronic; private NewInvoiceNameCommand( Date invoiceDate, String invoiceId, String userId, String firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { this.invoiceDate = invoiceDate; this.invoiceId = invoiceId; this.userId = userId; this.firmId = firmId; this.directInvoice = directInvoice; this.firmInvoice = firmInvoice; this.electronic = electronic; } public Date getInvoiceDate() { return invoiceDate; } public String getInvoiceId() { return invoiceId; } public String getUserId() { return userId; } public String getFirmId() { return firmId; } public boolean isDirectInvoice() { return directInvoice; } public boolean isFirmInvoice() { return firmInvoice; } public boolean isElectronic() { return electronic; } }
  9. def createInvoiceName( invoiceDate: Date, invoiceId: String, userId: String, firmId: String,

    directInvoice: Boolean, firmInvoice: Boolean, electronic: Boolean): String = { // ... }
  10. val newInvoiceId = invoiceCreator.createInvoiceName( new Date, // invoiceDate "45AE-45F", //

    invoiceId "872346", // userId "abc-234", // firmId true, // directInvoice false, // firmInvoice false // electronic )
  11. val newInvoiceId = invoiceCreator.createInvoiceName( invoiceDate = new Date, invoiceId =

    "45AE-45F", userId = "872346", firmId = "abc-234", directInvoice = true, firmInvoice = false, electronic = false )
  12. def createInvoiceName( invoiceDate: Date, invoiceId: String, userId: String, firmId: String,

    directInvoice: Boolean = true, firmInvoice: Boolean = false, electronic: Boolean): String = {
  13. val newInvoiceId = invoiceCreator.createInvoiceName( invoiceDate = new Date, invoiceId =

    "45AE-45F", userId = "872346", firmId = "abc-234", electronic = false )
  14. case class NewInvoiceNameCommand ( invoiceDate: Date, invoiceId: String, userId: String,

    firmId: String, directInvoice: Boolean = true, firmInvoice: Boolean = false, electronic: Boolean )
  15. val newInvoiceNameCommand = NewInvoiceNameCommand ( invoiceDate = new Date, invoiceId

    = "45AE-45F", userId = "872346", firmId = "abc-234", electronic = false ) val newInvoiceId = invoiceCreator.createInvoiceName( newInvoiceNameCommand)
  16. public int multiplyBy2(int number) { return number * 2; }

    [...] public void multiplyUserInputBy2() { Integer userInput = null; multiplyBy2(userInput); }
  17. def multiplyBy2(number: Int): Int = { number * 2 }

    def multiplyUserInputBy2 { //val userInput: Int = null // does not compile //val userInput = Int.unbox(new Integer(null)) throws exception val userInput = 2 multiplyBy2(userInput) }
  18. public class User { private final String name; private final

    String gender; private final Date dateOfBirth; public User(String name, String gender, Date dateOfBirth) { this.name = name; this.gender = gender; this.dateOfBirth = dateOfBirth; } public String getName() { return name; } public String getGender() { return gender; } public Date getDateOfBirth() { return dateOfBirth; } }
  19. public class User { private final String name; private final

    String gender; private final Date dateOfBirth; public User(String name, String gender, Date dateOfBirth) { this.name = name; this.gender = gender; this.dateOfBirth = dateOfBirth; } public String getName() { return name; } public String getGender() { return gender; } public Date getDateOfBirth() { return dateOfBirth; } public Integer getAge() { if (dateOfBirth == null) { return null; } Date now = new Date(); long difference = now.getTime() - dateOfBirth.getTime(); Calendar yearCalculator = Calendar.getInstance(); yearCalculator.setTimeInMillis(difference); return yearCalculator.get(Calendar.YEAR); } }
  20. public class UserBusiness { private final UserRepository userRepository = new

    UserRepository(); public boolean isUserAllowed(String name) { User user = userRepository.findUserByName(name); if (user != null) { if (user.getGender() != null && user.getGender().equals("F")) { if (user.getAge() != null && user.getAge() >= 18) { return true; } } } return false; } }
  21. case class User ( name: String, gender: Option[String] = None,

    dateOfBirth: Option[Date] = None ) { def age: Option[Int] = dateOfBirth.map { dob => calculateAge(dob) } private def calculateAge(dateOfBirth: Date): Int = { val now = new Date() val difference = now.getTime - dateOfBirth.getTime val yearCalculator = Calendar.getInstance() yearCalculator.setTimeInMillis(difference) yearCalculator.get(Calendar.YEAR) } }
  22. class UserBusiness { val userRepository = new UserRepository() def isUserAllowed(name:

    String): Boolean = { val allowedUser = for { user <- userRepository.findUserByName(name) gender <- user.gender if gender == "F" age <- user.age if age >= 18 } yield user allowedUser.isDefined } }
  23. public Promise<JsonNode> searchStock(String query) { Promise<WS.Response> responsePromise = WS.url("http://localhost:9001/search") .setQueryParameter("query",

    query) .get(); return responsePromise.map(new F.Function<WS.Response, JsonNode>() { @Override public JsonNode apply(WS.Response response) throws Throwable { if (response.getStatus() == 200) { JsonNode jsonNode = response.asJson(); return jsonNode.findPath("results"); } else { throw new Exception("Error calling search service.\nResponse status " + response.getStatus() + "\n"); } } }); }
  24. def searchStock(query: String): Future[Seq[JsObject]] = { WS.url("http://localhost:9001/search") .withQueryString("query" -> query)

    .get() .map { response => response.status match { case 200 => (response.json \ "results").as[Seq[JsObject]] case _ => throw new Exception(s"Error calling search service.\nResponse status ${response.status}\n") } } }
  25. public static Promise<Result> index(String userId) { Promise<User> user = backends.getUserById(userId);

    Promise<List<Order>> orders = user.flatMap(new F.Function<User, Promise<List<Order>>>() { @Override public Promise<List<Order>> apply(User user) throws Throwable { return backends.getOrdersForUser(user.getEmail()); } }); Promise<List<Product>> products = orders.flatMap(new F.Function<List<Order>, Promise<List<Product>>>() { @Override public Promise<List<Product>> apply(List<Order> orders) throws Throwable { return backends.getProductsForOrders(orders); } }); Promise<List<Stock>> stocks = products.flatMap(new F.Function<List<Product>, Promise<List<Stock>>>() { @Override public Promise<List<Stock>> apply(List<Product> products) throws Throwable { return backends.getStocksForProducts(products); } }); Promise<List<Object>> promises = Promise.sequence(user, orders, products, stocks); return promises.map(new F.Function<List<Object>, Result>() { @Override public Result apply(List<Object> results) throws Throwable { User user = (User)results.get(0); List<Order> orders = (List<Order>)results.get(1); List<Product> products = (List<Product>)results.get(2); List<Stock> stocks = (List<Stock>)results.get(3); return ok(orders.size() + " order(s) for user " + user.getEmail()); } }); }
  26. def index(userId: String) = Action.async { for { user <-

    getUserById(userId) orders <- getOrdersForUser(user.email) products <- getProductsForOrders(orders) stocks <- getStocksForProducts(products) } yield Ok(s"${orders.size} order(s) for user ${user.email}") }
  27. use this problem as opportunity Ex: “Yes, all of us

    were quite experienced Java programmers. [...] Because we were all learning together, this worked really well.”
  28. test("content disposition parser extracts the filename") { val header =

    "Attachment; filename=example.html" val filename = ContentDispositionHeader.parse(header).filename assert(filename === Some("example.html")) }
  29. it should "replace ä with ae" in { SwiftLatinCharset.from("fooÄfoo") shouldEqual

    "fooAefoo" SwiftLatinCharset.from("fooäfoo") shouldEqual "fooaefoo" }
  30. Build products ✔ efficient development ✔ motivated teams ✔ enable

    SOA (async IO) ✔ less lines of code ✔ easier maintenance