Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Flyweight - Design Pattern
class FlyweightExample {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val raceCars = arrayOf(
RaceCarClient("Midget"),
RaceCarClient("Midget"),
RaceCarClient("Midget"),
RaceCarClient("Sprint"),
RaceCarClient("Sprint"),
RaceCarClient("Sprint")
)
raceCars[0].moveCar(29, 3112)
raceCars[1].moveCar(39, 2002)
raceCars[2].moveCar(49, 1985)
raceCars[3].moveCar(59, 2543)
raceCars[4].moveCar(69, 2322)
raceCars[5].moveCar(79, 2135)
/*Output and observe the number of instances created*/
println("Midget Car Instances: " + FlyweightMidgetCar.num)
println("Sprint Car Instances: " + FlyweightSprintCar.num)
}
}
}
abstract class RaceCar {
/**
* Intrinsic state stored and shared in the Flyweight object
*/
var name: String? = null
var speed = 0
var horsePower = 0
/**
* Extrinsic state is stored or computed by client objects, and passed to the Flyweight.
*/
abstract fun moveCar(currentX: Int, currentY: Int, newX: Int, newY: Int)
}
class FlyweightMidgetCar : RaceCar() {
init {
num++
}
/**
* This method accepts car location (extrinsic). No reference to current
* or new location is maintained inside the flyweight implementation
*/
override fun moveCar(currentX: Int, currentY: Int, newX: Int, newY: Int) {
println("New location of $name is X$newX - Y$newY")
}
companion object {
/**
* Track number of flyweight instantiation
*/
var num = 0
}
}
class FlyweightSprintCar : RaceCar() {
init {
num++
}
/**
* This method accepts car location (extrinsic). No reference to current
* or new location is maintained inside the flyweight implementation
*/
override fun moveCar(currentX: Int, currentY: Int, newX: Int, newY: Int) {
println("New location of $name is X$newX - Y$newY")
}
companion object {
/**
* Track number of flyweight instantiation
*/
var num = 0
}
}
object CarFactory {
private val flyweights: MutableMap<String, RaceCar> = HashMap()
/**
* If key exist, return flyweight from Map
*/
fun getRaceCar(key: String): RaceCar? {
if (flyweights.containsKey(key)) {
return flyweights[key]
}
val raceCar: RaceCar
when (key) {
"Midget" -> {
raceCar = FlyweightMidgetCar()
raceCar.name = "Midget Car"
raceCar.speed = 140
raceCar.horsePower = 400
}
"Sprint" -> {
raceCar = FlyweightSprintCar()
raceCar.name = "Sprint Car"
raceCar.speed = 160
raceCar.horsePower = 1000
}
else -> throw IllegalArgumentException("Unsupported car type.")
}
flyweights[key] = raceCar
return raceCar
}
}
class RaceCarClient(name: String?) {
private val raceCar: RaceCar?
/**
* The extrinsic state of the flyweight is maintained by the client
*/
private var currentX = 0
private var currentY = 0
init {
/**
* Ask factory for a RaceCar
*/
raceCar = getRaceCar(name!!)
}
fun moveCar(newX: Int, newY: Int) {
/**
* Car movement is handled by the flyweight object
*/
raceCar!!.moveCar(
currentX,
currentY, newX, newY
)
currentX = newX
currentY = newY
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment