Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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

856 views

Published on

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

  • Be the first to comment

  • Be the first to like this

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

×