Що таке висока згуртованість і як її використовувати / зробити?


84

Я вивчаю комп'ютерне програмування, і в декількох місцях я натрапив на концепцію згуртованості і розумію, що бажано, щоб програмне забезпечення мало "високу згуртованість", але що це означає? Я програміст на Java, C та Python, що вивчаю C ++ із книги C ++ Primer, в якій згадується згуртованість, не маючи її в індексі, чи можете ви вказати мені кілька посилань на цю тему? Я не знайшов сторінки вікіпедії про згуртованість інформатики інформативною, оскільки там просто сказано, що це якісний показник і не наводиться реальних прикладів коду.



3
Висока згуртованість: пов'язана поведінка, щоб сидіти разом, і не пов'язана поведінка сидіти в іншому місці
Teoman shipahi

Відповіді:


240

Висока згуртованість - це коли у вас є клас, який виконує чітко визначену роботу. Низька згуртованість - це коли клас виконує багато робіт, які не мають багато спільного.

Візьмемо цей приклад:

У вас є клас, який додає два числа, але той самий клас створює вікно, що відображає результат. Це низький згуртований клас, оскільки вікно та операція додавання не мають багато спільного. Вікно - це візуальна частина програми, а функція додавання - це логіка, що стоїть за нею.

Щоб створити високе зв’язане рішення, вам слід створити клас Window і клас Sum. У вікні буде викликаний метод Sum, щоб отримати результат і відобразити його. Таким чином ви окремо розробите логіку та графічний інтерфейс свого додатка.


14
Чесно кажучи, я не визначаю згуртованість так. Ваше визначення - SRP (принцип єдиної відповідальності). І згуртованість полягає в тому, близькі між собою пакувальні класи, що мають однакову функцію, чи близькі вони один до одного чи ні.
v.oddou

4
SRP (Принцип єдиної відповідальності) - це лише ще один спосіб вираження тієї самої концепції. Згуртованість - це скоріше метрика; SRP - це прагматичне керівництво, яке, якщо його дотримуватись, призведе до згуртованих занять.
ComDubh

3
Я думаю, що вікно класу не повинно викликати будь-який об'єкт класу sum, оскільки його єдиною метою є надання йому не потрібно знати про "існування" класу sum або будь-якого іншого класу. Має бути інший клас, скажімо Driver, який повинен отримати результат від класу sum і передасть результат у вікно класу для візуалізації
Eklavyaa

1
Я не розумію. Це не згуртованість згідно чистого коду дядька Боба. Це SRP
karlihnos

Дуже акуратне пояснення! Дякуємо
Вінсент Ллаудерес

55

Пояснення того, що це таке, з Кодексу Стіва Макконнелла :

Згуртованість означає, наскільки всі підпрограми в класі або весь код у підпрограмі підтримують центральну мету . Класи, що містять сильно пов'язані функціональні можливості , описуються як такі, що мають сильну згуртованість, і евристична мета полягає в тому, щоб зробити згуртованість якомога сильнішою. Згуртованість є корисним інструментом управління складністю, оскільки чим більше коду в класі підтримує центральну мету, тим легше ваш мозок запам'ятовує все, що робить код.

Якийсь спосіб досягти цього з чистого коду дядька Боба :

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

Як правило, не бажано і не можливо створювати такі максимально згуртовані класи; з іншого боку, ми хотіли б, щоб згуртованість була високою. Коли згуртованість висока, це означає, що методи та змінні класу взаємозалежні та виступають разом як логічне ціле.

Поняття згуртованості тісно пов'язане з поняттям зчеплення; також існує принцип, заснований на евристиці високої згуртованості, названий Принципом єдиної відповідальності (S від SOLID).


1
Я думаю, що ваша відповідь є більш повною, ніж прийнята, оскільки вона описує як SRP, так і згуртованість, і тому вона допомагає зрозуміти особливості та відмінності між цими двома поняттями.
The Once-ler

18

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

Приклад цілком суб'єктивний, оскільки ми також повинні враховувати масштаб. Просту програму не слід занадто модулювати або вона буде фрагментована; тоді як складна програма може потребувати більшого рівня абстракцій, щоб подбати про складність.

напр. клас електронної пошти. Він повинен містити дані членів від, cc, bcc, subject, body і може містити ці методи saveAsDraft (), send (), discardDraft (). Але login () тут бути не повинно, оскільки існує низка протоколів електронної пошти, і їх слід реалізовувати окремо.


Це визначення SRP: "клас повинен робити лише те, що він повинен робити, і робить це повністю".
AliN11

11

Як правило, згуртованість вимірюється за допомогою однієї з метрик LCOM (Відсутність згуртованості), оригінальна метрика LCOM надійшла від Чідамбера та Кемерера. Див. Наприклад: http://www.computing.dcu.ie/~renaat/ca421/LCOM.html

Більш конкретний приклад: якщо клас має, наприклад, одне приватне поле та три методи; коли всі три методи використовують це поле для виконання операції, тоді клас дуже згуртований.

Псевдо-код згуртованого класу:

class FooBar {
  private SomeObject _bla = new SomeObject();

  public void FirstMethod() {
    _bla.FirstCall();
  }

  public void SecondMethod() {
    _bla.SecondCall();
  }

  public void ThirdMethod() {
    _bla.ThirdCall();
  }
}

Якщо клас має, наприклад, три приватні поля та три методи; коли всі три методи використовують лише одне з трьох полів, тоді клас погано зв’язаний.

Псевдо-код слабо когезійного класу:

class FooBar {
  private SomeObject _bla = new SomeObject();
  private SomeObject _foo = new SomeObject();
  private SomeObject _bar = new SomeObject();

  public void FirstMethod() {
    _bla.Call();
  }

  public void SecondMethod() {
    _foo.Call();
  }

  public void ThirdMethod() {
    _bar.Call();
  }
}

Принцип класу, який робить одне, - це принцип єдиної відповідальності, який походить від Роберта К. Мартіна і є одним із ТВЕРДИХ принципів. Принцип передбачає, що клас повинен мати лише одну причину для зміни.

Дотримання близького принципу єдиної відповідальності може призвести до створення більш згуртованого кодексу, але, на мій погляд, це дві різні речі.


4

Це приклад низької згуртованості:

class Calculator
{


     public static void main(String args[])
     {

          //calculating sum here
          result = a + b;
          //calculating difference here
          result = a - b;
          //same for multiplication and division
     }
}

Але висока згуртованість передбачає, що функції в класах виконують те, що вони повинні робити (як їх називають). А не якась функція, яка виконує роботу якоїсь іншої функції. Отже, наступним може бути прикладом високої згуртованості:

class Calculator
{


     public static void main(String args[])
     {

          Calculator myObj = new Calculator();
          System.out.println(myObj.SumOfTwoNumbers(5,7));
      }


     public int SumOfTwoNumbers(int a, int b)
     {

          return (a+b);
     }

     //similarly for other operations

}

3

Загальний спосіб думати про принцип згуртованості полягає в тому, що ви повинні знаходити код разом з іншим кодом, який або залежить від нього, або від якого він залежить. Згуртованість може і повинна застосовуватися до рівнів композиції вище рівня класу. Наприклад, пакет або простір імен в ідеалі повинні містити класи, які відносяться до якоїсь загальної теми і які в більшій мірі взаємозалежні, ніж залежать від інших пакетів / просторів імен. Тобто зберігати залежності локальними.


1

згуртованість означає, що клас або метод виконують лише одну визначену роботу. назва методу або класу також має бути зрозумілою. наприклад, якщо ви пишете калькулятор, вам слід назвати клас "калькулятор", а не "asdfghj". також вам слід подумати про створення методу для кожного завдання, наприклад, віднімання () додавання () тощо ... програміст, який може використовувати вашу програму в майбутньому, точно знає, що роблять ваші методи. хороше іменування може зменшити зусилля щодо коментування

також принцип СУХИЙ - не повторюйся


1

Термін згуртованість спочатку використовувався для опису модулів вихідного коду як якісного показника того, наскільки добре вихідний код модуля був пов'язаний між собою. Ідея згуртованості використовується в різних сферах. Наприклад, група людей, таких як військова частина, може бути згуртованою, тобто люди в підрозділі працюють разом задля досягнення спільної мети.

Суть згуртованості вихідного коду полягає в тому, що вихідний код модуля працює разом для досягнення спільної, чітко визначеної мети. Мінімальна кількість вихідного коду, необхідна для створення вихідних даних модуля, знаходиться в модулі і не більше. Інтерфейс чітко визначений, і входи надходять через інтерфейс, а виходи повертаються назад через інтерфейс. Побічних ефектів немає, і акцент робиться на мінімалізмі.

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

Модулем може бути клас на об'єктно-орієнтованій мові або функція на функціональній мові або необ'єктно-орієнтованій мові, такі як C. Більша частина оригінальної роботи в цій галузі вимірювання згуртованості, в основному, включає роботу з програмами COBOL в IBM ще в 1970-х, тому згуртованість - це, безумовно, не просто об’єктно-орієнтована концепція.

Первинним наміром дослідження, з якого виникла концепція згуртованості та пов’язана з ним концепція взаємозв’язку, було дослідження того, де особливості програм, які було легко зрозуміти, підтримувати та розширювати. Метою було мати можливість вивчити найкращі практики програмування, кодифікувати ці найкращі практики, а потім навчити практик інших програмістів.

Метою хороших програмістів є написання вихідного коду, згуртованість якого є якомога більшою, враховуючи середовище та проблему, що вирішується. Це означає, що у великій програмі деякі частини тіла вихідного коду будуть відрізнятися від інших частин за рівнем згуртованості вихідного коду в цьому модулі або класі. Деколи найкраще, що ви можете отримати, це тимчасова або послідовна згуртованість через проблему, яку ви намагаєтесь вирішити.

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

Багато бібліотек мови програмування містять ряд прикладів функціональних модулів, будь то класи, шаблони чи функції. Найбільш функціональними згуртованими прикладами можуть бути математичні функції, такі як гріх, косинус, квадратний корінь тощо.

Інші функції можуть мати побічні ефекти або підтримувати якийсь стан, що призводить до ускладнення використання цих функцій.

Наприклад, функція, яка видає виняток або встановлює глобальну змінну помилки ( errnoв C), або її потрібно використовувати в послідовності ( strtok()функція є прикладом із стандартної бібліотеки C, оскільки вона підтримує внутрішній стан), або яка надає покажчик, який повинен потім керуватися або видавати журнал до якоїсь утиліти журналу - це все приклади функції, яка більше не є функціональною цілісністю.

Я прочитав оригінальну книгу Вайдона та Костянтина "Структурне програмування", де вперше зіткнувся з ідеєю згуртованості у 1980-х і книгою Мейлір Пейдж-Джонс "Практичний посібник з проектування структурованих систем", і Пейдж-Джонс набагато краще описав як зчеплення, так і згуртованість. Книга Вайдона та Костянтина видається дещо більш академічною. Книга Стіва Макконнелла "Code Complete" є досить хорошою і практичною, і в переглянутому виданні можна сказати чимало про добру практику програмування.


Ви кажете, що The minimum amount of source code needed to create the module outputs is in the module and no moreце пов’язано не з згуртованістю, а з DTSTTCPW
v.oddou

@ v.oddou, мінімальна кількість коду справді пов'язана зі згуртованістю. Чим більше коду в модулі, який не пов'язаний з модулем, виводить, тим більша ймовірність коду має побічні ефекти, отже, нижча згуртованість. Кожне поняття має різні точки зору, особливо такі поняття, як згуртованість, які є дещо неоднозначними. Вимірювання згуртованості якісні, що вимагають певної нечіткої логіки, щоб віднести певний модуль до тієї чи іншої категорії за допомогою певної рубрики. Висловлення мінімального коду для виходів не є достатньою характеристикою для високої згуртованості лише одного з декількох.
Річард Чемберс,

1

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

Класи повинні мати невелику кількість змінних екземпляра. Кожен із методів класу повинен маніпулювати однією або кількома із цих змінних. Загалом, чим більше змінних метод маніпулює, тим ціліснішим цей метод є для свого класу. Клас, в якому кожна змінна використовує кожну змінну, є максимально згуртованим. Як правило, не бажано і не можливо створювати такі максимально згуртовані класи; з іншого боку, ми хотіли б, щоб згуртованість була високою. Коли згуртованість висока, це означає, що методи та змінні класу взаємозалежні та виступають разом як логічне ціле.

Дозвольте пояснити це визначенням класу

class FooBar {
private _bla;
private _foo;
private _bar;

function doStuff()

   if(this._bla>10){
     this._foo = 10;
     this._bar = 20;
   }

}
function doOtherStuff(){

    if(this._foo==10){
       this._bar = 100;
       this._bla = 200;
    }
}

}

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.