SRP: ano ito, prinsipyo ng iisang responsibilidad sa pag-develop

May-akda: IT Sectr Nai-publish: 2026-05-11 Oras ng pagbabasa: 9 min

SRP (Single Responsibility Principle) — ang unang prinsipyo ng SOLID na nagtatakda: bawat klase o modyul ay dapat may eksaktong isang dahilan upang magbago. Ang prinsipyong ito ay binumula ni Robert Martin sa aklat na Clean Architecture (2017) at naging pundasyon ng modular na pagdidisenyo. Ayon sa aklat na ito, ang paglalapat ng SRP ay direktang nagbabawas ng pagkakabit ng mga komponent at nag-aalis ng mga cascade na pagbabago kapag pinapahusay ang functionality.

Mga Pangunahing Punto

  • SRP — unang prinsipyo ng SOLID, nangangailangan ng iisang responsibilidad bawat klase
  • Dahilan ng pagbabago — ang tanging pamantayan para paghiwalayin ang responsibilidad sa isang modyul
  • Paglabag sa SRP ay humahantong sa magkadikit na code na mahirap i-test at palawakin
  • Paglalapat ng prinsipyo ay nagpapasimple ng refactoring at nagbabawas ng panganib ng regression errors
  • SRP sa mobile development ay tumutulong sa paghiwalay ng UI logic, mga panuntunan sa negosyo, at pagtatrabaho sa data

Ano ang SRP (Single Responsibility Principle)?

SRP (Single Responsibility Principle) — prinsipyo ng iisang responsibilidad na nagsasabi: bawat klase o modyul ay dapat may eksaktong isang dahilan upang magbago. Hindi ito nangangahulugan na ang isang klase ay dapat magsagawa ng eksaktong isang operasyon. Ito ay tungkol sa isang grupo ng magkakaugnay na aksyon na pinag-isa ng iisang responsibilidad sa harap ng isang aktor.

Binago ni Robert Martin ang pagkakabuo ng SRP sa mga termino ng aktor: ang isang klase ay dapat magbago lamang sa kahilingan ng isang interesadong tao o isang grupo ng mga tao. Kung dalawang magkaibang aktor ang humihiling ng pagbabago sa iisang klase — hindi wasto ang pagkakahati ng responsibilidad.

Halimbawa, ang klase na Employee, na sabay na nagkakalkula ng sahod (kahilingan ng accounting) at gumagawa ng ulat (kahilingan ng management) ay lumalabag sa SRP. Ang pagbabago ng mga panuntunan sa pagkalkula ay maaaring makaapekto sa paggawa ng ulat at vice versa.

Pormal na depinisyon ng SRP

Ang modyul ay dapat magkaroon ng isa at isa lamang dahilan upang magbago. Ang dahilan ng pagbabago ay tinutukoy ng aktor — ang tao o sistemang nagpapasimula ng kahilingan. Kung ang mga kahilingan mula sa iba't ibang aktor ay humahantong sa pagbabago ng iisang modyul — lumalabag ang modyul sa SRP.

Ang konsepto ng aktor ay ginagawang praktikal na kasangkapan ng pagsusuri ng arkitektura ang SRP, hindi isang abstract na rekomendasyon. Sa pagdidisenyo ng sistema, sapat na itanong: “Sino ang hihiling na baguhin ang code na ito?” — kung ang sagot ay may kasamang higit sa isang interesadong tao, ang responsibilidad ay dapat hatiin.

Paano gumagana ang prinsipyo ng iisang responsibilidad

Iisang responsibilidad ay naisasakatuparan sa pamamagitan ng pagpapangkat ng mga pamamaraan na nagbabago dahil sa iisang dahilan. Ang klase ay nagiging isang “punto ng pagtitipon” ng magkakaugnay na logic, hindi isang “Swiss na kutsilyo” para sa lahat ng okasyon. Pinapasimple nito ang pag-unawa sa code: nakikita ng developer ang klase at agad na nauunawaan ang layunin nito.

Ang mekanismo ng paggana ng SRP ay batay sa panuntunan ng iisang axis ng pagbabago. Kung ang functionality ay maaaring magbago dahil sa independiyenteng mga dahilan — dapat itong ilipat sa magkahiwalay na mga klase. Ang mga ugnayan sa pagitan ng mga klaseng ito ay binuo sa pamamagitan ng komposisyon o delegasyon.

Ang paglabag sa SRP ay nagpapakita sa “mga klase-diyos” (God Objects) na naglalaman ng dose-dosenang mga pamamaraan na gumagana sa iba't ibang data. Ang ganitong klase ay mahirap i-test — ang pag-test ng isang pamamaraan ay nangangailangan ng pag-set up ng kapaligiran para sa lahat ng iba pa. Ang pagbabago ng isang responsibilidad ay maaaring makasira ng isa pa, na ginagawang marupok ang code.

Sa praktika, tinutulungan ng SRP ang mga developer na sagutin ang tanong na “nasa'n ang code na ito?”. Kung ang bawat responsibilidad ay nakahiwalay sa sarili nitong klase, ang paghahanap ng kinakailangang file ay tumatagal ng ilang segundo. Sa isang proyektong Android na may arkitekturang MVVM, nangangahulugan ito na ang UserViewModel ay responsable lamang para sa estado ng screen ng user, at ang UserRepository ay para sa pagkuha ng data. Ang developer na naghahanap ng cache logic ay pumupunta sa UserCacheRepository, hindi sa ViewModel. Ang ganitong organisasyon ng code ay nagpapabilis sa onboarding ng mga bagong miyembro ng team at nagbabawas ng bilang ng mga error sa refactoring.

Bakit mahalaga ang SRP sa mobile development

Mobile development ay naglalagay ng mga espesyal na pangangailangan para sa modularidad ng code. Ang Android Fragment o iOS ViewController ay madalas na nagiging “mga punto ng atraksyon” ng logic: pagproseso ng pag-click, tawag sa API, pag-parse ng tugon, pag-update ng UI — lahat sa iisang klase. Hinihingi ng SRP ang paghihiwalay ng mga responsibilidad na ito.

Sa arkitekturang Android, ang SRP ay naka-embed sa mga rekomendasyon ng Google para sa Jetpack: ViewModel ay responsable para sa estado ng screen, Repository para sa data, UseCase para sa business logic. Ang bawat komponent ay may isang dahilan para magbago. Sa pag-develop ng iOS, ang pattern na MVVM at Coordinator ay sumusunod sa parehong logic.

Ang pagsunod sa SRP sa mga mobile na proyekto ay nagbibigay ng masusukat na mga benepisyo: pagbawas sa laki ng klase ng 40-60%, pagpapaikli ng oras ng code review, at pagbawas ng bilang ng regression bug kapag nagdadagdag ng bagong functionality. Ang mga isolated na modyul ay mas madaling takpan ng unit test at muling gamitin sa ibang mga screen.

Epekto ng SRP sa pag-test

Unit test ng mga klase na sumusunod sa SRP ay nangangailangan ng mas kaunting mock object at configuration. Kung ang isang klase ay may iisang responsibilidad, ang mga dependency nito ay limitado. Ang test ay sumusuri ng isang behavior, hindi kombinasyon ng maraming hindi magkakaugnay na scenario.

Ayon sa ulat ng Google Testing Blog (2023), ang mga klase na may iisang responsibilidad ay nagpapakita ng 35% mas mataas na test coverage kumpara sa mga aggregator na klase. Mas handang sumulat ng test ang mga developer para sa maliliit at naiintindihang modyul.

Mga halimbawa ng SRP sa Android at iOS

Tingnan ang isang tipikal na klase ng Android na lumalabag sa SRP — naglo-load ito ng data, nagpa-parse ng tugon, at nag-a-update ng UI. Pagkatapos ng refactoring, ang bawat responsibilidad ay nakahiwalay sa isang hiwalay na komponent.

kotlin
// Paglabag sa SRP: isang klase gumagawa ng lahat
class BadUserProfileActivity {
    fun loadUser(userId: Int) {
        // HTTP request
        // Pag-parse ng JSON
        // Pag-update ng UI
        // Pag-save sa database
    }
}

// Pagkatapos ng SRP application
class UserRepository {
    fun getUser(userId: Int): User
}

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

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

Ang katulad na halimbawa sa iOS Swift na may paghihiwalay ng network layer at presentation layer:

swift
// Paglabag sa SRP: ViewController namamahala ng data at UI
class BadProfileViewController: UIViewController {
    func viewDidLoad() {
        // URLSession request
        // Pag-decode ng JSON
        // Pag-update ng label
    }
}

// Pagkatapos ng SRP application
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) { }
}

Ang SRP refactoring ay hindi nagpapakumplikado ng arkitektura — muling ipinamahagi nito ang responsibilidad. Ang dami ng code ay maaaring bumaba pa sa pamamagitan ng pag-aalis ng duplikasyon. Ang bawat bagong klase ay may malinaw na layunin at maaaring paunlarin nang independiyente.

Komposisyon bilang alternatibo sa inheritance

Ang komposisyon ay tumutulong sa pagsunod sa SRP kung saan ang inheritance ay lumilikha ng hindi kinakailangang pagkakabit. Sa halip na isang superclass na may dose-dosenang mga pamamaraan, ang subclass ay tumatanggap ng isang set ng specialized na mga bagay sa pamamagitan ng constructor. Ang bawat bagay ay responsable para sa sarili nitong functionality.

Sa pag-develop ng Android, ang Decorator pattern ay nagbibigay-daan sa pagdaragdag ng mga responsibilidad nang hindi binabago ang orihinal na klase. Sa iOS, ang Middleware chain sa network layer ay naghihiwalay ng logging, caching, at authentication sa magkakahiwalay na modyul.

Mga karaniwang paglabag sa SRP at ang mga epekto nito

Ang pinakakaraniwang paglabag — “God Class”: isang klase na namamahala ng database, nagpapadala ng mga notification, gumagawa ng mga ulat, at nagpoproseso ng input ng user. Ang ganitong klase ay nagiging bottleneck ng proyekto: bawat pagbabago ay nangangailangan ng kumpletong regression testing.

Sa mobile development, ang paglabag sa SRP ay dulot ng paghahalo ng business logic at UI logic sa Activity, Fragment, o ViewController. Kapag ang onClickListener method ay sabay na nagva-validate ng data, tumatawag ng API, at nag-a-update ng visibility ng mga button — ito ay direktang paglabag sa prinsipyo ng iisang responsibilidad.

Ang mga epekto ng paglabag sa SRP ay kinabibilangan ng: kahirapan sa parallel development (mga conflict sa iisang file), nahihirapang unit testing, mataas na gastos ng mga pagbabago, at pagbaba ng readability ng code. Ang mga proyektong may sistematikong paglabag sa SRP ay nangangailangan ng 2-3 beses na mas maraming oras para magdagdag ng bagong functionality.

Mga indikator ng paglabag sa SRP sa code

Ang paglabag sa SRP ay maaaring matukoy sa pamamagitan ng hindi direktang mga palatandaan: ang klase ay naglalaman ng higit sa 200 linya, nag-i-import ng mga modyul mula sa iba't ibang layer ng aplikasyon (UI + network + database), may higit sa 5 pampublikong pamamaraan na may iba't ibang paksa. Metric ng cohesion — isang statistical indicator: ang mababang cohesion ng mga pamamaraan sa loob ng klase ay nagpapahiwatig ng paglabag sa SRP.

Para sa pagtuklas ng mga paglabag sa SRP, kapaki-pakinabang na gumamit ng mga kasangkapan ng static analysis: para sa Android — Detekt na may panuntunang TooManyFunctions, para sa iOS — SwiftLint na may panuntunang file_length. Ang mga utility na ito ay nagha-highlight ng mga klase na lumalampas sa threshold ng laki at complexity.

Ang refactoring ng mga klase na lumalabag sa SRP ay isinasagawa sa pamamagitan ng Extract Class o Extract Delegate: ang isang grupo ng magkakaugnay na pamamaraan ay inililipat sa isang hiwalay na klase, at ang orihinal na klase ay nagde-delegate ng mga tawag sa kanila. Ang unti-unting paglalapat ng mga refactoring na ito ay nagpapabago sa “God Class” sa isang set ng maluwag na magkakaugnay na modyul, bawat isa ay may iisang responsibilidad. Ang ganitong paraan ay nagbibigay-daan sa pagpapabuti ng arkitektura nang hindi humihinto sa pag-develop — ang refactoring ay ginagawa nang iterative, isang modyul sa bawat pagkakataon.

Mga Madalas Itanong

Ang SRP ba ay nangangahulugan na ang klase ay dapat maglaman ng isang pamamaraan?

Hindi. SRP ay hindi tungkol sa bilang ng mga pamamaraan, kundi tungkol sa bilang ng mga dahilan para magbago. Ang isang klase ay maaaring magkaroon ng sampung pamamaraan kung lahat ng ito ay naglilingkod sa iisang responsibilidad sa harap ng iisang aktor. Ang isang pamamaraan — ay ang kabilang sukdulan na humahantong sa labis na pagkakapira-piraso ng code.

Paano naiiba ang SRP sa prinsipyo ng iisang obligasyon?

Ito ay iisang prinsipyo. Single Responsibility Principle ay isinasalin kapwa bilang “iisang responsibilidad” at “iisang obligasyon”. Ang terminong “responsibilidad” ay mas tumpak na sumasalamin sa esensya: ito ay tungkol sa responsibilidad sa harap ng aktor, hindi tungkol sa teknikal na function.

Paano nauugnay ang SRP sa pattern ng Repository?

Repository — direktang resulta ng paglalapat ng SRP sa layer ng data. Sa halip na ikalat ang logic ng pag-access sa data sa ViewModel o UseCase, ang Repository ay kumukuha ng iisang responsibilidad: pagbibigay ng data na may abstraction ng pinagmulan. Ito ay isang klasikong implementasyon ng SRP sa mobile na arkitektura.

Maaari bang magkaroon ng mga dependency sa ibang mga klase ang isang klase na may SRP?

Oo, SRP ay hindi nagbabawal ng mga dependency. Ang isang klase na may iisang responsibilidad ay maaaring magdelegate ng bahagi ng trabaho sa ibang mga klase sa pamamagitan ng komposisyon. Mahalaga na ang mga delegadong gawaing ito ay bahagi ng iisang responsibilidad, hindi isang independiyenteng dahilan para magbago.

Paano suriin kung ang isang klase ay sumusunod sa SRP?

Magtanong: “Anong mga aktor ang maaaring humiling ng pagbabago sa klaseng ito?” Kung ang sagot ay may kasamang higit sa isang aktor — nilabag ang SRP. Dagdag pa: subukang ilarawan ang layunin ng klase sa isang pangungusap nang walang pangatnig na “at”. Kung hindi magawa — masyadong marami ang ginagawa ng klase.

Buod

  • SRP (Single Responsibility Principle) — unang prinsipyo ng SOLID, nangangailangan ng isang dahilan para sa pagbabago ng klase
  • Dahilan ng pagbabago ay tinutukoy ng aktor — tao o sistemang nagpapasimula ng kahilingan sa modyul
  • Paglabag sa SRP ay humahantong sa God Class, mababang testability, at mataas na gastos ng pagbabago
  • Sa mobile development ang SRP ay naghihiwalay ng UI logic, business logic, at pagtatrabaho sa data sa magkakahiwalay na komponent
  • Komposisyon ay tumutulong sa pagsunod sa SRP nang mas epektibo kaysa inheritance, sa pamamagitan ng delegasyon sa specialized na mga bagay
  • Mga kasangkapan ng static analysis (Detekt, SwiftLint) ay awtomatikong nakakatuklas ng potensyal na paglabag sa SRP
  • Unit test ng mga klase na may SRP ay nangangailangan ng mas kaunting mock object at nagpapakita ng mas mataas na code coverage

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din