Одной из доминирующих стратегий объектно-ориентированного проектирования является «принцип открытого-закрытого».

"программные объекты (классы, модули, функции и т. д.) должны быть открыты для расширения, но закрыты для модификации"

инкапсулировать детали интерфейса в базовом классе и спрятать детали реализации в производных классах. После этого клиенты могут подключиться к интерфейсу, и им не придется испытывать потрясения, связанные с изменением: никакого влияния при изменении количества производных классов и никакого влияния при изменении реализации производного класса.

Допустим, у нас есть транспортное средство базового класса, у которого есть дочерние классы, такие как Велосипед, Автомобиль, Трактор. Базовый класс имеет метод drive(), реализацию которого все эти классы наследуют и переопределяют. Предположим, мы получили требование добавить класс Airplane, который также наследуется от класса Vehicle, тогда у него также будет функция drive. Но самолеты не умеют водить, поэтому нам нужно переопределить метод drive() и заменить его пустым телом. Нам нужно было бы сделать это для каждого нового класса, производного от Vehicle, но не умеющего водить.

Вместо этого мы можем использовать шаблон проектирования стратегии. Здесь мы определяем интерфейс DriveBehaviour, который определяет метод drive. Затем мы определяем два класса DriveAsLandVehicle и DriveAsAeroplane. Класс DriveAsLandVehicle будет реализовывать метод привода и определять метод управления наземными транспортными средствами. А класс DriveAsAeroplane будет реализовывать метод привода, который ничего не делает. В классе транспортного средства мы определим переменную-член типа DriveBehaviour. И в производных классах велосипедов и автомобилей мы установим для DriveBehaviourMenmer значение DriveAsLandVehicle, а для класса самолета мы установим для члена DriveBehaviour значение DriveAsAeroplane. Таким образом мы отделяем реализацию от класса. Этот метод позволяет нам повторно использовать, а также является гибким.