Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
% Business Domain Modeling
%
%
Business Domain Modeling
========================
Enums and case classes together provide basic building blocks
for defining data types.
They are typically used to **model the business domain** of a program.
How to Model Things?
====================
Modeling consists of translating concepts from the real world
into data type definitions in the Scala world.
Modeling requires you to think about what details of the real
world are relevant for your program.
> The purpose of abstraction is not to be vague, but to create
> a new semantic level in which one can be absolutely precise.
>
> Edsger W. Dijkstra
Modeling Methodology (1)
========================
There is no systematic methodology: often, a same set of concepts
can be modeled in multiple ways.
But here are some advice.
->
- Identify the concepts (in general, nouns) that you are interested in
- Identify the relations between them
- Does a concept _belong to_ another one?
- e.g. “a rational number _has_ a numerator and a denominator”
- e.g. “a sum _has_ a left summand and a right summand”
- Does a concept _generalize_ another one?
- e.g. “‘functional programming’ _is_ a possible programming paradigm”
- e.g. “an arithmetic operation can either _be_ a product or a sum”
Modeling Methodology (2)
========================
- Translate each concept into a type definition
- Concepts belonging to others become **fields** of case classes
or of enumeration cases
- Concepts generalizing others become **enumerations**
- Check that you can construct meaningful objects from your model
Example: Painting Application
=============================
An image is made of a shape, a stroke width and a color.
Possible shapes are a square or a circle. A square has a side length.
A circle has a radius.
A color has a blue component, a red component and a green component.
Each component of a color is an integer value (between 0 and 255).
->
~~~
case class Image(shape: Shape, strokeWidth: Int, color: Color)
enum Shape {
case Square(side: Double)
case Circle(radius: Double)
}
case class Color(red: Int, green: Int, blue: Int)
~~~
Example: Painting Application
=============================
~~~
case class Image(shape: Shape, strokeWidth: Int, color: Color)
enum Shape
case Square(side: Double)
case Circle(radius: Double)
case class Color(red: Int, green: Int, blue: Int)
~~~
A blue circle:
~~~
val blue = Color(0, 0, 255)
val blueCircle = Image(Circle(10), 1, blue)
~~~
Data Types Define a Space of Possible States
============================================
The domain model defines the rules for constructing
objects representing a possible state of a program.
The more possible states, the more risks to have bugs
or to reach illegal states.
Hint: restrict the space of possible states to the minimum.
Summary
=======
In this lecture we have seen how to model the business domain
of a program using enumerations and case classes.