Last updated
Last updated
Този принцип гласи, че един елемент трябва да има само една отговорност. Освен това тя следва да има само една причина да се промени, тази причина е промяна в изискването, какво се изисква от този елемент да изпълнява.
Този принцип помага да и се раздели по-добър софтуер, като ни позволява по лесно да:
Тестваме – Клас с една отговорност ще има много по-малко тестови случаи.
По-малко връзки – По-малко функционалност в един клас ще има по-малко зависимости.
Организация – По-малките, добре организирани класове са по-лесни за разбиране от монолитните.
Да започнем от следния пример, най-вероятно сте чували принципа: Една функция трябва да прави едно и само едно нещо. Ние използваме този принцип, когато рефакторираме (преработка на код, с цел да се подобри неговото качество, без да се промени крайния резултат) големи функции в по-малки функции; използва се на най-ниските нива.
Въпреки това, вярвам че се е случвало да пишете подобен код:
Така написана функцията, дали може да получава числа от, файл, база данни, фруга функция, сензоро?
Според вас тази функция изпълнява ли повече от едно нещо?
SOLID принципа за единна отговорност (SRP), много прилича на принципа по горе но е и различен. Докато принципа "Една функция, една отговорност" е приложим на ниско ниво, по колкото по нагоре се отива толкова по трудно става разпознаването на отговорностите.
Всеки клас може да съдържа повече от един метод или поле, в тази ситуация не може да се приложи директно подхода както при функциите, а трябва да се мисли за средата в която това обединение от методи и променливи ще намери приложение.
Може да се разбере този принцип, като се разгледат симптомите/начините по които се нарушава.
СИМПТОМ 1: СЛУЧАЙНО ДУБЛИРАНЕ
Като пример може да разгледаме приложение за заплати в което присъства клас Employee, тои има три метода: calculatePay(), reportHours() и save().
Метода calculatePay() изчислява заплатата необходима за счетоводния отдел
Метода reportHours() е специфичен и се отнася към отдела за човешки ресурси
Метода save() се отнася до администраторите на Базата даннищ
Да предположим, че функцията calculatePay() и reportHours() споделят общ алгоритъм за изчисляване на часове без извънреден труд.
Как бихте организирали когда си?
Логично е да поставим този алгоритъм във функция, предимството ще е че няма да се дублира код, с името regularHours()
Обединяването на тези 3 метода в един клас може да доведе до следното:
Свързване на счетоводния отдел, човешки ресурси, администраторите помежду им. Това обединение може да може накара действията на счетоводния отдел да повлияят на нещо, от който отдел човешки ресурси зависи.
Например, нека разгледаме един клас, за да представим една проста книга:
В този код съхраняваме името, автора и текста, свързани с екземпляр на Книга.
Нека сега добавим няколко метода за обработка на текста:
Сега нашият клас Book работи добре и можем да съхраняваме толкова книги, колкото ни харесва в нашето приложение.
Но каква полза е съхраняването на информацията, ако не можем да изведем текста в нашата конзола и да я прочетем?
Нека оставим предпазливоста на страна и да добавим метод за печат:
Този метод ще има достъп до системните ресурси за извеждане, което ще добави нова зависимост в него. Освен да съхранява информацията за книгата, класа знае и къде да я презентира.
Това какво виждате нарушава принципа на единната отговорност, който очертахме по-рано.
За да оправим бъркотията си, трябва да внедрим отделен клас, който се занимава само с отпечатване на нашите текстове:
Не само сме разработили клас, който обслужва Book на нейните задължения за печат, но и можем да използваме нашия клас BookPrinter, за да изпратим текста си на други медии.
Независимо дали става дума за имейл, сеч, или нещо друго, имаме отделен клас, посветен на тази грижа.
Трикът за внедряване на SRP в нашия софтуер е познаването на отговорността на всеки клас.
Следвайки принципа SRP, нашите класове ще се придържат към една функционалност. Техните методи и данни ще бъдат загрижени с една ясна цел. Това означава високо кохерентност, както и устойчивост на промени, които заедно намаляват грешките.
Въпреки че името на принципа е саморазяснително, можем да видим колко лесно е да се приложи неправилно. Уверете се, че ще разграничите отговорността на всеки клас при разработването на проект и обърнете допълнително внимание на кохерентността.