Кажется, я понимаю концепцию того, как интерфейсы будут реализовывать свободную связь? Вы можете найти этот вопрос как дубликат какого-то другого вопроса, но я прочитал много ответов, связанных с этой темой, и я не нашел удовлетворительного объяснения.
Ниже приведен пример того, как многие разработчики реализуют свободное соединение.
interface shape { public function sayName(); } class Circle implements shape { public function sayName(){ echo 'Hello my name is circle'; } } class Square implements shape { public function sayName(){ echo 'Hello my name is square'; } } class Creator { public $shape = null; public function __construct(Shape $shape){ $this->shape = $shape; } } $circle = new Creator(new Circle()); $circle->sayName(); $square = new Creator(new Square()); $square->sayName();
В приведенном выше примере мы используем полиморфизм интерфейса для достижения свободной связи. Но я не вижу, что этот код слабо связан. В приведенном выше примере вызывающий код (клиент) имеет прямое отношение к классам «Круг» и «Квадрат» с использованием «нового» оператора, что создает плотную связь.
Чтобы решить эту проблему, мы можем сделать что-то подобное.
форма интерфейса {public function sayName (); }
class Circle implements shape { public function sayName(){ echo 'Hello my name is circle'; } } class Square implements shape { public function sayName(){ echo 'Hello my name is square'; } } class Creator { public $shape = null; public function __construct($type){ if(strtolower($type) == 'circle'){ $this->shape = new Circle(); } else if(strtolower($type) == 'square'){ $this->shape = new Square(); } else { throw new Exception('Sorry we don\'t have '.$type.' shape'); } } } $circle = new Creator('Circle'); $circle->sayName(); $square = new Creator('Square'); $square->sayName();
В этом примере исправлены проблемы предыдущего примера, но мы вообще не используем интерфейс.
Мой вопрос, почему я должен использовать интерфейс, если я могу реализовать свободную связь без него? какие преимущества предложит интерфейс в приведенном выше сценарии? или какие проблемы я столкнулся бы, если я не использую интерфейс в приведенном выше примере?
Спасибо за вашу помощь.
Как отмечали другие, то, что вы делаете, более похоже на линию инъекции зависимости, которая является связанной, но отдельной темой из свободной связи. Я попытаюсь дать некоторое представление о простом применении ослабленной связи через интерфейсы.
Я склонен думать о интерфейсах как о удобном способе определения / обеспечения исполнения контрактов. Вместо упрощенного примера, в котором каждая форма может приветствовать, рассмотрим случай, когда вам нужно отображать каждую фигуру на изображение.
Этот псевдокод показывает, как вы можете иметь дело с квадратами и кругами без интерфейса.
class Circle { function renderCircle() { ... } } class Square { function renderSquare() { ... } } // then when we use them Circle[] circlesArray = loadCircles Square[] squaresArray = loadSquares foreach(circle in circlesArray){ circle.renderCircle } foreach(square in squaresArray){ square.renderSquare }
Если вместо этого мы говорим, что мы не очень заботимся о том, какой тип формы он есть, а только о том, что вы можете его отобразить, мы получим следующий интерфейс:
interface renderableShape { function render() }
И так далее, когда вы беспокоитесь только о возможности визуализации фигуры, вы программируете против этого интерфейса.
У вас может быть что-то вроде этого:
function renderShapes(Array[renderableShape] shapes){ foreach(shape in shapes){ shape.render() } }
Теперь вы гарантируете, что ваша функция renderShapes
не имеет видимости ни в одной из конкретных деталей реализации Circle или Square. Все, что нужно знать, это то, что вы можете вызвать render
.