Skip to content

Commit 9bd3888

Browse files
author
Badacadabra
committed
Add Template (ES5 + ES6 + CoffeeScript + TypeScript)
1 parent 98f845b commit 9bd3888

File tree

7 files changed

+298
-0
lines changed

7 files changed

+298
-0
lines changed

doc/GoF/Behavioral/Template/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Synopsis
2+
3+
I am a construction professional and I always respect the basic principles of my job. I build houses and buildings following the common sense.
4+
5+
# Problem
6+
7+
Building something like a house is not trivial. It is very technical and, if you are not a construction professional, you may do things in the wrong order. For example, you could be tempted to build walls on a ground that is not fully prepared, leading to weak foundations.
8+
9+
# Solution
10+
11+
Even for professionals, it is good to have a template (like a plan drawn by an architect). This template makes it clear that you have to work on foundations first, then build walls and finally put the roof.
12+
13+
The Template design pattern is an ideal candidate to express with code this kind of situation. For this pattern, we need:
14+
15+
* An abstract representation of a construction (abstract class is preferred because it makes it possible to implement the template method which will be the same for every type of construction)
16+
* Concrete constructions (House & Building)
17+
18+
Most methods on the abstract class are abstract and are implemented in concrete constructions.
1.87 KB
Binary file not shown.
13.9 KB
Loading
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# ==============================
2+
# ABSTRACT HOME
3+
# ==============================
4+
5+
class Home
6+
constructor: ->
7+
throw new Error "You cannot instantiate an abstract class!" if @constructor is Home
8+
9+
foundations: ->
10+
throw new Error "You cannot call an abstract method!"
11+
12+
walls: ->
13+
throw new Error "You cannot call an abstract method!"
14+
15+
roof: ->
16+
throw new Error "You cannot call an abstract method!"
17+
18+
build: ->
19+
"""
20+
Construction of a new home:
21+
1. #{this.foundations()}
22+
2. #{this.walls()}
23+
3. #{this.roof()}\n
24+
"""
25+
26+
# ==============================
27+
# CONCRETE HOMES
28+
# ==============================
29+
30+
class House extends Home
31+
foundations: ->
32+
"House foundations"
33+
34+
walls: ->
35+
"House walls"
36+
37+
roof: ->
38+
"House roof"
39+
40+
class Building extends Home
41+
foundations: ->
42+
"Apartment building foundations"
43+
44+
walls: ->
45+
"Apartment building walls"
46+
47+
roof: ->
48+
"Apartment building roof"
49+
50+
# ==============================
51+
# CLIENT CODE
52+
# ==============================
53+
54+
house = new House
55+
building = new Building
56+
57+
console.log house.build()
58+
console.log building.build()
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// ==============================
2+
// ABSTRACT HOME
3+
// ==============================
4+
5+
abstract class Home {
6+
public abstract foundations(): string;
7+
public abstract walls(): string;
8+
public abstract roof(): string;
9+
10+
public build(): string {
11+
return `
12+
Construction of a new home:
13+
1. ${this.foundations()}
14+
2. ${this.walls()}
15+
3. ${this.roof()}`;
16+
}
17+
}
18+
19+
// ==============================
20+
// CONCRETE HOMES
21+
// ==============================
22+
23+
class House extends Home {
24+
public foundations(): string {
25+
return "House foundations";
26+
}
27+
28+
public walls(): string {
29+
return "House walls";
30+
}
31+
32+
public roof(): string {
33+
return "House roof";
34+
}
35+
}
36+
37+
class Building extends Home {
38+
public foundations(): string {
39+
return "Apartment building foundations";
40+
}
41+
42+
public walls(): string {
43+
return "Apartment building walls";
44+
}
45+
46+
public roof(): string {
47+
return "Apartment building roof";
48+
}
49+
}
50+
51+
// ==============================
52+
// CLIENT CODE
53+
// ==============================
54+
55+
let house: Home = new House(),
56+
building: Home = new Building();
57+
58+
console.log(house.build());
59+
console.log(building.build());
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'use strict';
2+
3+
// ==============================
4+
// ABSTRACT HOME
5+
// ==============================
6+
7+
var Home = (function() {
8+
function Home() {
9+
if (this.constructor === Home) {
10+
throw new Error("You cannot instantiate an abstract class!");
11+
}
12+
}
13+
14+
Home.prototype.foundations = function () {
15+
throw new Error("You cannot call an abstract method!");
16+
};
17+
18+
Home.prototype.walls = function () {
19+
throw new Error("You cannot call an abstract method!");
20+
};
21+
22+
Home.prototype.roof = function () {
23+
throw new Error("You cannot call an abstract method!");
24+
};
25+
26+
Home.prototype.build = function () {
27+
var home = "";
28+
home += "Construction of a new home:\n";
29+
home += " 1. " + this.foundations();
30+
home += " 2. " + this.walls();
31+
home += " 3. " + this.roof();
32+
return home;
33+
};
34+
35+
return Home;
36+
})();
37+
38+
// ==============================
39+
// CONCRETE HOMES
40+
// ==============================
41+
42+
var House = (function () {
43+
function House() {}
44+
House.prototype = Object.create(Home.prototype);
45+
House.prototype.constructor = House;
46+
47+
House.prototype.foundations = function () {
48+
return "House foundations\n";
49+
};
50+
51+
House.prototype.walls = function () {
52+
return "House walls\n";
53+
};
54+
55+
House.prototype.roof = function () {
56+
return "House roof\n";
57+
};
58+
59+
return House;
60+
})();
61+
62+
var Building = (function () {
63+
function Building() {}
64+
Building.prototype = Object.create(Home.prototype);
65+
Building.prototype.constructor = Building;
66+
67+
Building.prototype.foundations = function () {
68+
return "Apartment building foundations\n";
69+
};
70+
71+
Building.prototype.walls = function () {
72+
return "Apartment building walls\n";
73+
};
74+
75+
Building.prototype.roof = function () {
76+
return "Apartment building roof\n";
77+
};
78+
79+
return Building;
80+
})();
81+
82+
// ==============================
83+
// CLIENT CODE
84+
// ==============================
85+
86+
var house = new House(),
87+
building = new Building();
88+
89+
console.log(house.build());
90+
console.log(building.build());
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// ==============================
2+
// ABSTRACT HOME
3+
// ==============================
4+
5+
class Home {
6+
constructor() {
7+
if (new.target !== undefined) {
8+
throw new Error("You cannot instantiate an abstract class!");
9+
}
10+
}
11+
12+
foundations() {
13+
throw new Error("You cannot call an abstract method!");
14+
}
15+
16+
walls() {
17+
throw new Error("You cannot call an abstract method!");
18+
}
19+
20+
roof() {
21+
throw new Error("You cannot call an abstract method!");
22+
}
23+
24+
build() {
25+
return `
26+
Construction of a new home:
27+
1. ${this.foundations()}
28+
2. ${this.walls()}
29+
3. ${this.roof()}`;
30+
}
31+
}
32+
33+
// ==============================
34+
// CONCRETE HOMES
35+
// ==============================
36+
37+
class House extends Home {
38+
foundations() {
39+
return "House foundations";
40+
}
41+
42+
walls() {
43+
return "House walls";
44+
}
45+
46+
roof() {
47+
return "House roof";
48+
}
49+
}
50+
51+
class Building extends Home {
52+
foundations() {
53+
return "Apartment building foundations";
54+
}
55+
56+
walls() {
57+
return "Apartment building walls";
58+
}
59+
60+
roof() {
61+
return "Apartment building roof";
62+
}
63+
}
64+
65+
// ==============================
66+
// CLIENT CODE
67+
// ==============================
68+
69+
let house = new House(),
70+
building = new Building();
71+
72+
console.log(house.build());
73+
console.log(building.build());

0 commit comments

Comments
 (0)