Skip to content

Commit d78442a

Browse files
added Template method design pattern; refactored Builder and Singleton patterns;
1 parent fb3d98e commit d78442a

File tree

7 files changed

+277
-87
lines changed

7 files changed

+277
-87
lines changed

src/main/kotlin/design_patterns/Builder.kt

+77-43
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,56 @@ package design_patterns
88
*
99
*/
1010

11-
1211
/**
1312
* The first variant
1413
*/
15-
class Pony1 private constructor(
16-
private val name: String,
17-
private val family: String,
18-
private val cutieMark: String,
19-
private val city: String
14+
class HttpConnectionClient1 private constructor(
15+
private val dnsServerAddress: String,
16+
private val callTimeout: Int,
17+
private val connectTimeout: Int,
18+
private val readTimeout: Int,
19+
private val writeTimeout: Int,
20+
// class can have many more fields
2021
) {
2122

22-
override fun toString() = "$name, $family, $cutieMark, $city"
23+
override fun toString() = """
24+
dns -> $dnsServerAddress
25+
call timeout -> $callTimeout
26+
connect timeout -> $connectTimeout
27+
read timeout -> $readTimeout
28+
write timeout -> $writeTimeout
29+
""".trimIndent()
2330

2431
class Builder {
25-
private var name: String = ""
26-
private var family: String = ""
27-
private var cutieMark: String = ""
28-
private var city: String = ""
32+
private var dnsServerAddress: String = "8.8.8.8"
33+
private var callTimeout: Int = 0
34+
private var connectTimeout: Int = 10_000
35+
private var readTimeout: Int = 10_000
36+
private var writeTimeout: Int = 0
37+
38+
fun dnsServerAddress(address: String) = apply {
39+
dnsServerAddress = address
40+
}
2941

30-
fun changeName(name: String) = apply {
31-
this.name = name
42+
fun callTimeout(timeout: Int) = apply {
43+
// we can add some checks such as:
44+
// if (timeout < 0) throw IllegalArgumentException("Uncorrected timeout: $timeout")
45+
callTimeout = timeout
3246
}
3347

34-
fun changeFamily(family: String) = apply {
35-
this.family = family
48+
fun connectTimeout(timeout: Int) = apply {
49+
connectTimeout = timeout
3650
}
3751

38-
fun changeCutieMark(cutieMark: String) = apply {
39-
this.cutieMark = cutieMark
52+
fun readTimeout(timeout: Int) = apply {
53+
readTimeout = timeout
4054
}
4155

42-
fun changeCity(city: String) = apply {
43-
this.city = city
56+
fun writeTimeout(timeout: Int) = apply {
57+
writeTimeout = timeout
4458
}
4559

46-
fun build() = Pony1(name, family, cutieMark, city)
60+
fun build() = HttpConnectionClient1(dnsServerAddress, callTimeout, connectTimeout, readTimeout, writeTimeout)
4761

4862
}
4963

@@ -52,49 +66,69 @@ class Pony1 private constructor(
5266
/**
5367
* The second variant
5468
*/
55-
class Pony2 {
56-
private var name: String = ""
57-
private var family: String = ""
58-
private var cutieMark: String = ""
59-
private var city: String = ""
60-
61-
override fun toString() = "$name, $family, $cutieMark, $city"
69+
class HttpConnectionClient2 private constructor() {
70+
private var dnsServerAddress: String = "8.8.8.8"
71+
private var callTimeout: Int = 0
72+
private var connectTimeout: Int = 10_000
73+
private var readTimeout: Int = 10_000
74+
private var writeTimeout: Int = 0
75+
76+
override fun toString() = """
77+
dns -> $dnsServerAddress
78+
call timeout -> $callTimeout
79+
connect timeout -> $connectTimeout
80+
read timeout -> $readTimeout
81+
write timeout -> $writeTimeout
82+
""".trimIndent()
6283

6384
companion object {
64-
fun newBuilder() = Pony2().Builder()
85+
fun newBuilder() = HttpConnectionClient2().Builder()
6586
}
6687

6788
inner class Builder {
6889

69-
fun changeName(name: String) = apply {
70-
this@Pony2.name = name
90+
fun dnsServerAddress(address: String) = apply {
91+
dnsServerAddress = address
92+
}
93+
94+
fun callTimeout(timeout: Int) = apply {
95+
// we can add some checks such as:
96+
// if (timeout < 0) throw IllegalArgumentException("Uncorrected timeout: $timeout")
97+
callTimeout = timeout
7198
}
7299

73-
fun changeFamily(family: String) = apply {
74-
this@Pony2.family = family
100+
fun connectTimeout(timeout: Int) = apply {
101+
connectTimeout = timeout
75102
}
76103

77-
fun changeCutieMark(cutieMark: String) = apply {
78-
this@Pony2.cutieMark = cutieMark
104+
fun readTimeout(timeout: Int) = apply {
105+
readTimeout = timeout
79106
}
80107

81-
fun changeCity(city: String) = apply {
82-
this@Pony2.city = city
108+
fun writeTimeout(timeout: Int) = apply {
109+
writeTimeout = timeout
83110
}
84111

85-
fun build() = this@Pony2
112+
fun build() = this@HttpConnectionClient2
86113
}
87114

88115
}
89116

90117
/**
91118
* Kotlin variant with default arguments
92119
*/
93-
class Pony3(
94-
private var name: String = "",
95-
private var family: String = "",
96-
private var cutieMark: String = "",
97-
private var city: String = ""
120+
class HttpConnectionClient3(
121+
private val dnsServerAddress: String = "8.8.8.8",
122+
private val callTimeout: Int = 0,
123+
private val connectTimeout: Int = 10_000,
124+
private val readTimeout: Int = 10_000,
125+
private val writeTimeout: Int = 0
98126
) {
99-
override fun toString() = "$name, $family, $cutieMark, $city"
127+
override fun toString() = """
128+
dns -> $dnsServerAddress
129+
call timeout -> $callTimeout
130+
connect timeout -> $connectTimeout
131+
read timeout -> $readTimeout
132+
write timeout -> $writeTimeout
133+
""".trimIndent()
100134
}

src/main/kotlin/design_patterns/Factory Method.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ package design_patterns
1010
*
1111
*/
1212

13-
abstract class Pony4
13+
abstract class Pony
1414

15-
class EarthPony4 : Pony4()
16-
class Pegasus4 : Pony4()
17-
class Unicorn4 : Pony4()
15+
class EarthPony4 : Pony()
16+
class Pegasus4 : Pony()
17+
class Unicorn4 : Pony()
1818

1919
abstract class Place {
2020
private var numberOfPonies = 0
2121

22-
abstract fun pony() : Pony4
22+
abstract fun pony() : Pony
2323

24-
fun newPony() : Pony4 {
24+
fun newPony() : Pony {
2525
numberOfPonies++
2626
return pony()
2727
}

src/main/kotlin/design_patterns/Singleton.kt

+27-10
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,38 @@ package design_patterns
22

33
/**
44
*
5-
* pattern: Singleton
5+
* Singleton is a generative design pattern that guarantees the existence of one instance of a class
66
*
7-
* using: used when we need to have the same object throughout
8-
* the entire execution of our program
9-
*
10-
* description: class allows you to create only a single object
7+
* and provides a global access point to it
118
*
129
*/
1310

14-
object LocalData {
15-
private val names = mutableListOf<String>()
11+
object SQLiteDatabase {
12+
13+
// SQLiteDatabase instance state
14+
private var connectionId = -1
15+
16+
// These methods provide a global access point to SQLiteDatabase instance state
17+
fun openConnection() {
18+
if (connectionId < 0) {
19+
// open connection...
20+
connectionId = 1
21+
}
22+
}
23+
24+
fun execSQL(sql: String): List<String> {
25+
if (connectionId < 0) return emptyList()
26+
return when (sql) {
27+
"select * from names" -> listOf("Rick", "Morty", "Jerry", "Beth")
28+
else -> emptyList()
29+
}
30+
}
1631

17-
fun addName(nm: String) {
18-
names.add(nm)
32+
fun closeConnection() {
33+
if (connectionId > 0) {
34+
// close connection...
35+
connectionId = -1
36+
}
1937
}
2038

21-
fun names() = names.toList()
2239
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package design_patterns
2+
3+
/**
4+
*
5+
* Template method a behavioral design pattern that defines the basis of an algorithm
6+
*
7+
* and allows subclasses to redefine some steps of the algorithm without changing its overall structure
8+
*
9+
*/
10+
11+
data class Cake(
12+
val layers: List<String>,
13+
val cream: String,
14+
val sprinkles: String
15+
)
16+
17+
abstract class CakeBaker {
18+
19+
protected abstract fun layer(): String
20+
21+
protected abstract fun cream(): String
22+
23+
protected abstract fun sprinkles(): String
24+
25+
// we have the basis of an algorithm
26+
fun makeCake(numberOfLayers: Int): Cake {
27+
return Cake(
28+
layers = List(numberOfLayers) { layer() },
29+
cream = cream(),
30+
sprinkles = sprinkles()
31+
)
32+
}
33+
34+
}
35+
36+
class ChocolateCakeBaker : CakeBaker() {
37+
38+
// subclasses redefines some steps of the algorithm
39+
override fun cream(): String = "chocolate cream"
40+
41+
override fun layer(): String = "chocolate cake layer"
42+
43+
override fun sprinkles(): String = "chocolate chips"
44+
45+
}
46+
47+
class WaffleCakeBaker : CakeBaker() {
48+
49+
override fun cream(): String = "custard cream"
50+
51+
override fun layer(): String = "waffle cake layer"
52+
53+
override fun sprinkles(): String = "coconut flakes"
54+
55+
}

0 commit comments

Comments
 (0)