Используйте Получить по типу или Получить по идентификатору
У меня есть метод с именем GetObjectsRelatedToAType, например, GetCarsRelatedToDealership. Какой подход лучше с точки зрения веб-сервисов или сигнатур общего метода:
List<Cars> GetCarsRelatedToDealership( Dealership dealership );
или же
List<Cars> GetCarsRelatedToDealership( id dealership );
Мне нравится объектный подход, потому что он немного более силен, чтобы убедиться, что исходные данные метода верны. Мысли / советы?
6 ответов
Для веб-сервисов я стараюсь минимизировать объем передаваемых данных по проводам. Если вам также нужен метод, я бы, вероятно, сделал метод-член "GetRelatedCars" для класса / интерфейса "Дилерство". Когда приходит вызов веб-службы, вы можете проверить, что это реальное "Дилерство" (и вызывающий абонент имеет на него права), получив этот объект на основе идентификатора и для вызова метода "GetRelatedCars" для объекта.
Является ли идентификатор единственным элементом информации, который требуется для работы метода? Если так, я бы оставил это на этом.
У объектного подхода есть проблемы.
Dealership dealership;
GetCarsRelatedToDealership(dealership); // dealership is null
var dealership = new Dealership();
GetCarsRelatedToDealership(dealership); // dealership has no id
В этих случаях объект не дает вам никакого преимущества перед идентификатором. Идентификатор может быть неправильным, но вы можете проверить это. Объект делает вещи немного сложнее.
При работе со службами я бы создал пару классов запрос / ответ. Это позволяет вам гарантировать, что ваша подпись никогда не должна меняться. Ваши объекты Request или Response могут измениться, но сигнатура метода не изменится.
Теперь я могу передать идентификатор дилерского центра, а также того, кто запрашивает информацию, и убедиться, что запрашивающему пользователю разрешено видеть инвентарь этого дилерского центра. Что-то, просто проходящее через дилерский центр или удостоверение личности, не позволило бы.
public class CarsRequest
{
public int DealershipId { get; set; }
public int RequesterId { get; set; }
}
public class CarsResponse
{
public Car[] Cars { get; set; }
}
CarsResponse GetCarsRelatedToDealership(CarsRequest request);
Я бы пошел с подходом Id и подтвердил, что Id действителен. Вы могли бы потенциально получить недопустимый объект дилерства, в этом случае не было бы никакого преимущества при использовании Dealership
Можете ли вы иметь метод взять интерфейс? Это сделало бы его гораздо более гибким и, возможно, проще для тестирования.
List<Cars> GetCarsRelatedToDealership( IDealership dealership );
Использование только идентификатора обычно достаточно и намного проще, потому что вы можете просто передать идентификатор из одного места в другое. Это особенно важно для веб-сервисов, где вы хотите минимизировать объем передаваемых данных.
Однако, если у вас часто есть большие сигнатуры методов, когда входные данные не очень хорошо указаны именем метода:
List<Cars> GetCars(int makeId, int modelId, int year, int dealershipId);
... может быть очень легко передать неправильный идентификатор в неправильное место. С этого момента я бы начал пытаться найти другую стратегию. Строго вводить ваши входные данные как доменные объекты - это одно из решений, но, как правило, это доставит вам гораздо больше хлопот, чем просто использование специальных опций POCO:
public class GetCarsOptions
{
public int MakeId {get;set;}
public int ModelId {get;set;}
public int Year {get;set;}
public int DealershipId {get;set;}
}
List<Cars> GetCars(GetCarsOptions options)
{
ValidateOptions(options); // make sure the values all make sense.
}
Дело в том, что вы не сможете отловить каждую возможную ошибку во время выполнения, поэтому рекомендуется объединить автоматизированные тесты с методами "быстрого отказа", чтобы попытаться выявить как можно больше ошибок после компиляции и перед развертыванием.