Open/Closed Principle
Modules conform to the open/closed principle if they are…
Open for Extension - meaning the functionality of the module can be extended.
Closed for Change - meaning the module itself doesn’t require change to extend its functionality.
Rationale
Following this principle reduces the chances of cascades of changes needing to be made. These types of changes make code
fragile and unpredictable.
Examples
Example that breaks the rule
In this example adding any new type of shape required Canvas to change.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class Canvas {
public Canvas(List<String> shapes) {
this.shapes = shapes;
}
private drawCircle() { /*...*/ }
private drawSquare() { /*...*/ }
public draw() {
foreach(shape in shapes) {
switch(shapes) {
case "circle": drawCircle(); break;
case "square": drawSquare(); break;
}
}
}
}
|
Example that doesn’t break the rule
In this example adding any new shape only required new classe to be defined, but never changed.
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
|
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
/* ... */
}
}
class Square implements Shape {
public void draw() {
/* ... */
}
}
class Canvas {
public Canvas(List<Shape> shapes) {
this.shapes = shapes;
}
public void draw() {
foreach(shape in shapes) {
shape.draw();
}
}
}
|
References