В чем разница между свободной связью и плотной связью в объектно-ориентированной парадигме?

Можно ли описать точную разницу между свободной связью и плотной связью в объектно-ориентированной парадигме?

Ответ 1

Плотная связь - это когда группа классов сильно зависит друг от друга.

Этот сценарий возникает, когда класс принимает слишком много обязанностей или когда одна проблема распространяется на многие классы, а не на собственный класс.

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

Свободно связанный класс может потребляться и тестироваться независимо от других (конкретных) классов.

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

Пример герметичной связи:

class CustomerRepository
{
    private readonly Database database;

    public CustomerRepository(Database database)
    {
        this.database = database;
    }

    public void Add(string CustomerName)
    {
        database.AddRow("Customer", CustomerName);
    }
}

class Database
{
    public void AddRow(string Table, string Value)
    {
    }
}

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

class CustomerRepository
{
    private readonly IDatabase database;

    public CustomerRepository(IDatabase database)
    {
        this.database = database;
    }

    public void Add(string CustomerName)
    {
        database.AddRow("Customer", CustomerName);
    }
}

interface IDatabase
{
    void AddRow(string Table, string Value);
}

class Database : IDatabase
{
    public void AddRow(string Table, string Value)
    {
    }
}

Другой пример здесь.

Ответ 2

Объяснение без ЛЮБОГО кода

Сводный пример:

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

The Hat is "loosely coupled" to the body. This means you can easily take then hat off without making any changes to the the person/body. Picture Attribution: https://pixabay.com/en/greeting-cylinder-chapeau-dignity-317250/

Герметичное соединение (подробный пример)

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

  • Ключевой момент № 1: Другими словами, , если вы хотите изменить кожу, вы также должны изменить дизайн своего тела, потому что они соединены вместе - они тесно связаны.

Бог не был хорошим объектно-ориентированным программистом.

Слабая связь (подробный пример)

А теперь подумай одеться утром. Тебе не нравится синий? Нет проблем: вместо этого вы можете надеть красную рубашку. Вы можете сделать это легко и без усилий, потому что рубашка на самом деле не связана с вашим телом так же, как ваша кожа. Рубашка не знает и не заботится о том, на каком теле она идет. Другими словами, вы можете сменить одежду, не меняя своего тела.

  • Это ключевой момент № 2. Если вы меняете свою рубашку, то вы не обязаны менять свое тело - когда вы можете это сделать, тогда у вас слабая связь. Если вы не можете этого сделать, значит, у вас сильная связь.

Это основная концепция в двух словах.

Почему все это важно?

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

Практические примеры сцепления при кодировании

  • Примеры CSV/JSON/DB: Если кто-то хочет выводить его в файл CSV, а не в JSON и т.д., Или если вы хотите переключиться с MySQL на PostGreSQL, вы сможете очень легко внести эти изменения в свой код без необходимость переписывать весь класс и т.д. Другими словами, вы не хотите тесно связывать ваше приложение с конкретной реализацией базы данных (например, Mysql) или с конкретным выводом (например, CSV файлы). Потому что, как это неизбежно в программном обеспечении, изменения придут. Когда они приходят, гораздо проще, если ваши части кода слабо связаны.

  • Пример автозапчастей: Если кто-то хочет свою машину в черном, вам не нужно переделывать всю машину, чтобы сделать это. Автомобиль и его запчасти будут отличным примером слабо связанной архитектуры. Если вы хотите заменить свой двигатель на более качественный, вы сможете просто снять его без особых усилий и заменить его на лучший. Если ваш автомобиль работает только с двигателями Rolls Royce 1234 и без других двигателей - тогда ваш автомобиль будет тесно связан с этим двигателем (Rolls Royce 1234). Было бы лучше, если бы вы изменили конструкцию своего автомобиля, чтобы он работал с любым двигателем, чтобы он был немного слабее связан с его компонентами. Еще лучше было бы, если бы ваша машина могла работать без двигателя вообще! Должна произойти некоторая связь, но вы должны стараться свести ее к минимуму. Почему? Потому что, когда требования меняются, мы все равно должны иметь возможность поставлять качественное программное обеспечение очень быстро, и нам помогает эта цель благодаря слабой связи.

Резюме

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

Полиморфизм и твердые принципы

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

Атрибуция изображения.

Ответ 3

В объектно-ориентированном дизайне количество связей относится к тому, насколько дизайн одного класса зависит от дизайна другого класса. Другими словами, как часто изменения в классе A влияют на изменения в классе B? Плотная связь означает, что два класса часто меняются вместе, свободные связи означают, что они в основном независимы. В общем, рекомендуется использовать свободную муфту, потому что ее легче тестировать и поддерживать.

Вы можете найти эту статью от Мартина Фаулера (PDF).

Ответ 4

Программный разум Разница между жесткой связью и свободной связью

Плотная связь между объектами Java

class Traveler
{
    Car c=new Car();
    void startJourney()
    {
       c.move();
    }
}

class Car
{
  void move()
  {
     // logic...
  }
}

Свободная связь между объектами Java

class Traveler
{
    Vehicle v;
    public void setV(Vehicle v)
    {
      this.v = v;
    }      

    void startJourney()
    {
       v.move();
    }
}

//========================= Интерфейс =================== =================

 Interface Vehicle
    {
       void move();
    }

//========================================================================================================================= Первый class= ===

class Car implements Vehicle
{
    public void move()
    {
         // logic
    }
}

//=================== Второй class= ================

class Bike implements Vehicle
{
    public void move()
    {
         // logic
    }
}

Ответ 5

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

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

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

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

Ответ 6

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

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

Шаблон проектирования наблюдателя - хороший пример для того, чтобы классы были слабо связаны, вы можете посмотреть его в Wikipedia.

Ответ 7

Я понимаю, что плотно связанная архитектура не обеспечивает большую гибкость при изменении по сравнению с слабосвязанной архитектурой.

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

Ответ 8

Выдержка из моего сообщения блога о связи:

Что такое жесткая муфта: -

Как указано выше, Tightly Coupled Object - это объект, который должен знать о других объектах и обычно сильно зависит от интерфейсов друг друга.

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

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

namespace DNSLooseCoupling
{
    public class ShoppingCart
    {
        public float Price;
        public int Quantity;

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

    public class ShoppingCartContents
    {
        public ShoppingCart[] items;

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

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

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

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

Проблемы с приведенным выше примером

Плотная муфта создает некоторые трудности.

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

Ответ 9

Плотное соединение означает, что один класс зависит от другого класса.
Свободная связь означает, что один класс зависит от интерфейса, а не от класса.

В тесной связи существует жестко закодированная зависимость, объявленная в методах.
При слабой связи мы должны передавать зависимость извне во время выполнения, а не жестко закодировать. (Системы слабой пары используют интерфейс для уменьшения зависимости от класса.)

Например, у нас есть система, которая может отправлять вывод двумя или более способами, такими как вывод JSON, вывод CSV и т.д.

Плотно соединенный

public interface OutputGenerator {
    public void generateOutput();
}

public class CSVOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("CSV Output Generator");
    }
}

public class JSONOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("JSON Output Generator");
    }
}

// In Other Code, we write Output Generator like...
public class Class1 {
    public void generateOutput() {
        // Here Output will be in CSV-Format, because of hard-coded code.
        // This method tightly coupled with CSVOutputGenerator class, if we want another Output, we must change this method.
        // Any method, that calls Class1 generateOutput will return CSVOutput, because Class1 is tight couple with CSVOutputGenerator.
        OutputGenerator outputGenerator = new CSVOutputGenerator();
        output.generateOutput();
    }
}

В приведенном выше примере, если мы хотим изменить вывод в JSON, нам нужно найти и изменить весь код, потому что Class1 тесно связан с классом CSVOutputGenerator.

Свободная пара

public interface OutputGenerator {
    public void generateOutput();
}

public class CSVOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("CSV Output Generator");
    }
}

public class JSONOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("JSON Output Generator");
    }
}

// In Other Code, we write Output Generator like...
public class Class1 {
    public void generateOutput(OutputGenerator outputGenerator) {
        // if you want to write JSON, pass object of JSONOutputGenerator (Dependency will be passed externally to this method)
        // if you want to write CSV, pass object of CSVOutputGenerator (Dependency will be passed externally to this method)

        // Due to loose couple with class, we don't need to change code of Class1, because Class1 is loose coupled with CSVOutputGenerator or JSONOutputGenerator class
        // Any method, that calls Class1 generateOutput will desired output, because Class1 does not tight couple with CSVOutputGenerator or JSONOutputGenerator class
        OutputGenerator outputGenerator = outputGenerator;
        output.generateOutput();
    }
}

Ответ 10

Существуют определенные инструменты, которые обеспечивают инъекцию зависимостей через их библиотеку, например, в .net. ninject Library.

Если вы продвигаетесь дальше в java, тогда spring предоставляет эти возможности.

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

Скажите в своем коде, который вы пишете

Myclass m = new Myclass();

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

Ответ 11

Слабая связь означает, что степень зависимости между двумя компонентами очень низкая.
Пример: GSM SIM

Тесная связь означает, что степень зависимости между двумя компонентами очень высока.
Пример: CDMA Mobile

Ответ 12

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

Loose Coupling = IoC Подробнее см. .

Ответ 13

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

Ответ 14

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

Ссылка Разница между Loose Coupling и Tight Coupling в Java с примерами.

Ответ 15

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

Ответ 16

Если создание/существование объекта зависит от другого объекта, который не может быть адаптирован, его плотная связь. И, если зависимость может быть адаптирована, ее свободная связь. Рассмотрим пример в Java:

class Car {

    private Engine engine = new Engine( "X_COMPANY" ); // this car is being created with "X_COMPANY" engine
    // Other parts

    public Car() { 
        // implemenation 
    }

}

Клиент класса Car может создать его с помощью ТОЛЬКО движка "X_COMPANY".

Рассмотрите возможность разрушения этой связи с возможностью ее изменения:

class Car {

    private Engine engine;
    // Other members

    public Car( Engine engine ) { // this car can be created with any Engine type
        this.engine = engine;
    }

}

Теперь Car не зависит от движка "X_COMPANY", поскольку он может быть создан с помощью типов.

Специфическая заметка Java: использование интерфейсов Java только для де-связи - это не правильный подход. В Java интерфейс имеет свою цель - действовать в качестве контракта, который интригически обеспечивает поведение/преимущество де-связи.

Комментарий Билла Розма в принятом ответе имеет хорошее объяснение.

Ответ 17

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

Тесная связь

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

Слабая связь

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

Резюме

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

Так как же это сделать в С#? Интерфейсы и внедрение зависимостей!

РЕДАКТИРОВАТЬ

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