Java design patterns in
Scala
Radim Pavlicek
About me
● Java/Scala developer
● bogey golfer
● piano player
Agenda
Part I - OO Patterns
Functional Interface
Command
Builder
Iterator
Template method
Strategy
Null Object
Functional Interface
encapsulate a bit of program logic and treated
like any other first-class construct
Java
Collections.sort(people,
new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return p1.getFirstName...
Java
other use-cases
● runnable
● callable
Java 8 has solved
Scala
people.sortWith(
(p1, p2) => p1.firstName < p2.firstName
)
Command
Turn a method invocation into an object
and execute it in a central location
Java
public class PrintCommand implements Runnable {
private final String s;
PrintCommand(String s) { this.s = s; }
public...
Scala
object Invoker {
private var history: Seq[() => Unit] = Seq.empty
def invoke(command: => Unit) { // by-name paramete...
Scala advanced
def makePurchase(register: CaschRegister, amount: Int) =
{
() = {
println("Purchase in amount: " + amount)
...
Builder
to create an immutable object using a friendly
syntax
Java
Issues
● constructor arguments
Person(String n,String n2,String nick
● Defaults (telescoping constructor problem)
Per...
Java code
public class ImmutablePerson {
private final String firstName;
public String getFirstName() {
return firstName;}...
Scala - Case Class
case class Person {
firstName: String,
LastName: String,
nick: String = "")
val p = Person(firstName = ...
Scala - Tuples
● for explorative development
def p = (“Radim”, “Pavlicek”)
p._1 // Radim
p._2 // Pavlicek
Iterator
iterate through the elements of a sequence
without having to index into it
Java
public Set<Char> vowelsCount(String s) {
Set<Char> l = new HashSet<Char>();
for (Char c : s.toLowerCase().toCharArray...
Scala
● filter
● map
● reduce
Scala filter
filtering certain elements from collection
def vowelsNumber(word : String) =
word.filter(isVowel).toSet
vowel...
Scala map
function is applied to each element
def prependHello(names : Seq[String]) =
names.map((name) => “Hello, “ + name)
Scala reduce
reduce sequence to a single value
def sum(sq : Seq[Int]) =
if (sq.isEmpty) 0
else
sq.reduce((acc,curr) => acc...
Scala comprehensions
● guard
for (a <- list if isEven(a))
● pattern matching
for (Person(name, address) <- people)
● still...
Scala for comprehensions
case class Person(name: String, addr: Address)
case class Address(zip: Int)
def greetings(people:...
Template method
defines the program skeleton of an algorithm in
a method, called template method, which defers
some steps ...
Java
public abstract class Template {
public void doStuff() {
beforeStuff(); afterStuff();
}
protected abstract void befor...
Scala Function Builder
def doStuff(
beforeStuff: () => Unit,
afterStuff: () => Unit) =
() = {
beforeSuff()
afterStuff()
}
Scala Function Builder
def beforeStuff() = Console.println(“before”)
def afterStuff() = Console.println(“after”)
val test=...
Strategy
define an algorithm in abstract terms and make
it interchangeable within family
Java
public interface Strategy {
int compute(int a, int b);
}
public class Add implements Strategy {
public int compute(in...
Scala
define type alias and use first-class functions
type Strategy = (Int, Int) => Int
class Context(computer: Strategy) ...
Null Object
avoid null checks in code and
centralize logic that deals with handling the
absence of a value
Java
class NullPerson extends Person {....}
public Person build(String first, String last) {
if (first == null || last == ...
Scala
val nullPerson = Person() // case class
def build(first: Option[String],
last: Option[String]) =
(for (f <- first; l...
Decorator
add behaviour to an existing class
aka “there is a bug in the API class”
Java
public interface OutputStream {
void write(byte b);
void write(byte[] b);
}
public class FileOutputStream implements ...
Scala
def add(a: Int, b: Int) = a + b
def decorateLogger(calcF: (Int, Int) => Int) =
(a: Int, b: Int) => {
val result = ca...
Scala
val loggingAdd = decorateLogger(add)
scala> loggingAdd(1,4)
Result is 5
Sources
http://pavelfatin.com/design-patterns-in-scala
Upcoming SlideShare
Loading in …5
×

Java patterns in Scala

765 views

Published on

Java patters in Scala, decorator, command, builder, iterator, strategy, null object

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
765
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Java patterns in Scala

  1. 1. Java design patterns in Scala Radim Pavlicek
  2. 2. About me ● Java/Scala developer ● bogey golfer ● piano player
  3. 3. Agenda
  4. 4. Part I - OO Patterns Functional Interface Command Builder Iterator Template method Strategy Null Object
  5. 5. Functional Interface encapsulate a bit of program logic and treated like any other first-class construct
  6. 6. Java Collections.sort(people, new Comparator<Person>() { public int compare(Person p1, Person p2) { return p1.getFirstName().compareTo( ps.getFirstName()) } })
  7. 7. Java other use-cases ● runnable ● callable Java 8 has solved
  8. 8. Scala people.sortWith( (p1, p2) => p1.firstName < p2.firstName )
  9. 9. Command Turn a method invocation into an object and execute it in a central location
  10. 10. Java public class PrintCommand implements Runnable { private final String s; PrintCommand(String s) { this.s = s; } public void run() { System.out.println(s); } } public class Invoker { private final List<Runnable> history = new ArrayList<>(); void invoke(Runnable command) { command.run(); history.add(command); } } Invoker invoker = new Invoker(); invoker.invoke( new PrintCommand( "Scala")); invoker.invoke( new PrintCommand( "Vienna"));
  11. 11. Scala object Invoker { private var history: Seq[() => Unit] = Seq.empty def invoke(command: => Unit) { // by-name parameter command history :+= command _ } } Invoker.invoke(println( "foo"))
  12. 12. Scala advanced def makePurchase(register: CaschRegister, amount: Int) = { () = { println("Purchase in amount: " + amount) register.addCash(amount) } } // how to create purchase functions using closure
  13. 13. Builder to create an immutable object using a friendly syntax
  14. 14. Java Issues ● constructor arguments Person(String n,String n2,String nick ● Defaults (telescoping constructor problem) Person() Person(String name) Person(String name, String name2)...
  15. 15. Java code public class ImmutablePerson { private final String firstName; public String getFirstName() { return firstName;} private ImmetablePerson(Builder builder) { firstName = builder.firstName; } public static Builder newBuilder() { return new Builder(); } } public static class Builder { private String firstName; public Builder withFirstName(String firstName) { this.firstName = firstName; return this; } public ImmutablePerson build () { return new ImmutablePerson(this); } }
  16. 16. Scala - Case Class case class Person { firstName: String, LastName: String, nick: String = "") val p = Person(firstName = “Radim”, lastName = “Pavlicek”) val cloneMe = Person(firstName = “Radim”, lastName = “Pavlicek”) p.equals(cloneMe) // true val brother = p.copy(firstName = “Libor”) // Libor Pavlicek p.toString // Person[firstName=”Radim”, lastName= “Pavlicek”]
  17. 17. Scala - Tuples ● for explorative development def p = (“Radim”, “Pavlicek”) p._1 // Radim p._2 // Pavlicek
  18. 18. Iterator iterate through the elements of a sequence without having to index into it
  19. 19. Java public Set<Char> vowelsCount(String s) { Set<Char> l = new HashSet<Char>(); for (Char c : s.toLowerCase().toCharArray()) if (isVowel(c)) l.add(c) }
  20. 20. Scala ● filter ● map ● reduce
  21. 21. Scala filter filtering certain elements from collection def vowelsNumber(word : String) = word.filter(isVowel).toSet vowelsNumber(“Radim”) // Set(‘a’, ‘i’)
  22. 22. Scala map function is applied to each element def prependHello(names : Seq[String]) = names.map((name) => “Hello, “ + name)
  23. 23. Scala reduce reduce sequence to a single value def sum(sq : Seq[Int]) = if (sq.isEmpty) 0 else sq.reduce((acc,curr) => acc + curr)
  24. 24. Scala comprehensions ● guard for (a <- list if isEven(a)) ● pattern matching for (Person(name, address) <- people) ● still no mutable state
  25. 25. Scala for comprehensions case class Person(name: String, addr: Address) case class Address(zip: Int) def greetings(people: Seq[Person]) = for (Person(name, address) <- people if isCloseZip(address.zip) ) yield “Hello, %s”.format(name)
  26. 26. Template method defines the program skeleton of an algorithm in a method, called template method, which defers some steps to subclasses
  27. 27. Java public abstract class Template { public void doStuff() { beforeStuff(); afterStuff(); } protected abstract void beforeStuff(); protected abstract void afterStuff(); }
  28. 28. Scala Function Builder def doStuff( beforeStuff: () => Unit, afterStuff: () => Unit) = () = { beforeSuff() afterStuff() }
  29. 29. Scala Function Builder def beforeStuff() = Console.println(“before”) def afterStuff() = Console.println(“after”) val test= doStuff(beforeStuff, afterStuff) scala> test
  30. 30. Strategy define an algorithm in abstract terms and make it interchangeable within family
  31. 31. Java public interface Strategy { int compute(int a, int b); } public class Add implements Strategy { public int compute(int a, int b) { return a + b; } } public class Multiply implements Strategy { public int compute(int a, int b) { return a * b; } } public class Context { private final Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void use(int a, int b) { strategy.compute(a, b); } } new Context(new Multiply()).use(2, 3);
  32. 32. Scala define type alias and use first-class functions type Strategy = (Int, Int) => Int class Context(computer: Strategy) { def use(a: Int, b: Int) { computer(a, b) } } val add: Strategy = _ + _ val multiply: Strategy = _ * _ new Context(multiply).use( 2, 3)
  33. 33. Null Object avoid null checks in code and centralize logic that deals with handling the absence of a value
  34. 34. Java class NullPerson extends Person {....} public Person build(String first, String last) { if (first == null || last == null) return new NullPerson(); return new Person (first, last); }
  35. 35. Scala val nullPerson = Person() // case class def build(first: Option[String], last: Option[String]) = (for (f <- first; l <- last) yield Person(f, l) ).getOrElse(nullPerson)
  36. 36. Decorator add behaviour to an existing class aka “there is a bug in the API class”
  37. 37. Java public interface OutputStream { void write(byte b); void write(byte[] b); } public class FileOutputStream implements OutputStream { /* ... */ } public abstract class OutputStreamDecorator implements OutputStream { protected final OutputStream delegate; protected OutputStreamDecorator(OutputStream delegate) { this.delegate = delegate; } public void write(byte b) { delegate.write(b); } public void write(byte[] b) { delegate.write(b); } }
  38. 38. Scala def add(a: Int, b: Int) = a + b def decorateLogger(calcF: (Int, Int) => Int) = (a: Int, b: Int) => { val result = calcF(a, b) println(“Result is: “ + result) // here it comes result }
  39. 39. Scala val loggingAdd = decorateLogger(add) scala> loggingAdd(1,4) Result is 5
  40. 40. Sources http://pavelfatin.com/design-patterns-in-scala

×