Что такое слабая связь? Приведите примеры

Мне кажется, что я не могу понять концепцию «слабой связи». Полагаю, не помогает то, что слово «свободный» обычно имеет негативный оттенок, поэтому я всегда забываю, что слабая связь - это хорошо.

Кто-нибудь покажет, пожалуйста, код «до» и «после» (или псевдокод), который иллюстрирует эту концепцию?


person trebormf    schedule 22.10.2008    source источник
comment
Я не уверен, как это можно отделить от конкретного языка, потому что часть концепции заключается в том, как использовать язык, чтобы блоки кода не слишком запутывались друг с другом. Я также отмечаю, что некоторые ответы прибегают к коду, чтобы проиллюстрировать концепцию.   -  person Onorio Catenacci    schedule 22.10.2008
comment
Полностью не согласен, практические аспекты могут быть по-разному проиллюстрированы на разных языках, и это особенно очевидно в динамических и компилируемых языках. Но концепция в любом случае одна и та же.   -  person Owen    schedule 23.10.2008
comment
Свободный против плотного и Связывание против развязки. Помогать с нами - не всегда хорошо, иногда хорошо, а иногда плохо ... Как и у нас должна быть независимость, как и у классов.   -  person bonCodigo    schedule 15.05.2014


Ответы (20)


Рассмотрим простое приложение корзины покупок, которое использует класс CartContents для отслеживания товаров в корзине покупок и класс Order для обработки покупки. Order необходимо определить общую стоимость содержимого в корзине, он может сделать это так:

Пример сильной связи:

public class CartEntry
{
    public float Price;
    public int Quantity;
}

public class CartContents
{
    public CartEntry[] items;
}

public class Order
{
    private CartContents cart;
    private float salesTax;

    public Order(CartContents cart, float salesTax)
    {
        this.cart = cart;
        this.salesTax = salesTax;
    }

    public float OrderTotal()
    {
        float cartTotal = 0;
        for (int i = 0; i < cart.items.Length; i++)
        {
            cartTotal += cart.items[i].Price * cart.items[i].Quantity;
        }
        cartTotal += cartTotal*salesTax;
        return cartTotal;
    }
}

Обратите внимание, как метод OrderTotal (и, следовательно, класс Order) зависит от деталей реализации классов CartContents и CartEntry. Если бы мы попытались изменить эту логику, чтобы учесть скидки, нам, вероятно, пришлось бы изменить все 3 класса. Кроме того, если мы перейдем к использованию коллекции List<CartEntry> для отслеживания элементов, нам также придется изменить класс Order.

Вот немного лучший способ сделать то же самое:

Менее связанный пример:

public class CartEntry
{
    public float Price;
    public int Quantity;

    public float GetLineItemTotal()
    {
        return Price * Quantity;
    }
}

public class CartContents
{
    public CartEntry[] items;

    public float GetCartItemsTotal()
    {
        float cartTotal = 0;
        foreach (CartEntry item in items)
        {
            cartTotal += item.GetLineItemTotal();
        }
        return cartTotal;
    }
}

public class Order
{
    private CartContents cart;
    private float salesTax;

    public Order(CartContents cart, float salesTax)
    {
        this.cart = cart;
        this.salesTax = salesTax;
    }

    public float OrderTotal()
    {
        return cart.GetCartItemsTotal() * (1.0f + salesTax);
    }
}

Логика, специфичная для реализации позиции корзины, коллекции тележек или заказа, ограничивается только этим классом. Таким образом, мы могли изменить реализацию любого из этих классов, не меняя другие классы. Мы могли бы пойти дальше в этом разделении, улучшив дизайн, добавив интерфейсы и т. Д., Но я думаю, вы понимаете суть.

person Wedge    schedule 22.10.2008
comment
Не могли бы вы расширить ответ, введя дальнейшее разделение посредством внедрения зависимостей (хотя конструктор должен быть идеальным)? - person BAD_SEED; 12.04.2013
comment
@Wedge, я не вижу причин для Order знать о Cart. Живые покупки и фактурация - это два разных контекста. Когда клиент будет готов заплатить, у вас может быть процесс, ответственный за преобразование CartEntries во что-то значимое для Order. Таким образом, класс Order также будет создан и использован без Cart. - person plalx; 20.10.2013
comment
@Wedge Не могли бы вы отреагировать на мой комментарий? - person plalx; 31.10.2013
comment
Ну и объяснил просто. Я начал видеть свет на .. Обратите внимание, как метод OrderTotal (и, следовательно, класс Order) зависит от деталей реализации классов CartContents и CartEntry .. - person okey_on; 30.09.2015
comment
Этот пример четко представлен. Однако в наши дни все больше и больше архитекторов соглашаются, что этот чрезмерно объектно-ориентированный стиль - плохая практика. Нет смысла скрывать детали реализации CartEntry и CartContents. Поскольку они имеют совершенно ясное значение, их следует просто моделировать как мертвые данные. с точки зрения базы данных, все, что здесь нужно, это таблица CREATE TABLE entry (price INTEGER, quantity INTEGER) - person Jo So; 09.07.2016
comment
@JoSo, However in these days, more and more architects agree that this overly object-oriented style is bad practice [необходима ссылка] :) - person brgs; 18.06.2018
comment
@bargoras, ну давай. Просто оставьте землю сложности и выйдите на свет :-) - person Jo So; 18.06.2018

Многие интегрированные продукты (особенно Apple), такие как iPod, iPad, являются хорошим примером тесной связи: как только батарея разрядится, вы можете с таким же успехом купить новое устройство, потому что батарея припаивается и не отсоединяется, что делает замену очень дорогой. Слабосвязанный проигрыватель позволит легко заменить батарею.

То же касается разработки программного обеспечения: обычно (намного) лучше иметь слабосвязанный код для облегчения расширения и замены (и для облегчения понимания отдельных частей). Но очень редко и при особых обстоятельствах тесная связь может быть выгодна, потому что тесная интеграция нескольких модулей позволяет лучше оптимизировать.

person Konrad Rudolph    schedule 31.12.2008
comment
Слабое или плотное соединение - это хорошо? Как решить применять слабую связь или тугую? - person Sreekanth Karumanaghat; 14.07.2015
comment
спасибо за этот отличный пример. Я потратил много времени на другие ответы, но это не стоит того - person alamin; 18.11.2015
comment
Срикант Каруманагхат, вы бы предпочли потратить меньше денег только на батарею и снова иметь рабочий iPod или вы бы предпочли потратить много денег на целый iPod? - person Koshera; 21.04.2016
comment
@SreekanthKarumanaghat Обычно слабая связь лучше, потому что она способствует модульности и, таким образом, упрощает поддержку кода. Если вы плотно объедините свои классы / библиотеки / код, то любое небольшое изменение, которое вы сделаете в одном классе, должно быть реализовано во всех классах, которые его используют. - person Kenny Worden; 28.06.2017

Я буду использовать Java в качестве примера. Допустим, у нас есть класс, который выглядит так:

public class ABC
{
   public void doDiskAccess() {...}
}

Когда я вызываю класс, мне нужно сделать что-то вроде этого:

ABC abc = new ABC();

abc. doDiskAccess();

Все идет нормально. Теперь предположим, что у меня есть еще один класс, который выглядит так:

public class XYZ
{
   public void doNetworkAccess() {...}
}

Он выглядит точно так же, как ABC, но, допустим, работает по сети, а не на диске. Итак, теперь давайте напишем такую ​​программу:

if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();

Это работает, но немного громоздко. Я мог бы упростить это с помощью такого интерфейса:

public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}

Теперь мой код может выглядеть так:

Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();

Видите, насколько это чище и проще для понимания? Мы только что поняли первый основной принцип слабой связи: абстракцию. Ключевым моментом здесь является обеспечение того, чтобы ABC и XYZ не зависели от каких-либо методов или переменных классов, которые их вызывают. Это позволяет ABC и XYZ быть полностью независимыми API. Или, другими словами, они «развязаны» или «слабо связаны» с родительскими классами.

Но что, если нам нужна связь между ними? Что ж, тогда мы можем использовать дополнительные абстракции, такие как Event Model, чтобы гарантировать, что родительский код никогда не будет вместе с созданными вами API.

person 64BitBob    schedule 22.10.2008
comment
Этот пример все еще имеет довольно высокий уровень сцепления. Сейчас вместо того, чтобы быть привязанным к одному классу, есть два на выбор. В этом примере предполагается, что будут доступны только две реализации Runnable. В этом случае интерфейс даже не требуется. - person Owen; 23.10.2008
comment
Эти именованные методы Run * и Do * являются для меня огромным запахом кода. Вы также можете преобразовать это в использование IHandleStuff или IFrobnicateThings. «Работоспособность» в данном случае - слишком общий термин. - person Wedge; 23.10.2008
comment
Оуэн, мой друг, маленькие шажки. Если он не понимает сцепления, как он поймет, что ему дает фабричный паттерн? Этот пример кода направляет его на верный путь. Намерение состоит в том, чтобы он лучше понял проблему и осознал, как абстрагироваться от создания объектов. - person 64BitBob; 23.10.2008
comment
Было бы это более читабельным, если бы ABC и XYZ были переименованы примерно в DiskAccessor и NetworkAccessor? Я не знаю, java ... - person MusiGenesis; 21.10.2010

Извините, но «слабая связь» - это не проблема кодирования, это проблема дизайна. Термин «слабая связь» тесно связан с желаемым состоянием «высокой когезии», будучи противоположным, но дополняющим друг друга.

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

Высокая сплоченность - это своего рода «тесная связь», но высокая сплоченность - это состояние, при котором элементы дизайна, которым действительно необходимо знать друг о друге, спроектированы таким образом, чтобы они работали вместе чисто и элегантно.

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

Реализация этого оставлена ​​в качестве упражнения для читателя :).

person David M. Karr    schedule 22.10.2008

Тесно связанный код зависит от конкретной реализации. Если мне нужен список строк в моем коде, и я объявляю его так (на Java)

ArrayList<String> myList = new ArrayList<String>();

то я зависим от реализации ArrayList.

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

List<String> myList = new ArrayList<String>();

Это не позволяет мне вызывать любой метод для myList, специфичный для реализации ArrayList. Я ограничен только теми методами, которые определены в интерфейсе List. Если позже я решу, что мне действительно нужен LinkedList, мне нужно будет изменить свой код только в одном месте, где я создал новый список, а не в 100 местах, где я выполнял вызовы методов ArrayList.

Конечно, вы можете создать экземпляр ArrayList, используя первое объявление, и воздержаться от использования каких-либо методов, не являющихся частью интерфейса List, но использование второго объявления заставляет компилятор сохранять вашу честность.

person Bill the Lizard    schedule 22.10.2008
comment
Это вряд ли связано с тем, что на самом деле представляет собой связывание . См. stackoverflow.com/questions/39946/coupling-and-cohesion для некоторых хороших ответов. - person Rogério; 20.10.2010
comment
@Rogerio: Думаю, это имеет отношение. Возможно, вас смущают другие определения связывания, но вам следует прочитать Слабое связывание. Сильная связь возникает, когда зависимый класс содержит указатель непосредственно на конкретный класс, который обеспечивает требуемое поведение ... Слабая связь возникает, когда зависимый класс содержит указатель только на интерфейс, который затем может быть реализован одним или несколькими конкретными классами. В моем примере мой код будет слабо связан с ArrayList через интерфейс List. - person Bill the Lizard; 21.10.2010
comment
@Bill: Спасибо за ссылку, но эта статья мне кажется полностью надуманной. Похоже, что он переосмысливает идеи из другой области (организационное поведение), давая определение слабой связи, которое противоречит исходному определению Ларри Константина, относящемуся к конкретному программному обеспечению: en.wikipedia.org/wiki/Coupling_ (computer_science). - person Rogério; 21.10.2010
comment
@Rogerio: Статья Константина была написана в 1974 году. Вероятно, за последние 36 лет произошло много переосмыслений, но я не думаю, что статья в Википедии является ее источником. Например, такие шаблоны, как Injection Dependency, полагаются на интерфейсы для ослабления связи точно так же, как я опиши в моем ответе. - person Bill the Lizard; 21.10.2010
comment
@Bill: Конечно, работа Константина над структурированным дизайном - старая штука, но я не вижу причин, чтобы ее опровергнуть или радикально переосмыслить. Исходные концепции сплоченности и сцепления лежат в основе объектно-ориентированного дизайна, равно как и наследование и полиморфизм. DI (лучшая статья - martinfowler.com/articles/injection.html) - это просто метод для внешней конфигурации плагинов (абстрактные интерфейсы с реализациями, выбранными во время выполнения через код конфигурации); другой такой метод - это шаблон Service Locator. DI и связь - независимые концепции. - person Rogério; 21.10.2010
comment
@Rogerio: Это не делает его недействительным и не является радикальным переосмыслением. Да, DI и связь независимы. Я хотел сказать, что DI использует интерфейсы точно так же, как я проиллюстрировал в своем ответе. В статье Fowler DI, на которую вы ссылаетесь, используется тот же самый шаблон для отделения кода от конкретного класса с использованием интерфейса, который я показал здесь. - person Bill the Lizard; 21.10.2010
comment
@Bill: Возможно, вас заинтересует следующее современное описание связывания: cc2e.com/File.ashx ? cid = 336 (это глава 5 книги Code Complete, 2-е издание, доступной в Интернете - см. страницы 100-102). В частности, автор определяет соединение простого объекта как форму слабого связывания, описываемого как модуль - это простой объект, связанный с объектом, если он создает экземпляр этого объекта. Такая связь подходит. - person Rogério; 02.03.2011

Степень различия между ответами здесь показывает, почему эту концепцию было бы трудно понять, но, если выразить ее так просто, как я могу ее описать:

Чтобы я знал, что если я брошу тебе мяч, ты сможешь его поймать, мне действительно не нужно знать, сколько тебе лет. Мне не нужно знать, что вы ели на завтрак, и мне действительно все равно, кто был вашей первой любовью. Все, что мне нужно знать, это то, что ты можешь поймать. Если я это знаю, то меня не волнует, если это ты, я кидаю мяч тебе или твоему брату.

С нединамическими языками, такими как C # или Java и т. Д., Мы достигаем этого через интерфейсы. Допустим, у нас есть следующий интерфейс:

public ICatcher
{
   public void Catch();
}

А теперь допустим, что у нас есть следующие классы:

public CatcherA : ICatcher
{
   public void Catch()
   {
      console.writeline("You Caught it");
   }

}
public CatcherB : ICatcher
{
   public void Catch()
   {
      console.writeline("Your brother Caught it");
   }

}

Теперь и CatcherA, и CatcherB реализуют метод Catch, поэтому служба, для которой требуется Catcher, может использовать любой из них и не особо заботиться о том, какой именно. Таким образом, тесно связанный сервис может напрямую создать экземпляр перехваченного, т.е.

public CatchService
{
   private CatcherA catcher = new CatcherA();

   public void CatchService()
   {
      catcher.Catch();
   }

}

Таким образом, CatchService может делать именно то, что он намеревался делать, но он использует CatcherA и всегда будет пользователем CatcherA. Он жестко запрограммирован, поэтому остается там, пока кто-нибудь не придет и не изменит его структуру.

Теперь давайте рассмотрим другой вариант, называемый внедрением зависимостей:

public CatchService
{
   private ICatcher catcher;

   public void CatchService(ICatcher catcher)
   {
      this.catcher = catcher;
      catcher.Catch();
   }
}

Таким образом, вызовы, которые создают экземпляр CatchService, могут делать следующее:

CatchService catchService = new CatchService(new CatcherA());

or

CatchService catchService = new CatchService(new CatcherB());

Это означает, что служба Catch не тесно связана ни с CatcherA, ни с CatcherB.

Есть несколько других стратегий для слабого связывания таких сервисов, как использование инфраструктуры IoC и т. Д.

person Owen    schedule 22.10.2008
comment
Мне этот пример нравится больше, чем другие, поскольку подобные вещи происходят в деловом мире изо дня в день. Если работает Class Person, работает Class Cat, Class Dog и т. Д. Это была бы огромная программа, подробно описывающая все выполняемые классы. Но использование интерфейса под названием run, в котором каждый класс выполняет одно и то же, делает вашу программу более гибкой и управляемой. :) - person sksallaj; 22.07.2012
comment
Разъяснено очень хорошо, сэр, просто чтобы прояснить в последнем примере, что вы сделали это с помощью инъекции зависимостей, а первый пример также слабо связан? - person Ali Sajid; 23.09.2017
comment
Вау, старый ответ прокомментирован :). Итак, ответ - нет, первый пример сильно зависит от CatcherA, поэтому они сильно связаны. - person Owen; 04.10.2017

Вы можете думать о (сильной или слабой) связке буквально как о количестве усилий, которые вам потребуются, чтобы отделить конкретный класс от его зависимости от другого класса. Например, если каждый метод в вашем классе имеет небольшой блок finally внизу, где вы вызываете Log4Net, чтобы что-то регистрировать, то вы бы сказали, что ваш класс тесно связан с Log4Net. Если бы ваш класс вместо этого содержал частный метод с именем LogSomething, который был единственным местом, которое вызывало компонент Log4Net (а все другие методы вместо этого назывались LogSomething), тогда вы бы сказали, что ваш класс был слабо связан с Log4Net (потому что это не заняло бы много времени). попытка вытащить Log4Net и заменить его чем-то другим).

person MusiGenesis    schedule 22.10.2008
comment
Итак, слабая связь на самом деле означает меньше зависимостей? Я прав? - person user314362; 10.09.2010
comment
На самом деле это не связано с общим количеством зависимостей одного конкретного класса. Связь (тесная или слабая) на самом деле является свойством отношений между двумя классами. Таким образом, у вас может быть один класс, который слабо связан со 100 другими классами, или другой класс, который тесно связан всего с двумя другими классами (например). - person MusiGenesis; 10.09.2010
comment
Плохой пример, я бы сказал: у вас есть дублирование кода, а не тесная связь. А с помощью хорошего инструмента рефакторинга такое дублирование можно было бы устранить за секунды. - person Rogério; 20.10.2010
comment
@Rogerio: наверное, это не лучший пример. Мне лично нравится ответ 64BitBob больше. - person MusiGenesis; 21.10.2010

Определение

По сути, связь - это степень зависимости данного объекта или набора объектов от другого объекта или другого набора объектов для выполнения своей задачи.

Высокое сцепление

Представьте себе машину. Для запуска двигателя необходимо вставить ключ в замок зажигания, повернуть, должен присутствовать бензин, должна возникнуть искра, поршни должны загореться, а двигатель должен ожить. Можно сказать, что автомобильный двигатель сильно связан с несколькими другими объектами. Это высокая степень сцепления, но на самом деле это не так уж плохо.

Слабая связь

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

person Tom    schedule 22.10.2008

Это довольно общая концепция, поэтому примеры кода не дадут полной картины.

Один парень здесь на работе сказал мне: «Паттерны похожи на фракталы, вы можете увидеть их, когда увеличиваете масштаб очень близко, а когда вы уменьшаете масштаб до уровня архитектуры».

Чтение краткой страницы википедии может дать вам представление об этой общности:

http://en.wikipedia.org/wiki/Loose_coupling

Что касается конкретного примера кода ...

Вот одна слабая связь, с которой я недавно работал, из материала Microsoft.Practices.CompositeUI.

    [ServiceDependency]
    public ICustomizableGridService CustomizableGridService
    {
        protected get { return _customizableGridService; }
        set { _customizableGridService = value; }
    }

Этот код объявляет, что этот класс зависит от CustomizableGridService. Вместо того, чтобы напрямую ссылаться на точную реализацию службы, он просто заявляет, что для этого требуется НЕКОТОРАЯ реализация этой службы. Затем во время выполнения система разрешает эту зависимость.

Если это не ясно, вы можете прочитать более подробное объяснение здесь:

http://en.wikipedia.org/wiki/Dependency_injection

Представьте, что ABCCustomizableGridService - это реализация, которую я собираюсь здесь реализовать.

Если я захочу, я могу вырвать это и заменить на XYZCustomizableGridService или StubCustomizableGridService без каких-либо изменений в классе с этой зависимостью.

Если бы у меня была прямая ссылка на ABCCustomizableGridService, мне нужно было бы внести изменения в эту / эти ссылки, чтобы поменять местами другую реализацию службы.

person rice    schedule 22.10.2008

Связь связана с зависимостями между системами, которые могут быть модулями кода (функциями, файлами или классами), инструментами в конвейере, процессами сервер-клиент и т. Д. Чем менее общие зависимости, тем более «тесно связанными» они становятся, поскольку изменение одной системы потребовало изменения других систем, которые на нее полагаются. Идеальная ситуация - это «слабая связь», когда одна система может быть изменена, а системы, зависящие от нее, будут продолжать работать без изменений.

Общий способ добиться слабой связи - использовать четко определенные интерфейсы. Если взаимодействие между двумя системами четко определено и соблюдается с обеих сторон, становится легче изменить одну систему, гарантируя, что соглашения не нарушаются. На практике обычно не устанавливается четко определенный интерфейс, что приводит к неаккуратному дизайну и тесной связи.

Некоторые примеры:

  • Приложение зависит от библиотеки. При сильной связи приложение не работает в более новых версиях библиотеки lib. Google для "DLL Hell".

  • Клиентское приложение считывает данные с сервера. В условиях жесткой связи изменения на сервере требуют исправлений на стороне клиента.

  • Два класса взаимодействуют в объектно-ориентированной иерархии. При сильной связи изменения в одном классе требуют, чтобы другой класс был обновлен для соответствия.

  • Множественные инструменты командной строки обмениваются данными в конвейере. Если они тесно связаны, изменение версии одного инструмента командной строки вызовет ошибки в инструментах, считывающих его вывод.

person Parappa    schedule 22.10.2008

Связка означает, насколько тесно разные классы связаны друг с другом. Тесно связанные классы содержат большое количество взаимодействий и зависимостей.

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

Лего, игрушки, которые соединяются по протоколу SNAP, будут считаться слабо связанными, потому что вы можете просто соединить части вместе и построить любую систему, какую захотите. Однако в мозаике есть части, которые ПЛОТНО соединены между собой. Вы не можете взять кусок из одной мозаики (системы) и соединить ее в другую головоломку, потому что система (головоломка) очень зависит от очень конкретных частей, которые были созданы для этого конкретного «дизайна». Лего созданы в более общем виде, поэтому их можно использовать в вашем доме Lego или в моем Lego Alien Man.

Ссылка: https://megocode3.wordpress.com/2008/02/14/coupling-and-cohesion/

person user1263981    schedule 03.10.2016

Два компонента являются сильно связанными, когда они зависят от конкретной реализации друг друга.

Предположим, у меня есть этот код где-то в методе моего класса:

this.some_object = new SomeObject();

Теперь мой класс зависит от SomeObject, и они сильно связаны. С другой стороны, допустим, у меня есть метод InjectSomeObject:

void InjectSomeObject(ISomeObject so) { // note we require an interface, not concrete implementation
  this.some_object = so;
}

Тогда в первом примере можно просто использовать внедренный SomeObject. Это полезно во время тестирования. При нормальной работе вы можете использовать тяжелые классы, использующие базы данных, сетевые классы и т. д., в то время как для тестов, проходящих легкую фиктивную реализацию. С жестко связанным кодом этого не сделать.

Некоторые части этой работы можно упростить, используя контейнеры для внедрения зависимостей. Вы можете узнать больше о DI в Википедии: http://en.wikipedia.org/wiki/Dependency_injection.

Иногда легко зайти слишком далеко. В какой-то момент вам придется конкретизировать вещи, иначе ваша программа станет менее читаемой и понятной. Так что используйте эту технику в основном на границе компонентов и знайте, что делаете. Убедитесь, что вы используете слабую связь. В противном случае он вам, вероятно, не понадобится. Я могу усложнить вашу программу. Убедитесь, что вы сделали хороший компромисс. Другими словами, поддерживайте хороший баланс. Как всегда при проектировании систем. Удачи!

person Paweł Hajdan    schedule 23.10.2008

Рассмотрим приложение для Windows с FormA и FormB. FormA - это основная форма, которая отображает FormB. Представьте, что FormB нужно передать данные обратно своему родительскому элементу.

Если вы сделали это:

class FormA 
{
    FormB fb = new FormB( this );

    ...
    fb.Show();
}

class FormB 
{
    FormA parent;

    public FormB( FormA parent )
    {
        this.parent = parent;
    }     
}

FormB тесно связан с FormA. FormB не может иметь другого родителя, кроме типа FormA.

Если, с другой стороны, у вас есть FormB для публикации события и подписки FormA на это событие, тогда FormB может отправить данные обратно через это событие любому подписчику, имеющему это событие. В этом случае FormB даже не знает, что отвечает своему родителю; благодаря слабой связи событие обеспечивает простую беседу с подписчиками. Любой тип теперь может быть родительским для FormA.

rp

person rp.    schedule 22.10.2008

В информатике есть другое значение для "слабой связи", о котором здесь никто больше не писал, так что ... Вот и пошло - надеюсь, вы дадите мне несколько голосов, чтобы это не потеряно в нижней части кучи! УБЕДИТЕЛЬНО тема моего ответа относится к любому исчерпывающему ответу на вопрос ... А именно:

Термин «свободная связь» впервые появился в вычислениях как термин, используемый как прилагательное, относящееся к архитектуре ЦП в многопроцессорной конфигурации. Его аналог - термин «тесная связь». Слабая связь - это когда процессоры не разделяют много общих ресурсов, а сильная связь - когда они это делают.

Термин «система» может сбивать с толку, поэтому, пожалуйста, внимательно проанализируйте ситуацию.

Обычно, но не всегда, несколько процессоров в аппаратной конфигурации, в которой они существуют в одной системе (как в отдельных блоках «ПК»), будут тесно связаны. За исключением некоторых сверхвысокопроизводительных систем, подсистемы которых фактически разделяют основную память между «системами», все делимые системы слабо связаны.

Термины Tightly Coupled и Loosely Coupled были введены до изобретения многопоточных и многоядерных процессоров, поэтому этим терминам могут понадобиться некоторые компаньоны, чтобы полностью описать ситуацию сегодня. И действительно, сегодня вполне может быть система, которая объединяет оба типа в одну общую систему. Что касается текущих программных систем, есть две общие архитектуры, по одной каждой разновидности, которые достаточно распространены и должны быть знакомыми.

Во-первых, поскольку речь идет о том, о чем идет речь, несколько примеров слабосвязанных систем:

  • VaxClusters
  • Кластеры Linux

Напротив, некоторые примеры Tightly Coupled:

  • Операционные системы с семетрической многопроцессорной обработкой (SMP) - например, Fedora 9
  • Многопоточные процессоры
  • Многоядерные процессоры

В сегодняшних вычислениях нередки случаи, когда оба они работают в единой общей системе. Например, возьмем современные двух- или четырехъядерные процессоры Pentium под управлением Fedora 9 - это сильно связанные вычислительные системы. Затем объедините несколько из них в слабо связанный кластер Linux, и теперь у вас есть как слабосвязанные, так и тесно связанные вычисления! О, разве современное оборудование не замечательно!

person Richard T    schedule 23.10.2008

Говоря простым языком, слабосвязанный термин означает, что он не зависит от другого события. Он выполняется независимо.

person Ravindra Miyani    schedule 20.03.2014
comment
Это не совсем так - как упоминалось в других примерах, дело не столько в том, существует ли связь между сущностями (модулями, классами), сколько в том, могут ли они быть легко заменены другими классами, реализующими ту же функциональность. например, ViewModel может работать с разными моделями, но определенно не будет работать без одного - person Hayden Crocker; 12.03.2018
comment
а, не очень полезно - person brgs; 18.06.2018

Вот несколько длинных ответов. Но принцип очень прост. Я отправляю вступительное заявление из wikipedia:

"Слабая связь описывает устойчивые отношения между двумя или более системами или организациями, имеющими какие-то отношения обмена.

Каждый конец транзакции делает свои требования явными и делает мало предположений о другом конце ».

person Ben Aston    schedule 31.12.2008
comment
Если бы это было так просто, у нас не было бы этого обсуждения. - person brgs; 18.06.2018

Предлагаю очень простой Тест связывания кода:

  1. Часть A кода тесно связана с частью B кода, если существует какая-либо возможная модификация части B, которая принудительно изменяет часть A для сохранения правильности.

  2. Часть кода A не является тесно связанной с частью B кода, если нет возможности модификации части B, которая сделала бы изменение части A необходимым.

Это поможет вам проверить степень связи между частями вашего кода. для объяснения этого см. это сообщение в блоге: http://marekdec.wordpress.com/2012/11/14/loose-coupling-tight-coupling-decoupling-what-is-that-all-about/

person Marek Dec    schedule 14.11.2012

Когда вы создаете объект класса с помощью ключевого слова new в каком-то другом классе, вы фактически делаете жесткую связь (плохая практика), вместо этого вы должны использовать слабую связь, что является хорошей практикой.

--- A.java ---

package interface_package.loose_coupling;

public class A {

void display(InterfaceClass obji)
{
    obji.display();
    System.out.println(obji.getVar());
}
}

--- Б.Ява ---

package interface_package.loose_coupling;

public class B implements InterfaceClass{

private String var="variable Interface";

public String getVar() {
    return var;
}

public void setVar(String var) {
    this.var = var;
}

@Override
public void display() {
    // TODO Auto-generated method stub
    System.out.println("Display Method Called");
}
}

--- InterfaceClass ---

package interface_package.loose_coupling;

public interface InterfaceClass {

void display();
String getVar();
}

--- Главный класс ---

package interface_package.loose_coupling;

public class MainClass {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    A obja=new A();
    B objb=new B();
    obja.display(objb);     //Calling display of A class with object of B class 

}
}

Объяснение:

В приведенном выше примере у нас есть два класса A и B

Класс B реализует интерфейс, то есть InterfaceClass.

InterfaceClass определяет контракт для класса B, поскольку InterfaceClass имеет абстрактные методы класса B, к которым может получить доступ любой другой класс, например A.

В классе A у нас есть метод отображения, который может исключать объект класса, который реализует InterfaceClass (в нашем случае это класс B). И для этого объекта метод класса A вызывает display () и getVar () класса B

В MainClass мы создали объект класса A и B. И вызываем метод отображения A, передав объект класса B, то есть objb. Метод отображения A будет вызываться с объектом класса B.

Теперь поговорим о слабой связи. Предположим, что в будущем вам нужно будет изменить имя класса B на ABC, тогда вам не нужно будет изменять его имя в методе отображения класса B, просто создайте объект new (класс ABC) и передайте его методу отображения в MailClass. Вам не нужно ничего менять в классе A

ссылка: http://p3lang.com/2013/06/loose-coupling-example-using-interface/

person Abhishek Aggarwal    schedule 06.01.2015

Вы можете узнать больше об общей концепции "слабой связи".

Короче говоря, это описание взаимосвязи между двумя классами, где каждый класс знает о другом как минимум, и каждый класс потенциально может продолжать работать нормально независимо от того, присутствует другой или нет, и без зависимости от конкретной реализации другого. класс.

person Franci Penov    schedule 22.10.2008

Слабая связь - это, как правило, два участника, работающих независимо друг от друга над одной и той же рабочей нагрузкой. Итак, если у вас есть 2 веб-сервера, использующие одну и ту же внутреннюю базу данных, вы бы сказали, что эти веб-серверы слабо связаны. Примером сильной связи может служить наличие двух процессоров на одном веб-сервере ... эти процессоры тесно связаны.

Надеюсь, это немного поможет.

person Steve    schedule 22.10.2008
comment
Я понимаю, к чему вы стремитесь, но все же не очень хороший способ объяснить, что сильная связь - это когда две `` вещи '' взаимозависимы друг от друга, по сравнению со слабосвязанной, когда две `` вещи '' существуют независимо - когда одна `` вещь '' может заменить без изменений на другую «вещь» ... - person Bryan Rehbein; 22.10.2008
comment
Стив, вы ТОЧНО правы - вы не заслужили НИКАКОГО голоса против. Просто ваша аудитория не была готова к вашей терминологии, и слишком многие на этом сайте имеют привычку голосовать за то, что они не понимают или что незнакомо. пожатие плечами - person Richard T; 23.10.2008
comment
Я думаю, Стив упустил суть. Слабая связь не всегда подразумевает, что два участника работают независимо над одной и той же рабочей нагрузкой. - person Rob; 31.12.2008