Что такое «слабая связь»? Пожалуйста, приведите примеры


172

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

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


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

11
Полностью не согласен, практичность может быть по-разному проиллюстрирована на разных языках, и это особенно очевидно в динамических и компилируемых языках. Но концепция одинакова в любом случае.
Оуэн

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

Ответы:


180

Рассмотрим простое приложение для корзины покупок, которое использует класс CartContents для отслеживания товаров в корзине и класс 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 для отслеживания элементов, нам также придется изменить класс 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);
    }
}

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


Не могли бы вы расширить ответ, вводя дальнейшую развязку через внедрение зависимостей (хотя конструктор должен быть идеальным)?
BAD_SEED

4
@ Клин, я не вижу причин, Orderчтобы иметь какие-либо знания о Cart. Живые покупки и фактурация - это два разных контекста. Когда клиент готов заплатить, у вас может быть процесс, отвечающий за перевод CartEntries во что-то значимое для Order. Таким образом, Orderкласс также будет создан и использован без Cart.
plalx

@ Клин Не могли бы вы отреагировать на мой комментарий, пожалуйста?
plalx

Ну и просто объяснил. Я начал видеть свет в «.. Обратите внимание, как метод OrderTotal (и, следовательно, класс Order) зависит от деталей реализации классов CartContents и CartEntry ..»
okey_on

Этот пример наглядно представлен. Однако в наши дни все больше и больше архитекторов соглашаются с тем, что этот чрезмерно объектно-ориентированный стиль является плохой практикой. Нет смысла скрывать детали «реализации» CartEntryи CartContents. Поскольку они имеют совершенно четкое значение, их следует просто смоделировать как мертвые данные. в терминах базы данных, все, что нужно здесь, это таблицаCREATE TABLE entry (price INTEGER, quantity INTEGER)
Джо Так

160

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

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


Хорошая или слабая связь? Как принять решение о реализации слабой связи или жесткой связи?
Sreekanth Karumanaghat

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

1
Sreekanth Karumanaghat, вы бы предпочли потратить меньше денег только на батарею и снова иметь работающий iPod, или вы бы предпочли потратить много денег на целый iPod?
Кошера

1
@SreekanthKarumanaghat Обычно слабая связь лучше, потому что она способствует модульности и, следовательно, облегчает поддержку кода. Если вы тесно связываете свои классы / библиотеки / код, то любое небольшое изменение, которое вы делаете в одном классе, должно быть реализовано во всех классах, которые его используют.
Кенни Уорден

56

Я буду использовать 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. Или, другими словами, они «отделены» или «слабо связаны» с родительскими классами.

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


2
Этот пример все еще имеет довольно высокий уровень связи. Просто вместо того, чтобы быть связанным с одним классом, есть два на выбор. В этом примере предполагается, что будут доступны только две реализации «Runnable». В этом случае интерфейс даже не требуется.
Оуэн

Эти именованные методы Run * и Do * являются для меня огромным запахом кода. Вы могли бы также реорганизовать это в использование IHandleStuff или IFrobnicateThings. Runnable - это слишком, слишком общий термин в данном случае.
Клин

8
Оуэн, детка, шагает мой друг. Если он не понимает сцепления, как он поймет, какой заводской паттерн его покупает? Этот пример кода ставит его на правильный путь. Намерение состоит в том, что он лучше поймет проблему и поймет, как абстрагироваться от создания объектов.
64BitBob

6
Было бы это более читабельным, если бы ABC и XYZ были переименованы в нечто подобное DiskAccessorи NetworkAccessor? Я не знаю, ява ...
MusiGenesis

Использует ли он также шаблон фабричного дизайна? Потому что мы создаем новые объекты XYZ или ABC в зависимости от необходимости.
munmunbb

37

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

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

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

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

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


33

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

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

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

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

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

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

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


Это вряд ли относится к тому, что на самом деле является «сцепление» . См. Stackoverflow.com/questions/39946/coupling-and-cohesion для некоторых хороших ответов.
Rogério

@ Роджерио: Я думаю, что это связано. Может быть, вас смущают другие определения «связи», но вам следует прочитать « Слабая связь» . «Сильная связь возникает, когда зависимый класс содержит указатель непосредственно на конкретный класс, который обеспечивает требуемое поведение ... Слабая связь возникает, когда зависимый класс содержит указатель только на интерфейс, который затем может быть реализован одним или несколькими конкретными классами «. В моем примере мой код будет свободно связан с ArrayList через интерфейс List.
Билл Ящерица

@Bill: Спасибо за ссылку, но эта статья кажется мне полностью поддельной. Похоже, что он «переосмысливает» идеи из другой области (организационное поведение), давая определение «слабой связи», которое противоречит первоначальному определению программного обеспечения Ларри Константину: en.wikipedia.org/wiki/Coupling_(computer_science) .
Rogério

@Rogerio: статья Константина была написана в 1974 году. Вероятно, что за последние 36 лет было много переосмысления, но я не думаю, что статья в Википедии является ее источником. Например, шаблоны, такие как Dependency Injection, полагаются на интерфейсы для ослабления связи, как я описал в своем ответе.
Билл Ящерица

2
@ Билл: Конечно, работа Константина по структурированному дизайну - старая вещь, но я не вижу причин, чтобы сделать ее недействительной или радикально переосмыслить. Оригинальные концепции сплоченности и сцепления лежат в основе объектно-ориентированного дизайна, так же, как наследование и полиморфизм. DI (лучшая статья martinfowler.com/articles/injection.html ) - это просто техника для внешней конфигурации плагинов (абстрактные интерфейсы с реализациями, выбранными во время выполнения с помощью кода конфигурации); Другой такой метод - это шаблон Service Locator. DI и связь являются независимыми понятиями.
Rogério

27

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

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

С помощью нединамических языков, таких как 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();
   }
}

Таким образом, calss, который создает CatchService, может делать следующее:

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

или

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

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

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


1
Мне нравится этот пример лучше, чем другие, так как подобные вещи происходят в деловом мире изо дня в день. Если запускается Class Person, запускается Class Cat, запускается Class Dog и т. Д. Было бы огромной программой, чтобы детализировать все те классы, которые запускаются. Но использование интерфейса, называемого run, в котором каждый класс выполняет одно и то же, делает вашу программу более гибкой и управляемой. :)
sksallaj

Объяснил действительно хорошо, сэр, просто чтобы прояснить в последнем примере, вы сделали это с внедрением зависимостей, и первый пример также слабо связан?
Али Саджид

Ух, старый ответ прокомментировал :). Таким образом, ответ - нет, первый пример имеет жесткую зависимость от CatcherA, поэтому они тесно связаны
Оуэн,

23

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


1
Итак, «слабо связанный» на самом деле означает меньше зависимостей? Я прав?
user314362

4
На самом деле это не связано с общим количеством зависимостей, которые имеет один конкретный класс. Связь (жесткая или свободная) на самом деле является свойством отношений между двумя классами. Таким образом, у вас может быть один класс, который слабо связан со 100 другими классами, или другой класс, который тесно связан только с двумя другими классами (например).
MusiGenesis

2
Плохой пример, я бы сказал: у вас есть дублирование кода, а не жесткая связь. А с хорошим инструментом рефакторинга такое дублирование можно устранить за считанные секунды.
Rogério

@Rogerio: это, наверное, не лучший пример. Мне больше нравится 64BitBobответ.
MusiGenesis

12

Определение

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

Высокая связь

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

Слабая связь

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


7

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

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

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

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, то мне нужно было бы внести изменения в эти / те ссылки / ы, чтобы перейти в другую реализацию сервиса.


6

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

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

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

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

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

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

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


5

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

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

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

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


4

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

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

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 .

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


3

Рассмотрим приложение для 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.

Р.П.


3

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

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

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

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

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

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

  • VaxClusters
  • Linux-кластеры

Напротив, некоторые примеры тесно спаренных:

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

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


3

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


1
Это не совсем так - как упоминалось в других примерах, дело не столько в том, существует ли связь между сущностями (модулями, классами), но в том, могут ли они быть легко заменены на другие классы, реализующие те же функции. Например, ViewModel может работать с разными моделями, но без нее определенно не будет работать
Хейден Крокер,

да, не очень полезно
brgs

2

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

«Слабая связь» описывает упругие отношения между двумя или более системами или организациями с какими-то отношениями обмена.

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


1
Если бы это было так просто, у нас не было бы этого обсуждения.
BRG

2

Я предлагаю очень простой тест сцепления кода :

  1. Кусок А кода тесно связан с Куском В кода, если существует какая-либо возможная модификация Куска В, которая приведет к изменениям в Куске А, чтобы сохранить корректность.

  2. Кусок А кода не тесно связан с Куском В кода, если нет никакой возможной модификации Куска В, которая бы внесла необходимые изменения в Кусок А.

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


2

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

--- --- A.java

package interface_package.loose_coupling;

public class A {

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

--- --- B.java

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();
}

--- --- MainClass

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. Вам не нужно ничего менять в классе А

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


0

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

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


-8

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

Надеюсь, это несколько полезно.


1
Я понимаю, к чему вы стремитесь, но все еще не очень хороший способ объяснить, что тесно связаны, когда две «вещи» взаимозависимы друг от друга, по сравнению со слабосвязанными, когда две «вещи» существуют независимо друг от друга - где одна «вещь» может быть измененным без изменений на другую «вещь» ...
Брайан Ребейн

Стив, вы совершенно правы - вы не заслуживали НИКАКОГО отрицательного голоса. Просто ваша аудитория не была готова к вашей терминологии, и слишком многие на этом сайте имеют привычку осуждать то, что они не понимают или что незнакомо. -shrug-
Ричард Т

Я думаю, что Стив упустил суть. Слабая связь не всегда подразумевает, что 2 актера работают независимо над одной и той же рабочей нагрузкой.
Роб
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.