-
Notifications
You must be signed in to change notification settings - Fork 109
/
Copy pathFactory Method.kt
72 lines (53 loc) · 2.22 KB
/
Factory Method.kt
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
package design_patterns
/**
*
* A factory method is a generic design pattern that defines
*
* a common interface for creating objects in a superclass,
*
* allowing subclasses to change the type of objects they create.
*
*/
abstract class House(private val address: String, private val price: Int) {
override fun toString() = """
address = $address
price = $price
""".trimIndent()
}
// the factory method makes sense if we have a hierarchy of objects
class WoodenCheapHouse(address: String) : House(address, 50_000)
class WoodenAverageHouse(address: String) : House(address, 250_000)
class WoodenExpensiveHouse(address: String) : House(address, 1_000_000)
class StoneCheapHouse(address: String) : House(address, 45_000)
class StoneAverageHouse(address: String) : House(address, 230_000)
class StoneExpensiveHouse(address: String) : House(address, 900_000)
// we have a common logic for every HouseCompany
abstract class HouseCompany {
private val alreadyBuiltHouses = mutableListOf<House>()
val examplesAlreadyBuiltHouses: String
get() = alreadyBuiltHouses.joinToString("\n\n")
fun orderHouse(address: String, cost: HouseCompanyCost): House {
val house = buildHouse(address, cost)
alreadyBuiltHouses.add(house)
return house
}
// the subclasses define a specific implementation
protected abstract fun buildHouse(address: String, cost: HouseCompanyCost): House
enum class HouseCompanyCost { CHEAP, AVERAGE, EXPENSIVE }
}
// WoodenHouseCompany only builds wooden houses
class WoodenHouseCompany : HouseCompany() {
override fun buildHouse(address: String, cost: HouseCompanyCost) = when(cost) {
HouseCompanyCost.CHEAP -> WoodenCheapHouse(address)
HouseCompanyCost.AVERAGE -> WoodenAverageHouse(address)
HouseCompanyCost.EXPENSIVE -> WoodenExpensiveHouse(address)
}
}
// StoneHouseCompany only builds stone houses
class StoneHouseCompany : HouseCompany() {
override fun buildHouse(address: String, cost: HouseCompanyCost) = when(cost) {
HouseCompanyCost.CHEAP -> StoneCheapHouse(address)
HouseCompanyCost.AVERAGE -> StoneAverageHouse(address)
HouseCompanyCost.EXPENSIVE -> StoneExpensiveHouse(address)
}
}