Вы находитесь на странице: 1из 53

PROGRAMMING IN PAIN

ENNO RUNNE

Wednesday, February 16, 2011


WHAT MAKES ME FEEL PAIN

Coding Scala made me value new things.

I reconsidered old Java truths about what is good code, and I


try to take some of Scala’s goodness home to Java – at the
price of more noise.

Some concepts can’t be translated easily.

Wednesday, February 16, 2011


MANY METHOD ARGUMENTS

Wednesday, February 16, 2011


MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")

Wednesday, February 16, 2011


MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")

Wednesday, February 16, 2011


MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")

p = new Person("Enno", "Runne", city = "Stockholm") Scala

Wednesday, February 16, 2011


MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")

p = new Person("Enno", "Runne", city = "Stockholm") Scala


p = new Builder("Enno", "Runne").city("Stockholm").build();

Wednesday, February 16, 2011


MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")

p = new Person("Enno", "Runne", city = "Stockholm") Scala


p = new Builder("Enno", "Runne").city("Stockholm").build();

rel i eve m y pai n


builders

Wednesday, February 16, 2011


MANY METHOD ARGUMENTS
new Person("Enno", "Runne") Java
new Person("Enno", "Runne", "Sweden")
new Person("Enno", "Runne", "Sweden", "Stockholm")
new Person("Enno", "Runne", null, "Stockholm")

p = new Person("Enno", "Runne", city = "Stockholm") Scala


p = new Builder("Enno", "Runne").city("Stockholm").build();

Wednesday, February 16, 2011


FLUENT INTERFACE

class Builder {
String fn, ln, co, ci;
Java class Person( Scala
val fn: String,

val ln: String,
Builder(String fn, String ln) {
this.fn = fn; val country: String = null,
this.ln = ln; val city: String = null)
}

Person build() {
return new Person(fn, ln, co, ci);
}

Builder city(String ci) {
this.ci = ci;
return this;
}

Builder country(String co) {


this.co = co;
return this;
}

Wednesday, February 16, 2011


FLUENT INTERFACE

class Builder {
String fn, ln, co, ci;
Java class Person( Scala
val fn: String,

val ln: String,
Builder(String fn, String ln) {
this.fn = fn; val country: String = null,
this.ln = ln; val city: String = null)
}

Person build() {
return new Person(fn, ln, co, ci);
}

Builder city(String ci) {
this.ci = ci;
return this;
}

Builder country(String co) {


this.co = co;
return this;
}

Wednesday, February 16, 2011


VARIABLES AND VALUES

Wednesday, February 16, 2011


VARIABLES AND VALUES

var count = 6 variable, multiple assignment Scala

val count = 6 value, single assignment Scala

Wednesday, February 16, 2011


VARIABLES AND VALUES

var count = 6 variable, multiple assignment Scala

val count = 6 value, single assignment Scala

Wednesday, February 16, 2011


VARIABLES AND VALUES

var count = 6 variable, multiple assignment Scala


int count = 6; Java

val count = 6 value, single assignment Scala


final int count = 6; Java

Wednesday, February 16, 2011


VARIABLES AND VALUES

var count = 6 variable, multiple assignment Scala


int count = 6; Java

val count = 6 value, single assignment Scala


final int count = 6; Java

o r d can m i m i c
final keyw
Scala’s val

Wednesday, February 16, 2011


VARIABLES AND VALUES

var count = 6 variable, multiple assignment Scala


int count = 6; Java

val count = 6 value, single assignment Scala


final int count = 6; Java

Wednesday, February 16, 2011


VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:

• no mutable state, convenient • remove all setters


in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD

Wednesday, February 16, 2011


VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:

• no mutable state, convenient • remove all setters


in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD

Wednesday, February 16, 2011


VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:

• no mutable state, convenient • remove all setters


in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD

Wednesday, February 16, 2011


VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:

• no mutable state, convenient • remove all setters


in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD v i ct i o n
d iffere nt co n

Wednesday, February 16, 2011


VALUES AT LARGE
Scala Java
• stresses immutability • JavaBean
standard: get and
set methods for all fields
• can’t accidentally change the
wrong object • easy:

• no mutable state, convenient • remove all setters


in multi-threaded apps
• make fields final
• just as String class in Java,
value objects in DDD

Wednesday, February 16, 2011


SMALL CLASSES

Wednesday, February 16, 2011


SMALL CLASSES
Scala Java
class Xyz(val s: String) public class Xyz {
public final String s;
public Xyz(String s) {
• very little code required this.s = s;
}
• no requirement on matching }
file names
• quite a bit of text
• even several packages in one
file • one public class per file

Wednesday, February 16, 2011


SMALL CLASSES
Scala Java
class Xyz(val s: String) public class Xyz {
public final String s;
public Xyz(String s) {
• very little code required this.s = s;
}
• no requirement on matching }
file names
• quite a bit of text
• even several packages in one
file • one public class per file
o s pl i t c o d e
more work t
into s m aller c la s se s
Wednesday, February 16, 2011
SMALL CLASSES
Scala Java
class Xyz(val s: String) public class Xyz {
public final String s;
public Xyz(String s) {
• very little code required this.s = s;
}
• no requirement on matching }
file names
• quite a bit of text
• even several packages in one
file • one public class per file

Wednesday, February 16, 2011


COLLECTIONS

Wednesday, February 16, 2011


COLLECTIONS

val words = List("one", "two", "three") Scala


val wordsWithTs = words.filter(elem => elem.contains("t"))

Wednesday, February 16, 2011


COLLECTIONS

val words = List("one", "two", "three") Scala


val wordsWithTs = words.filter(elem => elem.contains("t"))

List<String> words = Arrays.asList("one", "two", "three"); Java


List<String> wordsWithTs = new ArrayList<String>();
for (String elem : words) {
if (elem.contains("t")) {
wordsWithTs.add(elem);
}
}

Wednesday, February 16, 2011


COLLECTIONS

val words = List("one", "two", "three") Scala


val wordsWithTs = words.filter(elem => elem.contains("t"))

Wednesday, February 16, 2011


COLLECTIONS

val words = List("one", "two", "three") Scala


val wordsWithTs = words.filter(elem => elem.contains("t"))

List<String> words = Arrays.asList("one", "two", "three"); Java


Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return elem.contains("t");
}
});

Wednesday, February 16, 2011


COLLECTIONS

val words = List("one", "two", "three") Scala


val wordsWithTs = words.filter(elem => elem.contains("t"))

List<String> words = Arrays.asList("one", "two", "three"); Java


Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return elem.contains("t");
}
});

Wednesday, February 16, 2011


COLLECTIONS

val words = List("one", "two", "three") Scala


val wordsWithTs = words.filter(elem => elem.contains("t"))

List<String> words = Arrays.asList("one", "two", "three"); Java


Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return elem.contains("t");
}
}); G o o g le’s G u ava
eases the pain

Wednesday, February 16, 2011


COLLECTIONS

val words = List("one", "two", "three") Scala


val wordsWithTs = words.filter(elem => elem.contains("t"))

List<String> words = Arrays.asList("one", "two", "three"); Java


Collection<String> wordsWithTs = filter(words,
new Predicate<String>() {
(with Google
public boolean apply(String elem) { Guava)
return elem.contains("t");
}
});

Wednesday, February 16, 2011


COMPOSITION

Wednesday, February 16, 2011


COMPOSITION

Scala Java
class A class A
abstract class B abstract class B
trait C interface C
trait D interface D

A extends B A extends B

A extends B with C with D A extends B implements C, D

Wednesday, February 16, 2011


COMPOSITION
Scala
trait HasName {
var name: String = ""
def getName() = name +
getOther()
def getOther(): String
}

Wednesday, February 16, 2011


COMPOSITION
Scala
trait HasName {
var name: String = ""
def getName() = name +
getOther()
def getOther(): String
}

Wednesday, February 16, 2011


COMPOSITION
Scala Java
trait HasName { interface HasName {
var name: String = "" String getName();
def getName() = name + String getOther();
getOther() }
def getOther(): String
} abstract class HasNameImpl
implements HasName {
String name;
public String getName() {
return name + getOther();
}
}

Wednesday, February 16, 2011


COMPOSITION
class User
Scala
extends HasName {
def getOther() = "!"
}

val u = new User


u.name = "name"
u.getName()

Wednesday, February 16, 2011


COMPOSITION
class User
Scala class User implements HasName { Java
extends HasName { HasName outer = this;
HasNameImpl impl = new HasNameImpl() {
def getOther() = "!"
String getOther() {
}
return outer.getOther();
}};
String getName() {
val u = new User return impl.getName();
u.name = "name" }
u.getName() String getOther() { return "!"; }
void setName(String s) { impl.name = s; }
}

User uc = new User();


uc.setName("name");
uc.getName();

Wednesday, February 16, 2011


ADVANCED SWITCH

Wednesday, February 16, 2011


ADVANCED SWITCH
Java
if (o instanceof Xyz) {
doThis();
}
else if (o instanceof Rst) {
doThat();
}

Wednesday, February 16, 2011


ADVANCED SWITCH
Java Java
if (o instanceof Xyz) { catch (Xyz o) {
doThis(); doThis();
} }
else if (o instanceof Rst) { catch (Rst o) {
doThat(); doThat();
} }

Wednesday, February 16, 2011


ADVANCED SWITCH
Java
catch (Xyz o) {
doThis();
}
catch (Rst o) {
doThat();
}

Wednesday, February 16, 2011


ADVANCED SWITCH
Scala Java
catch { catch (Xyz o) {
case o: Xyz => { doThis();
doThis(); }
} catch (Rst o) {
case o: Rst => { doThat();
doThat(); }
}
}

Wednesday, February 16, 2011


ADVANCED SWITCH
Scala
o match {
case o: Xyz => {
doThis();
}
case o: Rst => {
doThat();
}
case "hi" => {
doSomething();
}
}

Wednesday, February 16, 2011


ADVANCED SWITCH
Scala
o match {
case o: Xyz => {
doThis();
}
case o: Rst => {
doThat();
}
case "hi" => {
doSomething();
}
}

Wednesday, February 16, 2011


ADVANCED SWITCH
Scala Java
o match { match(o,
case_instanceOf(Xyz.class,
case o: Xyz => { new Code<String>() {
doThis(); public void run(String obj) {
} doThis(obj);
case o: Rst => { }
}),
doThat(); case_instanceOf(Rst.class,
} new Code<String>() {
case "hi" => { public void run(String obj) {
doThat(obj);
doSomething();
}
} }),
} case_eq("hi",
new Code<String>() {
public void run(String obj) {
doSomething(obj);

Wednesday, February 16, 2011


ADVANCED SWITCH
Scala Java
o match { match(o,
case_instanceOf(Xyz.class,
case o: Xyz => { new Code<String>() {
doThis(); public void run(String obj) {
} doThis(obj);
case o: Rst => { }
}),
doThat(); case_instanceOf(Rst.class,
} new Code<String>() {
case "hi" => { public void run(String obj) {
doThat(obj);
doSomething();
}
} }),
} case_eq("hi",
new Code<String>() {
public void run(String obj) {
doSomething(obj);

Wednesday, February 16, 2011


Wednesday, February 16, 2011
Thank you for listening.
Enno Runne

Wednesday, February 16, 2011


Wednesday, February 16, 2011