Кохезия (Cohesion) в мобилната разработка: основи, нива и как да я подобрим

Автор: IT Sectr Публикувано: 2026-05-13 Време за четене: 9 мин

Cohesion (кохезия) е метрика, която показва колко тясно са свързани елементите в рамките на един модул или клас. Според Wikipedia, високата кохезия е признак на добре проектиран модул, където всички методи и полета работят по една задача. Cohesion пряко влияе върху поддържаемостта на кода и се противопоставя на coupling — свързаността между модулите.

Основни точки

  • Cohesion — мярка за това доколко елементите в модула са свързани с обща цел
  • Висока кохезия улеснява разбирането на кода, тестването и извършването на промени
  • Ниска кохезия означава, че модулът изпълнява няколко несвързани задачи
  • Cohesion и coupling — взаимосвързани метрики: колкото по-висока е кохезията, толкова по-ниска е свързаността
  • Функционална кохезия — най-високото ниво, към което трябва да се стремим

Какво е Cohesion

Cohesion (кохезия) — метрика, която оценява доколко логически са свързани методите, полетата и свойствата в рамките на един клас или модул. Модул с висока кохезия изпълнява една задача и съдържа само елементите, необходими за нейното изпълнение. Модул с ниска кохезия се опитва да прави няколко неща едновременно — методите са слабо свързани по смисъл.

В контекста на обектно-ориентираното програмиране кохезията е тясно свързана с принципа Single Responsibility (S). Ако класът има една ясна отговорност, неговата кохезия обикновено е висока. Ако класът се занимава и с UI, и с бизнес логика, и с работа в мрежа — кохезията е ниска и такъв клас трябва да се раздели на няколко отделни класа с по-тясна отговорност.

Разбирането на cohesion помага на разработчика да взема решение за рефакторинг. Когато видите, че в класа има метод, който не използва полетата на класа, това е сигнал за ниска кохезия. Такъв метод или е излишен в класа, или класът е неправилно проектиран. Стремежът към висока кохезия е постоянна работа по подобряване на архитектурата на всяко ниво на кода.

Видове и нива на кохезия

В софтуерното инженерство се различават седем нива на кохезия, подредени от най-лошото към най-доброто. Разбирането на тази скала позволява обективна оценка на качеството на модула и разбиране на посоката при рефакторинг. Колкото по-високо е нивото, толкова по-поддържаем и разбираем ще бъде кодът.

Ниска кохезия: случайна, логическа и времева

Случайна (coincidental) — най-лошото ниво, когато елементите в модула са групирани случайно, без каквато и да е логическа връзка. Пример: класът Utilities, в който са събрани методи за форматиране на дата, изпращане на имейл и изчисляване на отстъпка. Такъв клас не може да бъде разбран без четене на всички методи и промяната на един метод може да счупи други само защото се намират заедно.

Логическа (logical) кохезия — елементите изпълняват логически свързани, но различни по същество задачи. Клас с методи parseJSON, parseXML и parseCSV е логически свързан с темата „парсване“, но всеки метод прави принципно различна работа. Проблем: при добавяне на нов формат (YAML) класът расте и неговият интерфейс става надут.

Времева (temporal) кохезия — елементите са групирани според времето на изпълнение. Класът AppInitializer, който настройва базата данни, зарежда конфигурацията, инициализира анализи — всичко това се случва при стартиране на приложението, но самите задачи не са свързани помежду си. По-добре да се разделят на отделни Initializer за всяка зона на отговорност.

Средна кохезия: процедурна и комуникационна

Процедурна (procedural) кохезия възниква, когато елементите са обединени от последователността на изпълнение. Модулът „Обработка на поръчка“ съдържа методи validateCart, processPayment, sendConfirmation — всеки метод се извиква строго след предишния. Това е по-добре от случайната или логическа кохезия, но все още не е идеал: всяка стъпка може да бъде изнесена в отделен модул.

Комуникационна (communicational) кохезия — елементите работят с едни и същи данни. Класът UserService с методи getUser, updateUser, deleteUser е обединен от общата същност User. Това е значително по-добре от процедурната кохезия: класът има ясна предметна област. Повечето Repository класове в мобилни проекти имат комуникационна кохезия.

Висока кохезия: функционална

Функционална (functional) кохезия — най-високото ниво, когато всеки елемент на модула участва в изпълнението на една задача. Класът PasswordValidator с единствен метод validate, който проверява дължината, наличието на символи и сложността на паролата — пример за функционална кохезия. Ако такъв клас се промени, то е само защото са се променили правилата за валидиране на пароли.

Постигането на функционална кохезия е основната цел на архитектурния рефакторинг. Всеки клас трябва да има точно една причина за промяна. В мобилната разработка функционалната кохезия се постига чрез извличане на отделни Use Cases, персонализирани View, форматировачи и валидатори. Всеки такъв клас е завършен градивен блок с ясна зона на отговорност.

Cohesion vs Coupling

Cohesion и coupling — две страни на едно и също качество. Колкото по-висока е кохезията в модула, толкова по-ниска обикновено е свързаността между модулите. Една добре проектирана система едновременно се стреми към висока кохезия отвътре и слаба свързаност отвън. Това правило се счита за фундаментално в софтуерното инженерство от 70-те години на миналия век.

Връзката cohesion-coupling може да се представи като баланс. Ако разработчикът жертва кохезията, обединявайки няколко задачи в един клас, съседните модули получават повече зависимости — те трябва да се обръщат към този претоварен клас за различни цели, което увеличава свързаността. И обратно, разделянето на малки класове с висока кохезия намалява броя на точките на взаимодействие между модулите.

На практика това означава: когато извличате нов клас с функционална кохезия, вие едновременно освобождавате други модули от необходимостта да знаят детайлите на неговата реализация. Например, извличайки EncryptionManager в отделен клас с функционална кохезия, вие давате на другите модули прост интерфейс encrypt/decrypt без необходимост да разбират детайлите на алгоритъма за криптиране.

kotlin
// Ниска кохезия — класът прави всичко наведнъж
class UserManager {
    fun fetchAndSaveUser(id: String) { }
    fun parseUserJson(json: String): User { }
    fun displayUserName(user: User): String { }
    fun validateEmail(email: String): Boolean { }
}

// Висока кохезия — всеки клас решава една задача
class UserRepository {
    fun fetchUser(id: String): User { }
}

class UserJsonParser {
    fun parse(json: String): User { }
}

class UserNameFormatter {
    fun format(user: User): String { }
}

class EmailValidator {
    fun isValid(email: String): Boolean { }
}

Примерът показва разликата: UserManager има логическа кохезия — всички методи са за потребители, но всеки прави принципно различна работа. След рефакторинг всеки клас има функционална кохезия и свързаността намалява, защото другите модули зависят само от класа, от който се нуждаят, а не от целия UserManager.

Как да измерваме кохезията в кода

LCOM (Lack of Cohesion of Methods) — най-известната метрика за измерване на кохезията на клас. LCOM изчислява колко двойки методи не използват общи полета. Стойност 0 означава идеална кохезия (всички методи работят с едни и същи полета), висока стойност означава ниска кохезия. LCOM4 (подобрена версия) отчита транзитивните връзки чрез други методи.

В Android разработката метриките за кохезия могат да бъдат получени чрез Detekt с правило TooManyFunctions. Класове с десет метода, използващи различни групи полета, най-вероятно имат ниска кохезия. В iOS SwiftLint има правила file_length и function_body_length — косвени индикатори: дългите файлове и методи често сигнализират за ниска кохезия.

Ръчен начин за оценка: задайте въпроса „Този клас ще се промени по една причина или по няколко?“ Ако можете да посочите повече от една независима причина — класът има ниска кохезия. Втори тест: „Може ли този клас да се раздели на два независими класа?“ Ако да — направете го. Редовната проверка на кохезията при код-ревю предотвратява появата на God класове и намалява техническия дълг.

Как да подобрим Cohesion в мобилен проект

Първа стъпка — приложете принципа Single Responsibility. Всеки клас трябва да има една ясна отговорност. Ако в класа има метод, който не се отнася до основната му задача, изнесете го в отделен клас. Техниката Extract Class или Extract Delegate в IDE автоматизира този процес. След извличането проверете дали оригиналният клас е станал по-фокусиран.

Втора стъпка — използвайте шаблона Facade за опростяване на интерфейса. Ако клас предоставя 20 метода, от които клиентите използват само 3-4, вероятно класът има ниска кохезия — предоставя твърде много различна функционалност. Групирайте методите по теми и извлечете отделни класове за всяка група, а оригиналния клас направете фасада или го премахнете.

Трета стъпка — обърнете внимание на групите полета. Ако класът има полета, които се използват само от част от методите — това е индикатор за ниска кохезия. Разделете класа по групи полета. Например, ако класът съдържа полета userRepository, networkClient и analyticsTracker, но методите от първата група използват само userRepository, а от втората — само networkClient, това са два различни класа.

Четвърта стъпка — избягвайте създаването на „помощни“ класове с произволни статични методи. Всеки статичен метод, намиращ се в клас Utils или Helpers, е кандидат за извличане в специализиран клас. FormatUtils.dateToString е по-добре да се премести в DateFormatter, а ValidationUtils.isValidEmail — в EmailValidator. Това повишава кохезията на всеки клас и прави кода самодокументиращ се.

Често задавани въпроси

Винаги ли високата кохезия е нещо добро?

Почти винаги. Функционалната кохезия прави кода разбираем и предвидим. Прекаляването обаче може да доведе до прекомерно раздробяване: когато за всяка операция се създава отделен клас и архитектурата става излишно сложна. Баланс — няколко класа на функционалност, всеки с функционална кохезия.

Как кохезията се различава от модуларността?

Cohesion — метрика за вътрешна съгласуваност на един модул или клас. Modularity — архитектурен принцип, при който приложението се разделя на физически модули. Високата кохезия е цел при проектирането както на отделни класове, така и на цели модули.

Как инструментите за анализ на код помагат с кохезията?

Detekt за Android и Xcode Analyzer за iOS подчертават класове с подозрително голям брой методи или полета. IntelliJ IDEA и AppCode имат визуализация на зависимостите — можете да видите графа на връзките и да откриете класове с ниска кохезия. SonarQube изчислява LCOM метриките автоматично.

Може ли интерфейсът да има висока кохезия?

Да. Интерфейс с методи connect, disconnect и isConnected има висока кохезия — всички методи се отнасят до управлението на връзката. Интерфейс с методи connect, parseData и renderUI има ниска кохезия. Принципът Interface Segregation (SOLID) изисква създаването на тясно специализирани интерфейси с висока кохезия.

Как да проверим кохезията при код-ревю?

Задайте три въпроса: може ли предназначението на класа да се опише с едно изречение? Всички методи поддържат ли това предназначение? Има ли в класа полета, които не се използват от част от методите? Ако отговорът на някой въпрос е отрицателен — кохезията е ниска и класът трябва да се раздели.

Резюме

  • Cohesion — метрика за вътрешна съгласуваност на модула, показваща доколко неговите елементи са свързани с обща цел
  • Функционална кохезия — най-високото ниво, когато всички елементи на модула работят по една задача
  • Случайната и логическата кохезия са най-лошите нива, сигнализиращи за необходимост от рефакторинг
  • Cohesion и coupling са обратно пропорционални: колкото по-висока е кохезията отвътре, толкова по-слаба е свързаността отвън
  • LCOM — метрика за числена оценка на кохезията, достъпна в статичните анализатори
  • Single Responsibility Principle — практически инструмент за постигане на висока кохезия
  • Избягвайте помощните класове Utils — всеки метод на такъв клас трябва да стане отделен специализиран клас

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също