@lexbt

Как организовать логику на основе типа сущности?

Добрый день. Прошу поделиться опытом, как правильно и логично реализовать следующее:
Имеем 4 класса Cat, Dog, Owl, Monkey
Каждый класс имеет как общие свойства, так и свои уникальные, которых нет в других классах. Есть апи ручка условно назовем ее SetAnimal. При вызове этой ручки передаётся тип животного и в контроллере идет проверка если тип такой то+ личные свойства животного подходят под проверку делаем такие то действия, для пример
если тип = cat то создаем класс new Cat(params)
или если тип monkey && weight > 20, new Monkey
...
При это в одной главной таблице создается запись что животное принято, animals -> id, date, type
и затем для каждого животного свой класс и запись в свою таблицу new Cat(requestParams), new Dog(requestParams), etc
1. Тип животного в базе не хранится, не вижу в этом смысла, насколько это корректно?
2. В каком виде корректно передавать типы животного? Видел реализацию где в качестве типа это какой то id, (т.е. Cat = 1, Dog = 2, и т.д.) и в базе так и хранят
Animals
id | date | typeId
1 |. ... | 1. - cat
2 | ..... | 2. - dog

При этом этот typeId не является внешним ключом к какой либо таблице.
Не лучше ли хранить в поле вместо цифр слово типа
id | date | type
1 |. ... | cat - cat
2 | ..... | dog - dog

Определение какой класс животного мы создаем в методе контроллера, хочется избежать if else if ...
Какой паттерн можно использовать, стратегия, фабричный метод?
Хочется чтобы в контроллере на входе получая тип, логика понимала что это класс такой то, создавала его и передавала параметры.
Что то вроде
cat => new Cat()
dog => new Dog()
...
При этом также хочется сделать валидацию на входные параметры для каждого из животного. У каких то параметров валидация одинаковая, у других своя уникальная, в том числе и поля.
Может быть имеет смысл разбить одну апи ручку на на несколько?
т.е. для каждого будет свои
POST /api/animals/cat {name: '..', anotherParam1}
POST /api/animals/dog {name: '..', anotherParam2}
POST /api/animals/owl {name: '..', anotherParam4: ''}
Для каждого создать свою request модель с валидацией, не придется в методе определять тип, сразу будет new Cat(params)...
  • Вопрос задан
  • 117 просмотров
Пригласить эксперта
Ответы на вопрос 1
@GineTik
Не могу сказать что мой ответ будет истинным, но может он чем-то поможет!

При вызове этой ручки передаётся тип животного и в контроллере идет проверка если тип такой то+ личные свойства животного подходят под проверку делаем такие то действия, для пример
если тип = cat то создаем класс new Cat(params)
или если тип monkey && weight > 20, new Monkey

Думаю, такой подход не очень хороший, так как при увеличении тех же животных придется городить больше ифов (свитчей и т.д.) в одном методе. В последствии будет большой и неудобный метод!

Как вы ответили в конце лучше будет сделать несколько конечных точек
POST /api/animals/cat {name: '..', anotherParam1}
POST /api/animals/dog {name: '..', anotherParam2}
POST /api/animals/owl {name: '..', anotherParam4: ''}
и в каждом уже прописать нужную логику. Будет лучше читаться и легче изменяться.

При этом также хочется сделать валидацию на входные параметры для каждого из животного. У каких то параметров валидация одинаковая, у других своя уникальная, в том числе и поля.

Для проверки полей или валидации рекомендую создать отдельные классы по типу CatValidator, MonkeyValidator которые будут наследоваться от, например, IValidator с методом Validate.

При это в одной главной таблице создается запись что животное принято, animals -> id, date, type
и затем для каждого животного свой класс и запись в свою таблицу new Cat(requestParams), new Dog(requestParams), etc
Не понятно зачем вам главная таблица Animals с перечнем всех животных, можете уточнить?

Для каждого создать свою request модель с валидацией, не придется в методе определять тип, сразу будет new Cat(params)...

Как мне кажется такой вариант будет неплохой. Также валидацию можно будет сделать c помощью атрибутов и встроенной в asp.net валидацией(ModelState.IsValid)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы