- Hands-On Design Patterns with Kotlin
- Alexey Soshin
- 368字
- 2021-06-25 20:49:29
Back to our bases
HQ is a special building that can produce other buildings. It keeps track of all the buildings it had built up until now. The same type of building can be built more than once:
class HQ {
val buildings = mutableListOf<Building<*, Unit>>()
fun buildBarracks(): Barracks {
val b = Barracks()
buildings.add(b)
return b
}
fun buildVehicleFactory(): VehicleFactory {
val vf = VehicleFactory()
buildings.add(vf)
return vf
}
}
You may be wondering what the star (*) means as regards generics. It's called a star projection, and it means I don't know anything about this type. It's similar to Java's raw types, but it's type safe.
All other buildings produce units. Units can be either infantry or armored vehicle:
interface Unit
interface Vehicle : Unit
interface Infantry : Unit
Infantry can be either riflemen or rocket soldier:
class Rifleman : Infantry
class RocketSoldier : Infantry
enum class InfantryUnits {
RIFLEMEN,
ROCKET_SOLDIER
}
Here we see the enum keyword for the first time. Vehicles are either tanks or armored personnel carriers (APCs):
class APC : Vehicle
class Tank : Vehicle
enum class VehicleUnits {
APC,
TANK
}
A barracks is a building that produces infantry:
class Barracks : Building<InfantryUnits, Infantry> {
override fun build(type: InfantryUnits): Infantry {
return when (type) {
RIFLEMEN -> Rifleman()
ROCKET_SOLDIER -> RocketSoldier()
}
}
}
We don't need the else block in our when. That's because we use enum, and Kotlin makes sure that when on enum is exhaustive.
A vehicle factory is a building that produces different types of armored vehicles:
class VehicleFactory : Building<VehicleUnits, Vehicle> {
override fun build(type: VehicleUnits) = when (type) {
APC -> APC()
TANK -> Tank()
}
}
We can make sure that we can build different units now:
val hq = HQ()
val barracks1 = hq.buildBarracks()
val barracks2 = hq.buildBarracks()
val vehicleFactory1 = hq.buildVehicleFactory()
And now on to producing units:
val units = listOf(
barracks1.build(InfantryUnits.RIFLEMEN),
barracks2.build(InfantryUnits.ROCKET_SOLDIER),
barracks2.build(InfantryUnits.ROCKET_SOLDIER),
vehicleFactory1.build(VehicleUnits.TANK),
vehicleFactory1.build(VehicleUnits.APC),
vehicleFactory1.build(VehicleUnits.APC)
)
We've already seen the listOf() function from the standard library. It will create a read-only list of different units that our buildings produce. You can iterate over this list and make sure that those are indeed the units we require.
- Practical Data Analysis Cookbook
- Facebook Application Development with Graph API Cookbook
- Spring Boot開發與測試實戰
- Visual FoxPro程序設計教程(第3版)
- vSphere High Performance Cookbook
- The Data Visualization Workshop
- 執劍而舞:用代碼創作藝術
- LabVIEW虛擬儀器程序設計從入門到精通(第二版)
- Internet of Things with ESP8266
- Citrix XenServer企業運維實戰
- R Data Science Essentials
- 青少年學Python(第2冊)
- Spring Boot從入門到實戰
- Flask開發Web搜索引擎入門與實戰
- 例說FPGA:可直接用于工程項目的第一手經驗