У чому різниця між принципом єдиної відповідальності та розділенням проблем


19

а) Яка різниця між SRP та SoC ? Можливо, що SRP застосовується на рівні класу, тоді як SoC може застосовуватися на рівні системи , підсистеми , модуля , класу або функції .

б) Якщо відповідь на " а" - так, то чи застосовується SoC на рівні класу синонім SRP ?

Дякую

Відповіді:


13

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

Розділення проблем стосується того, що ваш код не буде щільно пов'язаний з деякими іншими класами / системами. Використання інтерфейсів у вашому коді дуже допомагає, таким чином ви можете безперешкодно з'єднати класи / системи, які вам кодують. Плюсом цього є те, що простіше також перевірити свій код. Існує багато рамок (IoC), які можуть допомогти вам досягти цього, але ви можете, звичайно, також реалізувати таку річ.

Приклад чогось SoC, але не має SRP

public class Foo
{
    private readonly IValidator _validator;
    private readonly IDataRetriever _dataRetriever;

    public Foo(IValidator validator, IDataRetriever dataRetriever)
    {
        _validator = validator;
        _dataRetriever = dataRetriever;
    }

    public NavigationObject GetDataAndNavigateSomewhereIfValid()
    {
        var data = _dataRetriever.GetAllData();

        if(_validator.IsAllDataValid(data))
        {
            object b = null;
            foreach (var item in data.Items)
            {
                b = DoSomeFancyCalculations(item);
            }

            if(_validator.IsBusinessDataValid(b))
            {
                return ValidBusinessLogic();
            }
        }
        return InvalidItems();
    }

    private object DoSomeFancyCalculations(object item)
    {
        return new object();
    }
    private NavigationObject ValidBusinessLogic()
    {
        return new NavigationObject();
    }

    private NavigationObject InvalidItems()
    {
        return new NavigationObject();
    }
}

Як бачимо, цей код недостатньо поєднаний з класами або іншими системами, оскільки він використовує лише деякі інтерфейси, щоб робити речі. Це добре з точки зору SoC.

Як ви бачите, цей клас також містить 3 приватні методи, які роблять деякі химерні речі. З точки зору SRP, ці методи, ймовірно, повинні бути розміщені в деяких власних класах. 2 з них роблять щось із навігацією, що б відповідало якомусь класу INavigation. Інший робить деякі химерні розрахунки для елемента, це, ймовірно, може бути розміщено в класі IBusinessLogic.

Маючи щось подібне, у вас обох є SoC та SRP:

public class Foo
{
    private readonly IValidator _validator;
    private readonly IDataRetriever _dataRetriever;
    private readonly IBusinessLogic _businessLogic;
    private readonly INavigation _navigation;

    public Foo(IValidator validator, IDataRetriever dataRetriever, IBusinessLogic businessLogic, INavigation navigation)
    {
        _validator = validator;
        _dataRetriever = dataRetriever;
        _businessLogic = businessLogic;
        _navigation = navigation;
    }

    public NavigationObject GetDataAndNavigateSomewhereIfValid()
    {
        var data = _dataRetriever.GetAllData();

        if(_validator.IsAllDataValid(data))
        {
            object b = null;
            foreach (var item in data.Items)
            {
                b = _businessLogic.DoSomeFancyCalculations(item);
            }

            if(_validator.IsBusinessDataValid(b))
            {
                return _navigation.ValidBusinessLogic();
            }
        }
        return _navigation.InvalidItems();
    }
}

Звичайно, ви можете обговорити, чи варто всю цю логіку розмістити в GetDataAndNavigateSomewhereIfValidметоді. Це те, що ви повинні вирішити для себе. Мені здається, що цей метод робить занадто багато матеріалів.


"Прочитавши повний пост у відповіді Дж. Б. Кінга, я думаю, що це також хороший пост". Але відповідь Дж. Б. Кінга стверджує протилежну вашій відповіді, а саме - SoC також стосується єдиної відповідальності, лише за те, що вона може застосовуватися на більш високих рівнях, ніж SRP
користувач1483278

2

Що стосується застосування SRP лише на рівні класу, в його книгах Роберт К. Мартін (наскільки я знаю, він популяризував, якщо не придумав цю концепцію):

Чистий код, сторінка. 138 : "Принцип єдиної відповідальності (SRP) зазначає, що клас або модуль повинен мати одну, і лише одну, причину для зміни".

У "Agile Principles, Patterns and Practices" на C #, стор. 116 : "[...] і відносять згуртованість до сил, які викликають зміну модуля або класу."

Наголос мій.

У APPP він більш детально розмовляє про SRP і майже повністю зосередився на рівні класу. Хоча він, схоже, фокусується на рівні класу, я вважаю, що принцип також спрямований на модулі та інші конструкції вищого рівня.

З цієї причини я б не кваліфікував SRP як SoC на рівні класу, як ви пропонуєте у своєму запитанні.


Отже, якщо ми припускаємо, що SRP також можна застосовувати на більш високих рівнях, то різниця між SRP і SoC полягає в тому, що SRP несе єдину відповідальність, тоді як SoC може мати набір тісно пов’язаних між собою обов'язків?
користувач1483278

@ user1483278: Я дуже добре знайомий з SRP, але вперше почув про SoC, читаючи це питання, тому не можу відповісти на питання у вашому коментарі. З семантики здається, що SRP полягає в тому, щоб мати 1 відповідальність, а SoC відокремлює проблеми, я знаю, що це педантична відповідь, але в застосуванні занепокоєння принципів дають подібні результати.
Жиль

0

Тут ви можете знайти коротке відео, що чітко пояснює різницю між цими термінологіями. https://www.youtube.com/watch?v=C7hkrV1oaSY

Розділення проблем (SoC). Розділіть свою програму на різні функції з якомога меншим перекриттям функціоналу. (Microsoft).

"Concern" = "відмітна особливість" = "окремий розділ"

"Концерн" працює як на високому, так і на низькому рівнях

Принцип єдиної відповідальності зазначає, що кожен модуль або клас повинен нести відповідальність за окрему частину функціональних можливостей, що надаються програмним забезпеченням, і ця відповідальність повинна бути повністю капсульована класом. Усі його служби повинні бути узгоджені з цією відповідальністю. (Визначення Вікіпедії)

"Відповідальність" = "причина зміни"

змінити що? "Єдину частину функціоналу, що надається програмним забезпеченням" = Basic Unit

Висновок

Принцип єдиної відповідальності працює на основних одиницях -> працює на низькому рівні

Розділення концернів працює як на високому, так і на низькому рівнях

SRP та SoC працюють разом для роз'єднання проблем. Вони абсолютно однакові на низькому рівні


0

Ось моє розуміння цих принципів.

Розділення проблем (SoC) - це про поділ програмної системи на менші модулі, кожен з цих модулів відповідає за одну проблему. Викликає занепокоєння в цьому випадку особливість або випадок використання програмної системи. У результаті модуль має чітко визначений API (інтерфейс), завдяки чому ціла система є дуже згуртованою. Існує два основних типи: горизонтальний і вертикальний.

Принцип єдиної відповідальності (SRP) - це принцип проектування, який говорить про те, що кожен будівельний блок (це може бути клас, модуль, об'єкт або навіть функція) системи повинен мати лише одну відповідальність. Роберт К. Мартін. Мартін описує відповідальність як причину змін. Взагалі, набагато краще мати один клас / об'єкт, який несе відповідальність за одну частину функціоналу, а не зможе виконувати безліч, іноді навіть не пов'язаних між собою функцій, роблячи цей клас великим і щільно сполученим, т.з. називається "об'єктом Бога".

Також я описав ці принципи більш докладно у своїй публікації в блозі, будь ласка, подивіться.

https://crosp.net/blog/software-architecture/srp-soc-android-settings-example/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.