官术网_书友最值得收藏!

Making improvements

One may claim that having the VehicleFactory and Barracks classes is too cumbersome. They don't have any state, after all. Instead, we can replace them with objects.

Instead of the previous implementation of buildBarracks(), we can have the following:

fun buildBarracks(): Building<InfantryUnits, Infantry> {
val b = object : Building<InfantryUnits, Infantry> {
override fun build(type: InfantryUnits): Infantry {
return when (type) {
InfantryUnits.RIFLEMEN -> Rifleman()
InfantryUnits.ROCKET_SOLDIER -> RocketSoldier()
}
}
}
buildings.add(b)
return b
}

We've already seen two different usages of the object keyword: once in the Singleton design pattern, and another time in the Factory Method design pattern. Here is the third way we can use it: for creating anonymous classes on the fly. After all, Barracks is a building that, given InfantryUnitType, produces Infantry.

If our logic is straightforward, we can even shorten the declaration a bit more:

fun buildVehicleFactory(): Building<VehicleUnits, Vehicle> {
val vf = object : Building<VehicleUnits, Vehicle> {
override fun build(type: VehicleUnits) = when (type) {
VehicleUnits.APC -> APC()
VehicleUnits.TANK -> Tank()
}
}
buildings.add(vf)

return vf
}

Let's go to the beginning of this chapter. We said that Abstract Factory combines a number of related factories. So, what's common to all factories in our case? They're all buildings and they all produce units.

Having that principle in mind, you could apply it to many different cases. If you're familiar with strategy games, usually they have at least two different factions. Each may have different structures and units. To achieve that, you can repeat this pattern as many times as needed.

Let's assume we have two different factions now, cats and dogs, and Tanks and Rocket Infantry are only prerogatives of this faction. Dogs have Heavy Tanks and Grenadiers instead. What changes do we need to make in our system?

First, HQ becomes an interface:

interface HQ {
fun buildBarracks(): Building<InfantryUnits, Infantry>
fun buildVehicleFactory(): Building<VehicleUnits, Vehicle>
}

What was HQ previously now becomes CatHQ:

class CatHQ : HQ { 
// Remember to add override to your methods
}

And DogHQ will have to repeat the same steps, but with a different construction logic.

This ability to accommodate big changes is what makes Abstract Factory so powerful in some use cases. 

主站蜘蛛池模板: 珠海市| 玉溪市| 斗六市| 稻城县| 邳州市| 兴仁县| 五原县| 开化县| 禹城市| 砚山县| 祁连县| 宣化县| 屯留县| 渑池县| 自治县| 华亭县| 西宁市| 祥云县| 沾益县| 桂东县| 柳江县| 秭归县| 习水县| 桂林市| 济阳县| 临泉县| 安徽省| 宁津县| 山阴县| 赤壁市| 双辽市| 花莲市| 获嘉县| 姜堰市| 阳泉市| 永德县| 肃宁县| 雷山县| 东宁县| 凤庆县| 凉山|