Интерфейс, в данном случае означающий конструкцию кода, а не абстракцию проекта, поддерживает базовый принцип разработки кода, называемый «слабой связью». Есть еще несколько производных принципов, которые говорят вам, КАК код должен быть слабо связан, но в основном, слабая связь помогает изменениям кода влиять на как можно меньшую область кодовой базы.
Рассмотрим, например, вычисление некоторой произвольной сложности. Это вычисление используется 6 различными классами, и поэтому, чтобы избежать дублирования кода, вычисление заключено в его собственный класс, Калькулятор. Каждый из 6 классов содержит ссылку на калькулятор. Теперь скажите, что ваш клиент приходит к вам и говорит, что при одном использовании Калькулятора, если выполняются определенные условия, вместо этого следует использовать другой расчет. У вас может возникнуть желание просто поместить эти два правила (правило использования и бизнес-правило) и новый алгоритм вычислений в класс Calculator, но если вы это сделаете, то произойдут две вещи; Во-первых, вы делаете Калькулятор осведомленным о некоторых деталях реализации (как они используются) вне его области действия, которые ему не нужно знать и которые могут измениться позже. Во-вторых, остальные 5 классов, использующих Calculator, которые работали без перебоев, должны быть перекомпилированы, поскольку они ссылаются на измененный класс, и должны быть протестированы, чтобы убедиться, что вы не нарушили их функциональность, изменив для 6 класса.
«Правильным» решением для этого является интерфейс. Определив интерфейс ICalculator, который предоставляет методы, вызываемые другими классами, вы нарушаете конкретную зависимость 6 классов от конкретного класса Calculator. Теперь каждый из 6 классов может иметь ссылку на ICalculator. В 5 из этих классов вы предоставляете тот же класс Calculator, который у них был всегда, и отлично работаете с ним. 6-го числа вы предоставляете специальный калькулятор, который знает дополнительные правила. Если бы вы сделали это с самого начала, вам не пришлось бы трогать другие 5 классов, чтобы внести изменения в 6-й.
Суть в том, что классы не должны знать точную природу других объектов, от которых они зависят; вместо этого им нужно только знать, что этот объект для них сделает. Абстрагируя то, что объект ДЕЛАЕТ от того, чем объект является, несколько объектов могут делать похожие вещи, и классы, которым требуются эти вещи, не должны знать разницу.
Слабая связь, наряду с «высокой связностью» (объекты обычно должны быть специалистами, которые знают, как выполнять небольшой, очень тесно связанный набор задач), является основой для большинства шаблонов проектирования программного обеспечения, которые вы увидите как вы прогрессируете в теории разработки программного обеспечения.
В отличие от пары ответов, существуют методологии проектирования (например, SOLID), которые утверждают, что вы ВСЕГДА должны устанавливать зависимости как абстракции, такие как абстрактный базовый класс или интерфейс, и НИКОГДА не иметь один класс, зависящий от другого конкретного класса.,Логика здесь заключается в том, что при разработке коммерческого программного обеспечения начальный набор требований для приложения очень мал, но это безопасное предположение, если не гарантия, что набор требований будет расти и изменяться.Когда это происходит, программное обеспечение должно расти.Создание даже небольших приложений в соответствии со строгими принципами проектирования позволяет расширять программное обеспечение, не вызывая проблем, которые являются естественным следствием плохого проектирования (большие классы с большим количеством кода, изменения одного класса, влияющие на другие непредсказуемым образом и т. Д.).Однако искусство разработки программного обеспечения и ограничения по времени и деньгам таковы, что вы можете (и должны) быть умными и говорить: «Из того, что я знаю о том, как эта система будет развиваться, это область, которая нуждается вбыть хорошо разработанным, чтобы позволить адаптацию, в то время как этот другой раздел почти наверняка никогда не изменится ".Если эти предположения изменятся, вы можете вернуться и реструктурировать области кода, которые вы разработали, очень просто, чтобы быть более надежными, прежде чем расширять эту область.Но вы должны быть готовы и иметь возможность вернуться и изменить код после его первой реализации.