Bridge
While the Adapter design pattern helps you to work with legacy code, the Bridge design pattern helps you to avoid abusing inheritance. The way it works is actually very simple.
Let's imagine we want to build a system to manage different kinds of troopers for the Galactic Empire.
We'll start with an interface:
interface Trooper { fun move(x: Long, y: Long) fun attackRebel(x: Long, y: Long) }
And we'll create multiple implementations for different types of troopers:
class StormTrooper : Trooper { override fun move(x: Long, y: Long) { // Move at normal speed } override fun attackRebel(x: Long, y: Long) { // Missed most of the time } } class ShockTrooper : Trooper { override fun move(x...