Skip to content

Commit 66afa4a

Browse files
alvinjb-studios
authored andcommitted
Small edits while reviewing a comment by Vinz
1 parent d6e14d1 commit 66afa4a

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

_overviews/scala3-book/domain-modeling-tools.md

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ next-page: domain-modeling-oop
88
---
99

1010

11-
Scala 3 provides us with many different tools to model the world around us:
11+
Scala 3 provides many different constructs so we can model the world around us:
1212

1313
- Classes
1414
- Objects
@@ -32,8 +32,9 @@ class Person(var name: String, var vocation: String)
3232
class Book(var title: String, var author: String, var year: Int)
3333
class Movie(var name: String, var director: String, var year: Int)
3434
```
35-
The examples above show that Scala has a very lightweight way to declare classes.
36-
The definition of the class `Person` roughly corresponds to the following, more explicit, version
35+
36+
These examples show that Scala has a very lightweight way to declare classes.
37+
The definition of the class `Person` roughly corresponds to the following, more explicit, version:
3738

3839
```scala
3940
class Person:
@@ -49,7 +50,8 @@ class Person:
4950
name = _name
5051
vocation = _vocation
5152
```
52-
defining the two fields `name` and `vocation` together with a constructor that accepts values for the two fields and assigns them.
53+
54+
This version defines the two fields `name` and `vocation`, together with a constructor that accepts values for those two fields and assigns them.
5355

5456
All of the parameters of our example classes are defined as `var` fields, which means they are mutable: you can read them, and also modify them.
5557
If you want them to be immutable---read only---create them as `val` fields instead.
@@ -67,7 +69,7 @@ However, with [creator applications][creator] this isn’t required in Scala 3:
6769
val p = Person("Robert Allen Zimmerman", "Harmonica Player")
6870
```
6971

70-
Once you have an instance of a class, you can access its fields, which in this example are all constructor parameters:
72+
Once you have an instance of a class such as `p`, you can access its fields, which in this example are all constructor parameters:
7173

7274
```scala
7375
p.name // "Robert Allen Zimmerman"
@@ -227,7 +229,7 @@ This is shown in the previous `Socket` example.
227229

228230
An object is a class that has exactly one instance.
229231
It’s initialized lazily when its members are referenced, similar to a `lazy val`.
230-
Objects in Scala allow grouping methods and fields under one namespace, similar to how can use `static` members on a class in Java, Javascript (ES6) or `@staticmethod` in Python.
232+
Objects in Scala allow grouping methods and fields under one namespace, similar to how you use `static` members on a class in Java, Javascript (ES6), or `@staticmethod` in Python.
231233

232234
Declaring an `object` is similar to declaring a `class`.
233235
Here’s an example of a “string utilities” object that contains a set of methods for working with strings:
@@ -245,11 +247,22 @@ We can use the object as follows:
245247
StringUtil.truncate("Chuck Bartowski", 5) // "Chuck"
246248
```
247249

248-
Importing in Scala is very flexible and allows us to import all members of an object:
250+
Importing in Scala is very flexible, and allows us to import _all_ members of an object:
249251

250252
```scala
251253
import StringUtils._
252-
truncate("Chuck Bartowski", 5) // "Chuck"
254+
truncate("Chuck Bartowski", 5) // "Chuck"
255+
containsWhitespace("Sarah Walker") // true
256+
isNullOrEmpty("John Casey") // false
257+
```
258+
259+
or just _some_ members:
260+
261+
```scala
262+
import StringUtils.{truncate, containsWhitespace}
263+
truncate("Charles Carmichael", 7) // "Charles"
264+
containsWhitespace("Captain Awesome") // true
265+
isNullOrEmpty("Morgan Grimes") // Not found: isNullOrEmpty (error)
253266
```
254267

255268
Objects can also contain fields, which are also accessed like static members:
@@ -266,7 +279,7 @@ println(MathConstants.PI) // 3.14159
266279

267280
## Companion objects
268281

269-
An `object` that has the same name as a class, and is declared in the same file as the class, is called a _"companion object"_.
282+
An `object` that has the same name as a class, and is declared in the same file as the class, is called a _"companion object_."
270283
Similarly, the corresponding class is called the object’s companion class.
271284
A companion class or object can access the private members of its companion.
272285

@@ -287,7 +300,7 @@ circle1.area
287300
```
288301

289302
In this example the `area` method that’s available to each instance uses the `calculateArea` method that’s defined in the companion object.
290-
If you’re familiar with Java, `calculateArea` is similar to a static method.
303+
Once again, `calculateArea` is similar to a static method in Java.
291304
Also, because `calculateArea` is private, it can’t be accessed by other code, but as shown, it can be seen by instances of the `Circle` class.
292305

293306
### Other uses
@@ -300,7 +313,7 @@ Companion objects can be used for several purposes:
300313
- They can contain `apply` methods, which---thanks to some syntactic sugar---work as factory methods to construct new instances
301314
- They can contain `unapply` methods, which are used to deconstruct objects, such as with pattern matching
302315

303-
Here’s a quick look at how `apply` methods that can be used as factory methods to create new objects:
316+
Here’s a quick look at how `apply` methods can be used as factory methods to create new objects:
304317

305318
```scala
306319
class Person:
@@ -436,8 +449,8 @@ class Dog(name: String, var age: Int) extends Pet(name):
436449

437450
val d = Dog("Fido", 1)
438451
```
439-
Traits are more flexible to compose (you can mix in multiple traits, but only extend one class) and should most of the time be preferred to classes.
440-
The rule of thumb is to use classes whenever you want to create instances of a particular type and traits when you want to decompose and reuse behaviour.
452+
Traits are more flexible to compose --- you can mix in multiple traits, but only extend one class --- and should be preferred to classes and abstract classes most of the time.
453+
The rule of thumb is to use classes whenever you want to create instances of a particular type, and traits when you want to decompose and reuse behaviour.
441454

442455

443456
## Enums
@@ -466,7 +479,7 @@ import CrustSize._
466479
val currentCrustSize = Small
467480
```
468481

469-
Enum values can be compared using equals (`==`) and matched on:
482+
Enum values can be compared using equals (`==`), and also matched on:
470483

471484
```scala
472485
// if/then
@@ -529,11 +542,11 @@ The section on [algebraic datatypes][adts] and the [reference documentation][ref
529542
## Case classes
530543

531544
Case classes are used to model immutable data structures.
532-
Take the following example,
545+
Take the following example:
533546
```scala
534547
case class Person(name: String, relation: String)
535548
```
536-
Since we declared `Person` as a case class, the fields `name` and `relation` are public and immutable by default.
549+
Since we declare `Person` as a case class, the fields `name` and `relation` are public and immutable by default.
537550
We can create instances of case classes as follows:
538551
```scala
539552
val christina = Person("Christina", "niece")
@@ -544,9 +557,9 @@ christina.name = "Fred" // error: reassignment to val
544557
```
545558
Since the fields of a case class are assumed to be immutable, the Scala compiler can generate many helpful methods for you:
546559
* An `unapply` method is generated, which allows you to perform pattern matching on a case class (that is, `case Person(n, r) => ...`).
547-
* A `copy` method is generated in the class, which is very useful to create modified copies of an instance
560+
* A `copy` method is generated in the class, which is very useful to create modified copies of an instance.
548561
* `equals` and `hashCode` methods using structural equality are generated, allowing you to use instances of case classes in `Map`s.
549-
* A default `toString` method is generated, which is helpful for debugging
562+
* A default `toString` method is generated, which is helpful for debugging.
550563

551564
These additional features are demonstrated in the below example:
552565
```scala
@@ -576,8 +589,8 @@ As mentioned, case classes support functional programming (FP):
576589

577590
- In FP you try to avoid mutating data structures.
578591
It thus makes sense that constructor fields default to `val`.
579-
Since instances of case classes are not changed, they can easily be shared without fearing mutation or race conditions.
580-
- Instead of mutating one instance, you can use the `copy` method as a template to create a new (potentially changed) instance.
592+
Since instances of case classes can’t be changed, they can easily be shared without fearing mutation or race conditions.
593+
- Instead of mutating an instance, you can use the `copy` method as a template to create a new (potentially changed) instance.
581594
This process can be referred to as “update as you copy.”
582595
- Having an `unapply` method auto-generated for you also lets case classes be used in advanced ways with pattern matching.
583596

@@ -621,7 +634,7 @@ case Teacher(name, whatTheyTeach) =>
621634
```
622635

623636
Those patterns work because `Student` and `Teacher` are defined as case classes that have `unapply` methods whose type signature conforms to a certain standard.
624-
Technically, the specific type of pattern matching shown in these examples is known as a *constructor pattern*.
637+
Technically, the specific type of pattern matching shown in these examples is known as a _constructor pattern_.
625638

626639
> The Scala standard is that an `unapply` method returns the case class constructor fields in a tuple that’s wrapped in an `Option`.
627640
> The “tuple” part of the solution was shown in the previous lesson.

0 commit comments

Comments
 (0)