Motivation: A class has two independent dimensions of variation (e.g., shape and colour), and combining them via inheritance would multiply the number of subclasses.

Intent: Separate an abstraction from its implementation so that the two can vary independently.

The point of this is to decouple 2 dimensions of variations so they can evolve independently, connected by a composition rather than inheritance. This one is slightly more confusing but the idea here, is that in this example, we have a Circle and Square which can both be rendered as a vector and raster. Instead of each class having a VectorSquare and RasterSquare etc, the renderer is pulled out.

interface Renderer {
    fun renderCircle(radius: Double)
    fun renderSquare(side: Double)
}
 
class VectorRenderer : Renderer {
    override fun renderCircle(radius: Double) { /* draw with vectors */ }
    override fun renderSquare(side: Double) { /* draw with vectors */ }
}
 
class RasterRenderer : Renderer {
    override fun renderCircle(radius: Double) { /* draw with pixels */ }
    override fun renderSquare(side: Double) { /* draw with pixels */ }  
}
 
abstract class Shape(protected val renderer: Renderer) {
    abstract fun draw()
}
 
class Circle(renderer: Renderer, val radius: Double) : Shape(renderer) {
    override fun draw() = renderer.renderCircle(radius)
}
 
class Square(renderer: Renderer, val side: Double) : Shape(renderer) {
    override fun draw() = renderer.renderSquare(side)
}