Может быть полезно программировать интерфейсы, даже если мы не зависим от абстракций.
Программирование на интерфейсы заставляет нас использовать контекстно-зависимое подмножество объекта. Это помогает, потому что это:
Например, рассмотрим класс Person
, который реализует интерфейс Friend
и Employee
.
class Person implements AbstractEmployee, AbstractFriend {
}
В контексте дня рождения человека мы программируем интерфейс Friend
, чтобы предотвратить обращение с человеком как Employee
.
function party() {
const friend: Friend = new Person("Kathryn");
friend.HaveFun();
}
В контексте работы человека мы программируем интерфейс Employee
, чтобы предотвратить размывание границ рабочего места.
function workplace() {
const employee: Employee = new Person("Kathryn");
employee.DoWork();
}
Отлично. Мы ведем себя соответственно в разных контекстах, и наше программное обеспечение работает хорошо.
В будущем, если наш бизнес изменится для работы с собаками, мы сможем довольно легко изменить программное обеспечение. Сначала мы создаем класс Dog
, который реализует как Friend
, так и Employee
. Затем мы благополучно меняем new Person()
на new Dog()
. Даже если обе функции имеют тысячи строк кода, это простое редактирование будет работать, потому что мы знаем следующее:
party
использует только подмножество Friend
в Person
. workplace
использует только подмножество Employee
в Person
. Dog
реализует интерфейсы Friend
и Employee
. С другой стороны, если либо party
, либо workplace
должны были запрограммироваться против Person
, существует риск того, что оба имеют Person
-специфический код. Переход от Person
в Dog
потребовал бы, чтобы мы расчесывали код, чтобы искоренить любой Person
-специфический код, который Dog
не поддерживает.
Мораль: программирование на интерфейсы помогает нашему коду вести себя надлежащим образом и быть готовыми к переменам. Он также подготавливает наш код к зависимости от абстракций, что приносит еще больше преимуществ.