Чистая архитектура UseCases vs Controller с функциями - PullRequest
3 голосов
/ 18 июня 2019

Я только начал читать о чистой архитектуре, и я запутался в определениях реализаций вариантов использования.

Рассмотрим класс контроллера, имеющий набор функций, который принимает T и возвращает R после выполнения некоторой логики

interface IController {
   fun usecase1(param:T) : R 
   fun usecase2(param:T) : R
}

Теперь я могу выполнить сценарии использования с экземпляром IController.

Другой способ - определить каждый сценарий использования как класс и внедрить его в другие объекты, что требует функциональности.

class UseCase1 {
    fun execute(param:T):R {}
}

class UseCase2 {
    fun execute(param:T):R {}
}

Каковы преимущества / недостатки между наличием сценариев использования в качестве отдельных единиц по сравнению с наличием его в качестве функций некоторого класса?

IMO, отдельные единицы добавляют издержки на сжатие и внедрение, тогда как другой подход страдает 'проблемы наследования над композицией ».Какой правильный путь?

Ответы [ 3 ]

2 голосов
/ 19 июня 2019

Каковы преимущества / недостатки между наличием вариантов использования в качестве отдельных единиц по сравнению с наличием его в качестве функций некоторого класса?

Если вы поместите все в контроллер, вы нарушите принцип единственной ответственности. Код контроллера изменится по причинам, отличным от кода варианта использования.

например. Контроллер принимает ввод от пользователя и создает вывод для пользователя, часто с помощью докладчика. Это означает, что он читает входные данные из моделей представлений и обновляет модели представлений. Модели представлений принадлежат пользовательскому интерфейсу и будут меняться по причинам пользовательского интерфейса.

Варианты использования не должны зависеть от пользовательского интерфейса, если вы реализуете чистую архитектуру, и они изменятся по другим причинам, чем пользовательский интерфейс. Варианты использования не зависят от пользовательского интерфейса. Это также облегчит их тестирование, и их будет проще использовать повторно с другими пользовательскими интерфейсами.

Рассмотрим класс контроллера, имеющий набор функций, который принимает T и возвращает R после выполнения некоторой логики

Имейте в виду, что параметры и возвращаемые типы контроллеров не совпадают с типами вариантов использования.

Ваш контроллер может использовать типы, предназначенные для сериализации и десериализации json. Это проблема транспорта. Варианты использования не заботятся о транспорте. Способ передачи данных - это деталь. Интернет это деталь. Если вы используете одни и те же типы для контроллеров и вариантов использования, вы создадите зависимость между ними.

1 голос
/ 22 июня 2019

Чистая архитектура - это та, которая имеет меньшую связь между слоями. Теперь, когда мы пытаемся применить чистую архитектуру к веб-приложению, такому как Google Photos, оно может иметь несколько слоев, например,

  1. слой пользовательского интерфейса (тот, который воспринимается пользователем)
  2. Уровень маршрутизации, который может направлять URL-адрес к нужному файлу класса
  3. В зависимости от вариантов использования может быть несколько слоев адаптера
  4. Постоянный слой, который снова можно подразделить на,

    4,1. Постоянство метаданных (например, Postgress, MySQL)

    4,2. Постоянство содержимого (напр., Hadoop)

Как здесь используются примеры использования?

Вариант использования - это случай, описывающий взаимодействие пользователя с системой. Это может быть так же просто, как проверка по неправильному паролю во время аутентификации (или) с возможностью применить фильтр к изображению. Реализация варианта использования может закончиться методом или может возникнуть между несколькими классами и файлами.

Чистая архитектура - это своего рода руководство, которое настаивает на том, чтобы у нас была слабая связь между слоями, чтобы замена одного слоя на другой была легкой с минимальными изменениями.

1 голос
/ 19 июня 2019

В соответствии с принципом разделения интерфейсов, лучше иметь отдельные интерфейсы вариантов использования для каждого случая. Это позволяет вам каким-то образом абстрагировать реализацию варианта использования. И вы можете разделить или разделить реализацию варианта использования независимо от уровня контроллера.

Я бы порекомендовал разделить каждый вариант использования на отдельный класс. Потому что, когда вы модифицируете один из них, вы будете на 100% уверены, что не тормозите другой. Но если у вас есть много вариантов использования, и они маленькие, в этом случае имеет смысл сгруппировать его в файлы. Но я думаю, функции высокого порядка подходят лучше, чем набор функций в классе.

Имеет смысл создать класс, когда он имеет состояние и поведение, но если вы создадите класс для сценариев использования, он не будет иметь состояния и методы вряд ли будут тесно связаны.

Но что действительно важно, согласно чистой архитектуре, так это разделение слоев. Не важно, как организовать хранение вариантов использования, но очень важно иметь возможность изменить решение позже независимо от других уровней.

...