Коротше кажучи, щоразу, коли ви використовуєте "new", ви щільно з'єднуєте клас, що містить цей код, з об'єктом, який створюється; для того, щоб створити один з цих об'єктів, клас, який робить інстанцію, повинен знати про конкретний клас, який інстанціюється. Отже, використовуючи "new", ви повинні врахувати, чи клас, у який ви розміщуєте екземпляр, є "хорошим" місцем для проживання цих знань, і ви готові внести зміни в цю область, якщо форма об'єкт, який інстанціюється, повинен був змінитися.
Не завжди слід уникати щільного зчеплення, тобто предмета, що володіє знаннями іншого конкретного класу; на деякому рівні дещо, ДЕЙШЕ, повинно знати, як створити цей об’єкт, навіть якщо все інше має справу з об'єктом, надаючи його копію з іншого місця. Однак, коли клас, який створюється, змінюється, будь-який клас, який знає про конкретну реалізацію цього класу, повинен бути оновлений, щоб правильно боротися зі змінами цього класу.
Питання, яке вам слід завжди задавати, - це: "Чи буде цей клас знати, як створити цей інший клас, стане відповідальністю при підтримці програми?" Обидві основні методології проектування (SOLID та GRASP) зазвичай відповідали "так" з тонко різних причин. Однак це лише методології, і обидві мають крайнє обмеження, що вони не були сформульовані на основі знань вашої унікальної програми. Таким чином, вони можуть помилятися лише на стороні обережності, і припускати, що будь-яка точка щільного з’єднання НАРУЧНО спричинить вам проблему, пов’язану із внесенням змін в ту чи іншу сторону цієї точки. Ви повинні прийняти остаточне рішення, знаючи три речі; найкраща теоретична практика (яка полягає в тому, щоб вільно з'єднати все, тому що все може змінитися); витрати на впровадження теоретичної найкращої практики (яка може включати кілька нових шарів абстрагування, що полегшить зміну одного типу, перешкоджаючи іншому); і реальна ймовірність того, що тип змін, який ви передбачаєте, коли-небудь буде необхідний.
Деякі загальні вказівки:
Уникайте тісного з'єднання між зібраними бібліотеками кодів. Інтерфейс між DLL (або EXE та його DLL) є головним місцем, де щільна муфта представлятиме недолік. Якщо ви внесете зміни до класу A в DLL X, а клас B в основному EXE знає про клас A, вам доведеться перекомпілювати та випустити обидва бінарні файли. У межах одного двійкового файла більш жорстке з'єднання, як правило, є більш допустимим, оскільки весь бінарний файл повинен бути відновлений для будь-якої зміни. Іноді необхідність відновлення декількох бінарних файлів неминуча, але ви повинні структурувати свій код так, щоб уникнути цього, де це можливо, особливо в ситуаціях, коли пропускна здатність переважає (наприклад, розгортання мобільних додатків; натискання нової DLL в оновлення набагато дешевше ніж натискання на всю програму).
Уникайте тісних зв'язків між основними "логічними центрами" вашої програми. Ви можете думати про добре структуровану програму, що складається з горизонтальних і вертикальних фрагментів. Горизонтальні зрізи можуть бути традиційними рівнями додатків, такими як інтерфейс користувача, контролер, домен, DAO, дані; вертикальні фрагменти можуть бути визначені для окремих вікон або представлень, або для окремих "історій користувачів" (наприклад, створення нового запису якогось базового типу). Під час здійснення дзвінка, який рухається вгору, вниз, вліво або вправо у добре структурованій системі, слід загалом абстрагувати зазначений виклик. Наприклад, коли під час перевірки потрібно отримати дані, вона не повинна мати доступ до БД безпосередньо, але повинна робити виклик до інтерфейсу для пошуку даних, який підтримується фактичним об'єктом, який знає, як це зробити. Коли деякий елемент управління користувачем інтерфейсу повинен виконувати розширену логіку, що включає інше вікно, він повинен абстрагувати запуск цієї логіки через подію та / або зворотний виклик; не потрібно знати, що буде зроблено в результаті, що дозволяє змінити те, що буде зроблено, не змінюючи керування, яке його запускає.
У будь-якому випадку, подумайте, наскільки легкими чи важкими будуть зміни, і наскільки ймовірними будуть ці зміни. Якщо об'єкт, який ви створюєте, використовується коли-небудь з одного місця, і ви не передбачаєте цього зміни, то щільне з'єднання, як правило, є більш допустимим, і навіть може перевершити в цій ситуації над нещільним зчепленням. Вільне сполучення вимагає абстрагування, що є додатковим шаром, який перешкоджає зміні залежних об'єктів, коли реалізація залежності повинна змінюватися. Однак якщо сам інтерфейс повинен змінитися (додавання нового виклику методу або додавання параметра до вже існуючого виклику методу), то інтерфейс фактично збільшує обсяг роботи, необхідний для внесення змін. Ви повинні зважити ймовірність різних типів змін, що впливають на дизайн,