Можно ли описать точную разницу между свободной связью и плотной связью в объектно-ориентированной парадигме?
В чем разница между свободной связью и плотной связью в объектно-ориентированной парадигме?
Ответ 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
Объяснение без ЛЮБОГО кода
Сводный пример:
Шляпа "слабо связана" с телом. Это означает, что вы можете легко снять шляпу, не внося никаких изменений в человека/тело. Когда вы можете сделать это, у вас есть "слабая связь". Смотрите ниже для уточнения.
Герметичное соединение (подробный пример)
Подумай о своей коже. Это прилипло к вашему телу. Это подходит как перчатка. Но что, если вы хотите изменить цвет вашей кожи, скажем, с белого на черный? Можете ли вы представить себе, насколько больно было бы отслоить кожу, покрасить ее, а затем приклеить обратно и т.д.? Изменить кожу сложно, потому что она тесно связана с вашим телом. Вы просто не можете легко вносить изменения. Вы должны кардинально изменить дизайн человека, чтобы сделать это возможным.
- Ключевой момент № 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, где глаза - это класс, который мы украшаем, отвечая требованиям интерфейса, но предоставляя различные функциональные возможности (например, солнцезащитные очки, очки для чтения, лупы для ювелиров и т.д.)