Date post: | 18-Nov-2014 |
Category: |
Technology |
Upload: | lukasz-kuczera |
View: | 2,974 times |
Download: | 0 times |
Clean Code Scala
Scala == Effective Java ?
„Leave camp cleaner than you found it.”
Uncle Bob
Why do we write bad code ???
• Rush (duck tape programmer)• Laziness• Careless• We don’t know how good code looks like• Lack of resources• We like to do new things (create)
„Its harder to read the code
than to write it”
Joel Spolsky
How to improve work quality ?
• Dont give developers money rewardsbigger reward == worse performance
• Let them work on what they like and how they like (Google, Atlassian, Facebook)
• Allow and encourage self improvement
Java dev libraries
• Google Guava• Apache Commons• Spring• Guice• Scala !
Why Scala ?
• More concise• More powerfull• Fun!• Fast• Becoming popular !
Who uses Scala already
Class Parameters - Javapublic class Person {
private String name;private int age;
public Person(String name, int age) {this.name = name;this.age = age;
}public String getName() {
return name;}public void setName(String name) {
this.name = name;}public int getAge() {
return age;}public void setAge(int age) {
this.age = age;}
}
Class Parameters - Scala
class Person(var name: String, var age: Int)
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return String.format("Person: %s age: %s", name, age);
}
@Override
public int hashCode() {
int hashCode = 0;
for(char c: name.toCharArray()) {
hashCode += c;
}
return 11 * hashCode + age;
}
@Override
public boolean equals(Object other) {
if(other == null) return false;
if(other instanceof Person) {
Person person = (Person)other;
return person.name.equals(name) && person.age == age;
}
return false;
}
Scala case class
case class Person(name: String, age: Int)
Dostajemy za darmo: equals(), hashCode() oraz toString() oraz niezmienną klasę (immutable).
To equal or not to equal ? Person p = new Person("Jan Kowalski", 30);
Set<Person> set = new HashSet<Person>();
set.add(p);
System.out.println(set.contains(p));
// true
p.setAge(p.getAge()+1);
System.out.println(set.contains(p));
// false
... WTF ???
To equal or not to equal ?Iterator<Person> it = set.iterator();
boolean containedP = false;
while (it.hasNext()) {
Person nextP = it.next();
if (nextP.equals(p)) {
containedP = true;
break;
}
}
System.out.println(containedP);
// true
// ... ???
Scala Case Classclass Person(val name: String, val age: Int)
object Person {
def apply(name: String, age: Int) = new Person(name, age)
// def hashCode(): Int
// def toString(): String
// def equals(other: Object): Boolean
def unapply(p: Person): Option[(String, Int)]=Some(p.name, p.age)
}
• Extractor
case
Java – working with PersonObject x = new Person("Bill Clinton", 64);
if(x instanceof Person) {
Person p = (Person)x;
System.out.println(„Person name: "+p.getName());
} else {
System.out.println("Not a person");
}
x = "Lukasz Kuczera";
if(x instanceof Person) {
Person p = (Person)x;
System.out.println("hello "+p.getName());
} else if(x instanceof String) {
String s = (String)x;
if(s.equals("Bill Clinton"))
System.out.println("Hello Bill");
else System.out.println("hello: "+s);
} else System.out.println("err, ???");
Scala – Pattern Matchingvar x: Any = Person("Lukasz", 28);
x match {
case Person(name, age) => println("Person name: "+name);
case _ => println("Not a person")
}
x = "Lukasz Kuczera"
x match {
case Person(name, age) => println("Person name: "+name)
case "Bill Clinton" => println("hello Bill")
case s: String => println("hello "+s)
case _ => "err, ???"
}
Person name: Lukaszhello Lukasz Kuczera
Parameter validationpublic class Person {
private String name;private int age;
public Person(String name, int age) {if(name == null) {
throw new NullPointerException();}if(age < 0) {
throw new IllegalArgumentException("Age < 0")}
this.name = name;this.age = age;
}
Parameter validationcase class Person(name: String, age: Int) {
// @elidable(ASSERTION) assert(age > 0, "Age < 0") // by name parameter
}
Working with arraysJava
public class Partition {Person[] all;Person[] adults;Person[] minors; {
ArrayList<Person> minorsList = new ArrayList<Person>();ArrayList<Person> adultsList = new ArrayList<Person>();for(int i=0; i<all.length; i++ ) {(all[i].age<18 ? adultsList: minorsList).add(all[i]);
}minors = (Person[]) minorsList.toArray();adults = (Person[]) adultsList.toArray();
}}
Working with arraysScala
val all: Array[Person]
val (minors, adults) = all.partition(_.age<18)
Null’s – Java
Map<String, String> capitals = new HashMap<String, String>();
capitals.put("Poland", "Warsaw");
System.out.println(capitals.get("Polska").trim());
Exception in thread "main" java.lang.NullPointerException
Null’s - Scala val capitals = Map("Poland" -> "Warsaw"); val capitalOption: Option[String] = capitals.get("Polska") capitalOption match { case Some(value) => println(value) case None => println("Not found") case _ => } if(capitalOption.isDefined) println(capitalOption.get) println(capitalOption getOrElse "Not found")
Scala IO == Java + Commons IOval lines = Source.fromFile("d:\\scala\\MobyDick.txt").getLines;
val withNumbers = lines.foldLeft(List(""))((l,s) => (s.length+" "+s)::l)
println(withNumbers.mkString("\n"))
withNumbers.foreach(println)
withNumbers.filter(!_.startsWith("0")).map(_.toUpperCase).
sort(_.length < _.length).foreach(println)
Scala DI - Cake Patterntrait PersonService {
def findByAge(age: Int): Person
}
trait PersonServiceImpl extends PersonService {
def findByAge(age: Int): Person = new Person("", 12)
}
trait PersonDAO {
def getAll(): Seq[Person]
}
trait PersonDAOImpl extends PersonDAO {
def getAll(): Seq[Person] = List(new Person("", 12))
}
Scala DI - Cake Patterntrait Directory {
self: PersonService with PersonDAO =>
}
class DirectoryComponent extends Directory with PersonServiceImpl with PersonDAOImpl {
}
Guice
• Minimize mutability• Avoid static state• @Nullable