SRP: шта је то, принцип јединствене одговорности у развоју

Аутор: IT Sectr Објављено: 2026-05-11 Време читања: 9 мин

SRP (Single Responsibility Principle) — први принцип SOLID-а који одређује: свака класа или модул треба да има тачно један разлог за промену. Овај принцип је формулисао Роберт Мартин у књизи Clean Architecture (2017) и постао је темељ модуларног пројектовања. Према подацима из ове књиге, примена SRP директно смањује повезаност компоненти и елиминише каскадне промене при допуни функционалности.

Главно

  • SRP — први принцип SOLID-а, захтева једну одговорност по класи
  • Разлог промене — једини критеријум за издвајање одговорности у модул
  • Кршење SRP доводи до повезаног кода који је тешко тестирати и проширивати
  • Примена принципа поједностављује рефакторисање и смањује ризик од регресивних грешака
  • SRP у мобилном развоју помаже у раздвајању логике UI, пословних правила и рада са подацима

Шта је SRP (Single Responsibility Principle)?

SRP (Single Responsibility Principle) — принцип јединствене одговорности који каже: свака класа или модул треба да има тачно један разлог за промену. То не значи да класа треба да обавља тачно једну операцију. Реч је о групи повезаних радњи, обједињених једном одговорношћу према једном актору.

Роберт Мартин је преформулисао SRP у терминима актора: класа треба да се мења само на захтев једне заинтересоване особе или једне групе људи. Ако два различита актора захтевају промену исте класе — одговорност је подељена неправилно.

На пример, класа Employee, која истовремено израчунава плату (захтев рачуноводства) и генерише извештај (захтев менаџмента), крши SRP. Промена правила обрачуна може утицати на генерисање извештаја и обрнуто.

Формална дефиниција SRP

Модул треба да има један и само један разлог за промену. Разлог промене одређује актор — особа или систем који покреће захтев. Ако захтеви од различитих актора доводе до промене истог модула — модул крши SRP.

Концепт актора чини SRP практичним алатом за архитектонску анализу, а не апстрактном препоруком. При пројектовању система довољно је поставити питање: „Ко ће тражити промену овог кода?“ — ако одговор садржи више од једне заинтересоване особе, одговорност треба поделити.

Како функционише принцип јединствене одговорности

Јединствена одговорност се реализује кроз груписање метода које се мењају из једног разлога. Класа постаје „тачка прикупљања“ повезане логике, а не „швајцарски нож“ за све прилике. То поједностављује разумевање кода: програмер види класу и одмах разуме њену намену.

Механизам рада SRP заснива се на правилу једне осе промене. Ако се функционалност може мењати из независних разлога — треба је извући у засебне класе. Везе између ових класа граде се кроз композицију или делегирање.

Кршење SRP се манифестује у „класама-боговима“ (God Objects), које садрже десетине метода које раде са различитим подацима. Такву класу је тешко тестирати — тест једне методе захтева подешавање окружења за све остале. Промена једне одговорности може покварити другу, што чини код крхким.

У пракси, SRP помаже програмерима да одговоре на питање „где се налази овај код?“. Ако је свака одговорност издвојена у своју класу, проналажење потребног фајла траје секунде. У Android пројекту са MVVM архитектуром то значи да UserViewModel одговара само за стање екрана корисника, а UserRepository — за преузимање података. Програмер који тражи логику кеширања иде у UserCacheRepository, а не у ViewModel. Таква организација кода убрзава укључивање нових чланова тима и смањује број грешака при рефакторисању.

Зашто је SRP важан у мобилном развоју

Мобилни развој поставља посебне захтеве за модуларност кода. Android Fragment или iOS ViewController често постају „тачке привлачења“ логике: обрада кликова, позив API-ја, парсирање одговора, ажурирање UI — све у једној класи. SRP захтева раздвајање ових одговорности.

У Android архитектури, SRP је уграђен у Google-ове препоруке за Jetpack: ViewModel одговара за стање екрана, Repository — за податке, UseCase — за пословну логику. Свака компонента има један разлог за промену. У iOS развоју образац MVVM и Coordinator следе исту логику.

Поштовање SRP у мобилним пројектима даје мерљиве предности: смањење величине класа за 40-60%, скраћење времена за код-преглед и смањење броја регресивних грешака при додавању нове функционалности. Изоловани модули се лакше покривају unit-тестовима и поново користе у другим екранима.

Утицај SRP на тестирање

Unit-тестирање класа које поштују SRP захтева мање mock-објеката и подешавања. Ако класа има једну одговорност, њене зависности су ограничене. Тест проверава једно понашање, а не комбинацију више неповезаних сценарија.

Према извештају Google Testing Blog (2023), класе са јединственом одговорношћу показују 35% већу покривеност тестовима у поређењу са класама-агрегаторима. Програмери радо пишу тестове за мале, разумљиве модуле.

Примери SRP у Android и iOS

Размотримо типичну Android класу која крши SRP — и учитава податке, и парсира одговор, и ажурира UI. Након рефакторисања, свака одговорност је издвојена у посебну компоненту.

kotlin
// Кршење SRP: једна класа ради све
class BadUserProfileActivity {
    fun loadUser(userId: Int) {
        // HTTP захтев
        // Парсирање JSON
        // Ажурирање UI
        // Чување у бази
    }
}

// Након примене SRP
class UserRepository {
    fun getUser(userId: Int): User
}

class UserViewModel {
    private val repo: UserRepository
    fun loadUser(userId: Int) { }
}

class UserProfileFragment {
    fun render(user: User) { }
}

Аналогичан пример на iOS Swift са раздвајањем мрежног слоја и слоја приказа:

swift
// Кршење SRP: ViewController управља подацима и UI
class BadProfileViewController: UIViewController {
    func viewDidLoad() {
        // URLSession захтев
        // Декодирање JSON
        // Ажурирање label
    }
}

// Након примене SRP
protocol UserServiceProtocol {
    func fetchUser(id: Int) async throws -> User
}

class ProfileViewModel {
    private let service: UserServiceProtocol
    func loadProfile(id: Int) { }
}

class ProfileViewController: UIViewController {
    func display(user: User) { }
}

Рефакторисање SRP не компликује архитектуру — прерасподељује одговорност. Количина кода се чак може смањити елиминацијом дуплирања. Свака нова класа има јасну намену и може се развијати независно.

Композиција као алтернатива наслеђивању

Композиција помаже у поштовању SRP тамо где наслеђивање ствара непотребне повезаности. Уместо суперкласе са десетинама метода, подкласа добија скуп специјализованих објеката кроз конструктор. Сваки објекат одговара за своју функционалност.

У Android развоју, образац Decorator омогућава додавање одговорности без промене оригиналне класе. У iOS-у, ланац Middleware у мрежном слоју раздваја логирање, кеширање и аутентификацију на засебне модуле.

Типична кршења SRP и њихове последице

Најчешће кршење — „God Class“: класа која управља базом података, шаље обавештења, генерише извештаје и обрађује кориснички унос. Таква класа постаје уско грло пројекта: свака промена захтева потпуно регресивно тестирање.

У мобилном развоју, кршење SRP доводи до мешања пословне логике и UI логике у Activity, Fragment или ViewController. Када onClickListener метод истовремено валидира податке, позива API и ажурира видљивост дугмади — то је директно кршење принципа јединствене одговорности.

Последице кршења SRP укључују: отежано паралелно програмирање (конфликти у истом фајлу), отежано unit-тестирање, високу цену измена и смањену читљивост кода. Пројекти са систематским кршењем SRP захтевају 2-3 пута више времена за додавање нове функционалности.

Индикатори кршења SRP у коду

Кршење SRP може се одредити по посредним знацима: класа садржи више од 200 линија, увози модуле из различитих слојева апликације (UI + network + database), има више од 5 јавних метода са различитом тематиком. Метрика повезаности (cohesion) — статистички показатељ: ниска повезаност метода унутар класе указује на кршење SRP.

За откривање SRP кршења корисно је користити алате статичке анализе: за Android — Detekt са правилом TooManyFunctions, за iOS — SwiftLint са правилом file_length. Ови алати истичу класе које прелазе граничне вредности величине и сложености.

Рефакторисање класа које крше SRP врши се кроз Extract Class или Extract Delegate: група повезаних метода се извлачи у засебну класу, а оригинална класа им делегира позиве. Постепена примена таквих рефакторисања претвара „God Class“ у скуп слабо повезаних модула, сваки са једном одговорношћу. Такав приступ омогућава побољшање архитектуре без заустављања развоја — рефакторисање се изводи итеративно, по један модул истовремено.

Често постављана питања

Да ли SRP значи да класа треба да садржи једну методу?

Не. SRP није о броју метода, већ о броју разлога за промену. Класа може имати десет метода ако све оне опслужују једну одговорност према једном актору. Једна метода — друга је крајност која води ка претераном уситњавању кода.

По чему се SRP разликује од принципа јединствене обавезе?

То је исти принцип. Single Responsibility Principle се преводи и као „јединствена одговорност“ и као „јединствена обавеза“. Термин „одговорност“ тачније одражава суштину: реч је о одговорности према актору, а не о техничкој функцији.

Како је SRP повезан са обрасцем Repository?

Repository — директни резултат примене SRP на слој података. Уместо развлачења логике приступа подацима по ViewModel или UseCase, Repository преузима јединствену одговорност: обезбеђивање података са апстракцијом извора. То је класична имплементација SRP у мобилној архитектури.

Може ли класа са SRP имати зависности од других класа?

Да, SRP не забрањује зависности. Класа са једном одговорношћу може делегирати део посла другим класама кроз композицију. Важно је да ти делегирани задаци буду део исте одговорности, а не самостални разлог за промену.

Како проверити да ли класа поштује SRP?

Поставите питање: „Који актори могу захтевати промену ове класе?“ Ако одговор садржи више од једног актора — SRP је прекршен. Додатно: покушајте да опишете намену класе једном реченицом без везника „и“. Ако не успевате — класа ради превише.

Завршни преглед

  • SRP (Single Responsibility Principle) — први принцип SOLID-а, захтева један разлог за промену класе
  • Разлог промене одређује актор — особа или систем који покреће захтев према модулу
  • Кршење SRP води ка God Class, ниској тестирабилности и високим трошковима измена
  • У мобилном развоју SRP раздваја UI логику, пословну логику и рад са подацима на засебне компоненте
  • Композиција помаже у поштовању SRP ефикасније од наслеђивања, захваљујући делегирању специјализованим објектима
  • Алати статичке анализе (Detekt, SwiftLint) аутоматски откривају потенцијална кршења SRP
  • Unit-тестирање класа са SRP захтева мање mock-објеката и показује већу покривеност кода

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође