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. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.249.198