Что такое высокая сплоченность и как ее использовать / делать?


84

Я изучаю компьютерное программирование, и в нескольких местах я наткнулся на концепцию сплоченности и понимаю, что желательно, чтобы программное обеспечение имело «высокую сплоченность», но что это значит? Я программист на Java, C и Python, изучаю C ++ из книги C ++ Primer, в которой упоминается сплоченность без ее включения в указатель. Не могли бы вы указать мне несколько ссылок по этой теме? Я не нашел страницу в Википедии о сплоченности информатики информативной, поскольку она просто говорит, что это качественная мера, и не дает реальных примеров кода.



3
Высокая сплоченность: связанное поведение - сидеть вместе и несвязанное поведение - сидеть в другом месте.
Теоман Шипахи

Ответы:


242

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

Возьмем этот пример:

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

Чтобы создать высоко связное решение, вам нужно будет создать класс Window и класс Sum. Окно вызовет метод Sum, чтобы получить результат и отобразить его. Таким образом вы разработаете отдельно логику и графический интерфейс вашего приложения.


14
Честно говоря, я не так определяю Сплоченность. Ваше определение - SRP (принцип единой ответственности). А сплоченность - это то, насколько близки друг к другу классы, ориентированные на один и тот же набор функций, или нет.
v.oddou 08

4
SRP (принцип единой ответственности) - это просто еще один способ выражения той же концепции. Сплоченность - это скорее показатель; SRP - это прагматическое руководство, которое, если следовать ему, приведет к сплоченности классов.
ComDubh

3
Я думаю, что окно класса не должно вызывать какой-либо объект суммы классов, поскольку его единственная цель - отобразить, что ему не нужно знать о «существовании» суммы класса или любого другого класса. Должен быть другой класс, скажем Драйвер, который должен получить результат от класс суммы и передаст результат в класс Window для рендеринга
Eklavyaa

1
Я не понимаю. Это не сплоченность в соответствии с чистым кодом дяди Боба. Это SRP
karlihnos

Очень изящное объяснение! Спасибо
Винсент Ллаудерес

55

Объяснение того, что это такое, из полного кода Стива МакКоннелла :

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

Один из способов добиться этого из Чистого кода дяди Боба :

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

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

Понятие сплоченности тесно связано с понятием связи; Кроме того, существует принцип, основанный на эвристике высокой сплоченности, который называется Принцип единой ответственности (S от SOLID).


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

18

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

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

например, класс электронной почты. Он должен содержать элементы данных to, from, 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». также вам следует подумать о создании метода для каждой задачи, например subtract () add () и т. д. ... программист, который может использовать вашу программу в будущем, точно знает, что делают ваши методы. хорошее именование может уменьшить усилия по комментированию

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


1

Термин «сплоченность» изначально использовался для описания модулей исходного кода как качественной меры того, насколько хорошо исходный код модуля связан друг с другом. Идея сплоченности используется в самых разных областях. Например, группа людей, такая как военное подразделение, может быть сплоченной, что означает, что люди в подразделении работают вместе для достижения общей цели.

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

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

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

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

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

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

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

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

Например, функция, которая генерирует исключение или устанавливает глобальную переменную ошибки ( 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это связано не с Cohesion, а с DTSTTCPW
v.oddou

@ v.oddou, минимальное количество кода действительно связано с Cohesion. Чем больше кода в модуле, не связанного с модулем, выводит, тем больше вероятность, что код имеет побочные эффекты, следовательно, ниже Cohesion. Каждая концепция имеет разные точки зрения, особенно такие концепции, как Cohesion, которые несколько неоднозначны. Измерения Сплоченности являются качественными, и для этого требуется некая нечеткая логика для отнесения конкретного модуля к той или иной категории с использованием какой-либо рубрики. Сказание минимального кода для выходов не является достаточной характеристикой для высокой сплоченности - это всего лишь одна из нескольких характеристик.
Ричард Чемберс

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.