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

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

Ответы [ 15 ]

303 голосов
/ 14 мая 2010

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

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

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

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

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

Пример плотного сцепления:

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)
    {
    }
}

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

142 голосов
/ 23 июня 2016

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

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

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

The Hat is

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

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

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

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

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

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

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

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

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

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

Практические примеры связи в вычислительной технике

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

Другой пример: аналог автомобиля и запасных частей сцепления

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

Резюме

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

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

65 голосов
/ 14 мая 2010

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

Вы можете найти этот документ Мартина Фаулера (PDF) полезным.

13 голосов
/ 08 октября 2012

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

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

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

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

9 голосов
/ 09 января 2012

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

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

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

5 голосов
/ 18 сентября 2014

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

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

4 голосов
/ 21 марта 2015

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

Что такое Плотное соединение : -

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

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

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

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() дают нам полную сумму для текущих предметов тележек. Если мы хотим добавить функции скидок в эту систему корзины. Это очень сложно сделать в приведенном выше коде, потому что мы должны вносить изменения в каждый класс, так как он очень тесно связан.

3 голосов
/ 01 июня 2017

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

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

3 голосов
/ 16 июня 2012

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

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

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

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

Myclass m = new Myclass();

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

2 голосов
/ 28 февраля 2018

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

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

Например, у нас есть система, которая может отправлять вывод двумя или более способами, такими как вывод 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's 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's generateOutput will desired output, because Class1 does not tight couple with CSVOutputGenerator or JSONOutputGenerator class
        OutputGenerator outputGenerator = outputGenerator;
        output.generateOutput();
    }
}
...