** Table of Contents ** If Abstract Factory is a factory as its name suggests and provides the function to manufacture each part, this pattern is a combination of parts ** product ( What is the image of ** mass-producing ** (composite objects) **?
By making the creation process of a composite object independent of the expression format, it is possible to generate objects with different expression formats in the same creation process.
-Abstract class for generating the Builder Product class -ConcreteBuilder Concrete Builder class. Generate Product class -Create an object using the interface of the Director Builder class -Product A composite object consisting of many components
Creators will create a city with the following flow.
Ask a professional builder to build the building you want to build-> Decide the number of floors and rooms in the building-> Ask them to build as many as you want
Builder interface
Builder.kt
package builder
interface Builder {
enum class ProductType(val value: String) {
ArtMuseum("Museum"),
Museum("Museum"),
MovieTheater("Movie theater")
}
fun getProduct(): Product
fun addFloor(floorNum: Int)
fun addRoom(targetFloor: Int, roomNo: Int)
}
Museum specialist builder concrete class
MuseumBuilder.kt
package builder
class MuseumBuilder(productName: String): Builder {
private var product = Product(Builder.ProductType.Museum, productName)
override fun getProduct(): Product {
product.countUpProductNumber()
return product.clone() as Product
}
override fun addFloor(floorNum: Int) {
if (product.floorList.asSequence().filter { floor -> floor.floorNum == floorNum }.count() == 0) {
product.floorList.add(Floor(floorNum))
}
}
override fun addRoom(targetFloor: Int, roomNo: Int) {
val floor= product.floorList.filter { floor -> floor.floorNum== targetFloor }
if (floor.count() > 0) {
floor[0].addRoom(roomNo)
}
}
}
Museum specialist builder concrete class
ArtMuseumBuilder.kt
package builder
class ArtMuseumBuilder(productName: String) : Builder {
private var product = Product(Builder.ProductType.ArtMuseum, productName)
override fun getProduct(): Product {
product.countUpProductNumber()
return product.clone() as Product
}
override fun addFloor(floorNum: Int) {
if (product.floorList.asSequence().filter { floor -> floor.floorNum == floorNum }.count() == 0) {
product.floorList.add(Floor(floorNum))
}
}
override fun addRoom(targetFloor: Int, roomNo: Int) {
val floor= product.floorList.filter { floor -> floor.floorNum== targetFloor }
if (floor.count() > 0) {
floor[0].addRoom(roomNo)
}
}
}
Movie theater specialist builder concrete class
MovieTheaterBuilder.kt
package builder
class MovieTheaterBuilder(productName: String): Builder {
private var product = Product(Builder.ProductType.MovieTheater, productName)
override fun getProduct(): Product {
product.countUpProductNumber()
return product.clone() as Product
}
override fun addFloor(floorNum: Int) {
if (product.floorList.asSequence().filter { floor -> floor.floorNum == floorNum }.count() == 0) {
product.floorList.add(Floor(floorNum))
}
}
override fun addRoom(targetFloor: Int, roomNo: Int) {
val floor= product.floorList.filter { floor -> floor.floorNum== targetFloor }
if (floor.count() > 0) {
floor[0].addRoom(roomNo)
}
}
}
You can skip the section from the building to the room.
Building class
Product.kt
package builder
class Product(productType: Builder.ProductType, productName: String): Cloneable {
var productType = productType
val floorList: MutableList<Floor> = mutableListOf()
var productName = productName
var productNumber = 0
fun countUpProductNumber() {
productNumber++
}
fun show(): String {
var ret = "【building】${productType.value}:$productName$productNumber Building"
for (floor in floorList) {
ret += floor.show()
}
return ret
}
public override fun clone(): Any {
return super.clone()
}
}
Hierarchical class 1st floor 2nd floor ...
Floor.kt
package builder
class Floor(floorNum: Int) {
var floorNum = floorNum
private val roomList:MutableList<Room> = mutableListOf()
fun addRoom(roomNo: Int) {
if (roomList.asSequence().filter { room -> room.roomNo == roomNo }.count() == 0) {
roomList.add(Room(roomNo))
}
}
fun show(): String {
var ret: String = "【hierarchy】$floorNum floor"
for (room in roomList) {
ret += room.show()
}
return ret
}
}
Room class
Room.kt
package builder
class Room(roomNo: Int) {
val roomNo = roomNo
fun show(): String {
return "【room】$roomNo room"
}
}
City maker class
Creator.kt
package builder
class Creator {
init {
var productList:MutableList<Product> = mutableListOf()
//Ask a museum specialist to build the Western Art Museum
var artMuseumBuilder1 = ArtMuseumBuilder("National Museum of Western Art").apply {
addFloor(1)
addFloor(2)
addFloor(3)
addRoom(1, 101)
addRoom(1, 102)
addRoom(2, 201)
addRoom(3, 301)
}
//Ask a museum specialist builder to build the Oriental Museum
var artMuseumBuilder2 = ArtMuseumBuilder("Museum of Oriental Ceramics").apply {
addFloor(1)
addFloor(2)
addRoom(1, 101)
addRoom(2, 201)
}
//Ask a museum specialist to build a national museum
var museumBuilder = MuseumBuilder("National Museum").apply {
addFloor(1)
addRoom(1, 101)
}
//Ask a movie theater specialist to build Hoge Cinemas
var movieTheaterBuilder = MovieTheaterBuilder("HOGE Cinemas").apply {
addFloor(1)
addRoom(1, 101)
}
//Creating a list to build in the city
productList.add(artMuseumBuilder1.getProduct())
productList.add(artMuseumBuilder1.getProduct())
productList.add(artMuseumBuilder1.getProduct())
productList.add(artMuseumBuilder2.getProduct())
productList.add(artMuseumBuilder2.getProduct())
productList.add(museumBuilder.getProduct())
productList.add(movieTheaterBuilder.getProduct())
for (product in productList) {
println(product.show())
}
}
}
Creators think about what kind of building they want to build in the city, ask each builder to build as much as they need. Was it easier to understand if it was a convenience store?
It's a simple structure because it can't be helped to make it too much, but if you let the Product class hold the address property and make it build `getProduct ()`
each time you can set the address property, it will be more image. Was it easy?
With the above, the purpose of ** mass-producing ** products (composite objects) ** has been achieved.
I want to add another movie theater in the middle of building a town! You can also ** duplicate (mass) ** the same building by calling `movieTheaterBuilder.getProduct ()`
. The `` `return product.clone () as Product``` of each Builder # getProduct () method does a good job.
[output]
[Building] Museum:The 1st floor of the National Museum of Western Art [Level] 1st floor [Room] Room 101 [Room] Room 102 [Level] 2nd floor [Room] Room 201 [Level] 3rd floor [Room] Room 301
[Building] Museum:The National Museum of Western Art, 2nd floor [Level] 1st floor [Room] Room 101 [Room] Room 102 [Level] 2nd floor [Room] Room 201 [Level] 3rd floor [Room] Room 301
[Building] Museum:The 3rd building of the National Museum of Western Art [Level] 1st floor [Room] Room 101 [Room] Room 102 [Level] 2nd floor [Room] Room 201 [Level] 3rd floor [Room] Room 301
[Building] Museum:The Museum of Oriental Ceramics 1st Building [Level] 1st floor [Room] Room 101 [Level] 2nd floor [Room] Room 201
[Building] Museum:The Museum of Oriental Ceramics 2nd Building [Level] 1st floor [Room] Room 101 [Level] 2nd floor [Room] Room 201
[Building] Museum:National Museum 1st Building [Level] 1st Floor [Room] Room 101
[Building] Movie theater:HOGE Cinemas 1st Building [Level] 1st Floor [Room] Room 101
If you don't do ``` product.clone ()` ``, you will get the following result, and you will end up with a useless builder.
[output]
[Building] Museum:The 3rd building of the National Museum of Western Art...
[Building] Museum:The 3rd building of the National Museum of Western Art...
[Building] Museum:The 3rd building of the National Museum of Western Art...
[Building] Museum:The second building of the Oriental Museum...
[Building] Museum:The second building of the Oriental Museum...
[Building] Museum:National Museum 1st Building...
[Building] Movie theater:HOGE Cinemas 1...
Recommended Posts