Skip to content

Commit 695c8e1

Browse files
author
mdodsworth
committed
adding code examples from the book
1 parent f627a16 commit 695c8e1

File tree

347 files changed

+8169
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

347 files changed

+8169
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// code-examples/AdvOOP/objects/PersonUser.java
2+
3+
package objects;
4+
5+
public class PersonUser {
6+
public static void main(String[] args) {
7+
// The following line won't compile.
8+
// Person buck = Person.apply("Buck Trends", 100);
9+
Person buck = PersonFactory.make("Buck Trends", 100);
10+
System.out.println(buck);
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// code-examples/AdvOOP/objects/PersonUserWontCompile.java
2+
// WON'T COMPILE
3+
4+
package objects;
5+
6+
public class PersonUserWontCompile {
7+
public static void main(String[] args) {
8+
Person buck = Person.apply("Buck Trends", 100); // ERROR
9+
System.out.println(buck);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// code-examples/AdvOOP/objects/button-unapply-spec.scala
2+
3+
package objects
4+
import org.specs._
5+
6+
object ButtonUnapplySpec extends Specification {
7+
"Button.unapply" should {
8+
"match a Button object" in {
9+
val b = new Button("click me")
10+
b match {
11+
case Button(label) => label mustEqual "click me"
12+
case _ => fail()
13+
}
14+
}
15+
"match a RadioButton object" in {
16+
val b = new RadioButton(false, "click me")
17+
b match {
18+
case Button(label) => label mustEqual "click me"
19+
case _ => fail()
20+
}
21+
}
22+
"not match a non-Button object" in {
23+
val tf = new TextField("hello world!")
24+
tf match {
25+
case Button(label) => fail()
26+
case x => x must notBeNull // hack to make Specs not ignore this test.
27+
}
28+
}
29+
"extract the Button's label" in {
30+
val b = new Button("click me")
31+
b match {
32+
case Button(label) => label mustEqual "click me"
33+
case _ => fail()
34+
}
35+
}
36+
"extract the RadioButton's label" in {
37+
val rb = new RadioButton(false, "click me, too")
38+
rb match {
39+
case Button(label) => label mustEqual "click me, too"
40+
case _ => fail()
41+
}
42+
}
43+
}
44+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// code-examples/AdvOOP/objects/button.scala
2+
3+
package objects
4+
import ui3.Clickable
5+
6+
class Button(val label: String) extends Widget with Clickable {
7+
8+
def click() = {
9+
// Logic to give the appearance of clicking a button...
10+
}
11+
12+
def draw() = {
13+
// Logic to draw the button on the display, web page, etc.
14+
}
15+
16+
override def toString() = "(button: label="+label+", "+super.toString()+")"
17+
}
18+
19+
object Button {
20+
def unapply(button: Button) = Some(button.label)
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// code-examples/AdvOOP/objects/list-apply-example-script.scala
2+
3+
val list1 = List()
4+
val list2 = List(1, 2.2, "three", 'four)
5+
val list3 = List("1", "2.2", "three", "four")
6+
println("1: "+list1)
7+
println("2: "+list2)
8+
println("3: "+list3)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// code-examples/AdvOOP/objects/list-unapply-example-script.scala
2+
3+
val list = List(1, 2.2, "three", 'four)
4+
list match {
5+
case List(x, y, _*) => println("x = "+x+", y = "+y)
6+
case _ => throw new Exception("No match! "+list)
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// code-examples/AdvOOP/objects/person-factory.scala
2+
3+
package objects
4+
5+
object PersonFactory {
6+
def make(name: String, age: Int) = new Person(name, age)
7+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// code-examples/AdvOOP/objects/person.scala
2+
3+
package objects
4+
5+
class Person(val name: String, val age: Int) {
6+
override def toString = "name: " + name + ", age: " + age
7+
}
8+
9+
object Person {
10+
def apply(name: String, age: Int) = new Person(name, age)
11+
def unapply(person: Person) = Some((person.name, person.age))
12+
13+
def main(args: Array[String]) = {
14+
// Test the constructor...
15+
val person = new Person("Buck Trends", 18)
16+
assert(person.name == "Buck Trends")
17+
assert(person.age == 21)
18+
}
19+
}
20+
21+
object PersonTest {
22+
def main(args: Array[String]) = Person.main(args)
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// code-examples/AdvOOP/objects/radio-button-unapply-spec.scala
2+
3+
package objects
4+
import org.specs._
5+
6+
object RadioButtonUnapplySpec extends Specification {
7+
"RadioButton.unapply" should {
8+
"should match a RadioButton object" in {
9+
val b = new RadioButton(true, "click me")
10+
b match {
11+
case RadioButton(on, label) => label mustEqual "click me"
12+
case _ => fail()
13+
}
14+
}
15+
"not match a Button (parent class) object" in {
16+
val b = new Button("click me")
17+
b match {
18+
case RadioButton(on, label) => fail()
19+
case x => x must notBeNull
20+
}
21+
}
22+
"not match a non-RadioButton object" in {
23+
val tf = new TextField("hello world!")
24+
tf match {
25+
case RadioButton(on, label) => fail()
26+
case x => x must notBeNull
27+
}
28+
}
29+
"extract the RadioButton's on/off state and label" in {
30+
val b = new RadioButton(true, "click me")
31+
b match {
32+
case RadioButton(on, label) => {
33+
label mustEqual "click me"
34+
on mustEqual true
35+
}
36+
case _ => fail()
37+
}
38+
}
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// code-examples/AdvOOP/objects/radio-button.scala
2+
3+
package objects
4+
5+
/**
6+
* Button with two states, on or off, like an old-style,
7+
* channel-selection botton on a radio.
8+
*/
9+
class RadioButton(val on: Boolean, label: String) extends Button(label)
10+
11+
object RadioButton {
12+
def unapply(button: RadioButton) = Some((button.on, button.label))
13+
// equivalent to: = Some(Pair(button.on, button.label))
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// code-examples/AdvOOP/objects/text-field-unapply-spec.scala
2+
package objects
3+
import org.specs._
4+
5+
object TextFieldUnapplySpec extends Specification {
6+
"TextField.unapply" should {
7+
"should match a TextField object" in {
8+
val tf = new TextField("hello world!")
9+
tf match {
10+
case TextField(text) => text mustEqual "hello world!"
11+
case _ => fail()
12+
}
13+
}
14+
"not match a non-TextField object" in {
15+
val b = new Button("click me")
16+
b match {
17+
case TextField(text) => fail()
18+
case x => x must notBeNull
19+
}
20+
}
21+
"extract the text field's text" in {
22+
val tf = new TextField("hello world!")
23+
tf match {
24+
case TextField(text) => text mustEqual "hello world!"
25+
case _ => fail()
26+
}
27+
}
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// code-examples/AdvOOP/objects/text-field.scala
2+
package objects
3+
import ui3.Clickable
4+
5+
class TextField(var text: String) extends Widget with Clickable {
6+
7+
def click() = {
8+
// ... logic to select the appropriate point in the text.
9+
}
10+
11+
def draw() = {
12+
// ... logic to draw the text field on the display, web page, etc.
13+
}
14+
15+
override def toString() = "(textfield: text="+text+", "+super.toString()+")"
16+
}
17+
18+
object TextField {
19+
def unapply(textField: TextField) = Some(textField.text)
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// code-examples/AdvOOP/objects/widget-apply-spec.scala
2+
3+
package objects
4+
import org.specs._
5+
6+
object WidgetApplySpec extends Specification {
7+
"Widget.apply with a valid widget specification string" should {
8+
"return a widget instance with the correct fields set" in {
9+
Widget("(button: label=click me, (Widget))") match {
10+
case Some(w) => w match {
11+
case b:Button => b.label mustEqual "click me"
12+
case x => fail(x.toString())
13+
}
14+
case None => fail("None returned.")
15+
}
16+
Widget("(textfield: text=This is text, (Widget))") match {
17+
case Some(w) => w match {
18+
case tf:TextField => tf.text mustEqual "This is text"
19+
case x => fail(x.toString())
20+
}
21+
case None => fail("None returned.")
22+
}
23+
}
24+
}
25+
"Widget.apply with an invalid specification string" should {
26+
"return None" in {
27+
Widget("(button: , (Widget)") mustEqual None
28+
}
29+
}
30+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// code-examples/AdvOOP/objects/widget.scala
2+
3+
package objects
4+
5+
abstract class Widget {
6+
def draw(): Unit
7+
override def toString() = "(widget)"
8+
}
9+
10+
object Widget {
11+
val ButtonExtractorRE = """\(button: label=([^,]+),\s+\(Widget\)\)""".r
12+
val TextFieldExtractorRE = """\(textfield: text=([^,]+),\s+\(Widget\)\)""".r
13+
14+
def apply(specification: String): Option[Widget] = specification match {
15+
case ButtonExtractorRE(label) => new Some(new Button(label))
16+
case TextFieldExtractorRE(text) => new Some(new TextField(text))
17+
case _ => None
18+
}
19+
}
20+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// code-examples/AdvOOP/observer/button-observer2-spec.scala
2+
3+
package ui
4+
import org.specs._
5+
import observer._
6+
7+
object ButtonObserver2Spec extends Specification {
8+
"An Observer watching a SubjectForReceiveUpdateObservers button" should {
9+
"observe button clicks" in {
10+
val observableButton =
11+
new Button(name) with SubjectForReceiveUpdateObservers {
12+
override def click() = {
13+
super.click()
14+
notifyObservers
15+
}
16+
}
17+
val buttonObserver = new ButtonCountObserver
18+
observableButton.addObserver(buttonObserver)
19+
for (i <- 1 to 3) observableButton.click()
20+
buttonObserver.count mustEqual 3
21+
}
22+
}
23+
"An Observer watching a SubjectForFunctionalObservers button" should {
24+
"observe button clicks" in {
25+
val observableButton =
26+
new Button(name) with SubjectForFunctionalObservers {
27+
override def click() = {
28+
super.click()
29+
notifyObservers
30+
}
31+
}
32+
var count = 0
33+
observableButton.addObserver((button) => count += 1)
34+
for (i <- 1 to 3) observableButton.click()
35+
count mustEqual 3
36+
}
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// code-examples/AdvOOP/observer/observer2.scala
2+
3+
package observer
4+
5+
trait AbstractSubject {
6+
type Observer
7+
8+
private var observers = List[Observer]()
9+
def addObserver(observer:Observer) = observers ::= observer
10+
def notifyObservers = observers foreach (notify(_))
11+
12+
def notify(observer: Observer): Unit
13+
}
14+
15+
trait SubjectForReceiveUpdateObservers extends AbstractSubject {
16+
type Observer = { def receiveUpdate(subject: Any) }
17+
18+
def notify(observer: Observer): Unit = observer.receiveUpdate(this)
19+
}
20+
21+
trait SubjectForFunctionalObservers extends AbstractSubject {
22+
type Observer = (AbstractSubject) => Unit
23+
24+
def notify(observer: Observer): Unit = observer(this)
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// code-examples/AdvOOP/overrides/abs-method-field-class-script.scala
2+
3+
abstract class AbstractParent {
4+
def name: String
5+
}
6+
7+
class ConcreteChild extends AbstractParent {
8+
val name = "Child"
9+
}
10+
11+
println(new ConcreteChild().name) // => "Child"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// code-examples/AdvOOP/overrides/abs-method-field-trait-script.scala
2+
3+
trait AbstractNameTrait {
4+
def name: String
5+
}
6+
7+
class ConcreteNameClass extends AbstractNameTrait {
8+
val name = "ConcreteNameClass"
9+
}
10+
11+
println(new ConcreteNameClass().name) // => "ConcreteNameClass"

0 commit comments

Comments
 (0)