У меня есть 4 класса, которые я должен изменять каждый раз, когда хочу позвонить в базу данных, и процесс становится смешным. Мне интересно, есть ли простой способ упростить процесс.
У меня есть вызывающий класс, который:
public ResponseObjectA getClients() {
RequestObjectA req = new RequestObjectA();
ResponseObjectA res = ProxyClass.GetClients(request);
}
public ResponseObjectB getVendors() {
RequestObjectB req = new RequestObjectB();
ResponseObjectB res = ProxyClass.GetVendors(request);
}
затем в моем ProxyClass:
public static ResponseObjectA getClients(RequestObjectA request) [
ResponseObjectA res = new ResponseObjectA();
res = ServiceClass.GetClients(request);
}
public static ResponseObjectB getVendors(RequestObjectB request) [
ResponseObjectB res = new ResponseObjectB();
res = ServiceClass.GetVendors(request);
}
затем в моем ServiceClass:
public ResponseObjectA getClients(RequestObjectA request) [
ResponseObjectA res = new ResponseObjectA();
DALClass.GetClients(request, res);
}
public ResponseObjectB getVendors(RequestObjectB request) [
ResponseObjectB res = new ResponseObjectB();
DALClass.GetVendors(request, res);
}
наконец, мой DALClass:
public void getClients(RequestObjectA request, ResponseObjectA response) [
..perform sql stuff..
}
public void getVendors(RequestObjectB request, ResponseObjectB response) [
..perform sql stuff
}
Вы видите проблему здесь, если я собираюсь добавить ResponseObjectC и RequestObjectC, если я собираюсь сделать вызов под названием GetSales? Это еще 5 обновлений.
Я упростил эти методы, чтобы проиллюстрировать эту точку, каждый метод делает что-то полезное. Проблема, которую я испытываю, - это повторяемость методов копирования и изменение одной части кода. Мне было интересно, есть ли способ сделать общий тип для ProxyClass и ServiceClass, поэтому мне не нужно их модифицировать. Просто вызывающий класс и DALClass.
Боковое примечание: ResponseObjectA и ResponseObjectB являются и дочерними классами BaseResponse.. Аналогично для RequestObjectA и RequestObjectB являются дочерними классами BaseRequest.
Одно решение: я думал о том, что все имена методов называются "Handle" и используют перегрузку метода.
Как и конечный результат DALClass, будут иметь следующие подписи:
public void Handler(RequestObjectA, ResponseObjectA) { }
public void Handler(RequestObjectB, ResponseObjectB) { }
но я не уверен, что классы Proxy и Service будут выглядеть так, чтобы убедиться, что вызывается правильный обработчик.
Похоже, вы могли бы консолидировать несколько пишущих общий метод или два:
public static TResponse get<TRequest, TResponse>(TRequest request, Func<TRequest, TResponse> getter)
where TRequest : BaseRequest
where TResponse : BaseResponse
{
TResponse res = getter(request);
}
Вам все равно придется выписывать каждый метод, но они были бы короче, поскольку вы могли бы абстрагировать общий материал:
public static ResponseObjectA getClients(RequestObjectA request) {
return get(request, ServiceClass.GetClients);
}
public static ResponseObjectB getVendors(RequestObjectB request) {
return get(request, ServiceClass.GetVendors);
}
Кроме того, если вы еще этого не сделали, я бы посмотрел, не будут ли удобны шаблоны T4 - похоже, они могут быть. Вместо robo-кодирования классов Proxy и Service вы можете сохранить что-то вроде списка кортежей (имя метода, тип запроса, тип ответа), а затем написать шаблон T4, который генерирует каждый из классов с различными методами для каждой записи в списке. (Вот как генерируется автоматически сгенерированный код, такой как прокси-сервер службы и классы сущностей базы данных в Visual Studio.)
Основная проблема, с которой вы столкнетесь, заключается в том, что веб-службы не поддерживают дженерики - для них требуются конкретные типы. Вместо того, чтобы пытаться сделать все уровни обобщенными, я бы вместо этого посмотрел, где вы используете код повторного использования, и попытайтесь реорганизовать это в общие классы (где вы, возможно, сможете использовать дженерики в дальнейшем).
Если вам не нравится копирование/вставка, вы можете посмотреть на создание шаблонов, которые будут генерировать большую часть общей структуры и кода для вас - вам просто нужно заполнить спецификацию для нового типа.
getClients()
, нет? Кроме того, почему прокси-код создает экземпляр объекта ответа только для его отбрасывания? Кроме того, почему не DAL создает объект ответа (в отличие от вашего класса обслуживания, создающего экземпляр, который нужно заполнить, как это кажется сейчас)?