2016-06-17 3 views
0

Это первая мысль, которую я получил во время чтения Interface Implementation (Interface Segregation Principle)Интерфейс реализация - Создание интерфейса для параметров

Мысль

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

interface IServiceProviderInput 
{ 
    string Username { get; } 
    string Password { get; } 
    string AgentId { get; } // XYZServiceProvider needs this. 
    // Similarly add props here to represent new parameters 
    // required by future service provider implementations. 
} 

interface IServiceProvider 
{ 
    bool Authenticate(IServiceProviderInput parameters); 
} 

class ABCServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

class EFGServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

class XYZServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

Вопрос

бы это имеет смысл или каковы недостатки в этом? Есть предположения?

Редактировать

Еще одна мысль, чтобы добавить более конкретный интерфейс для поставщика XYZ:

interface IServiceProviderInput 
{ 
    string Username { get; } 
    string Password { get; } 
} 

interface IXYZServiceProviderInput : IServiceProviderInput 
{ 
    string AgentId { get; } 
} 

class XYZServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IXYZServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

Вполне возможно, что и мысли неправильны или есть недостатки, я не уверен, поэтому вопрос ,

+0

Почему у входных свойств есть сеттеры? Это странно для меня. Ожидаете ли вы, что поставщик услуг сможет изменить значения свойств входа? – recursive

+0

@recursive Services не будут устанавливать их. Как бы код вызова устанавливал значения параметра в противном случае? – niksofteng

+1

Код вызова не требует доступа к ним исключительно через этот интерфейс. Целью интерфейса является группировка связанных операций с ответственностью. Если эта ответственность должна действовать как входной сигнал, то сеттер не нужен на интерфейсе. Но это не означает, что сеттер не может существовать в реализации или более производном интерфейсе. Чтобы использовать другой пример, вы не можете '.Add()' элемент в 'IEnumerable ', даже если вы можете на 'List '. – recursive

ответ

2

Вы, конечно, могли бы это сделать, но если ВСЕ методы не принимали и не нуждались во всех параметрах, определяемых интерфейсом, это была ужасная идея. Никогда не передавайте больше информации методу, тогда НУЖНО, иначе вы не поймете, что нужно для работы, а что нет - от интерфейса.

+0

Итак, чтобы указать только требуемые параметры, я упомянул мысль №2, где я создал «IXYZServiceProviderInput», но да, это будет еще хуже или непрактично сделать это для нескольких методов. Итак, мы заключаем, что это на самом деле плохая идея, и ее следует строго избегать? Или ждать больше мыслей от других? – niksofteng

+0

Скорее всего, в конечном итоге у вас будут интерфейсы для всех параметров методов. Я уверен, что кто-то будет спорить «Делает для большого модульного тестирования», но без особых причин делать это я бы не рекомендовал. Теперь, если мы действительно следуем ООП, где говорят, что все эти функции принимают IPerson и концептуально работают над данными IPerson, тогда это гораздо более приемлемо, но даже тогда вы хотите избежать создания пути для объекта Person в состоянии, когда методы могут неожиданно завершиться, пользователь забыл установить какое-то поле, чтобы не было очевидного способа узнать их. –

0

Мой единственный вопрос с вашей реализацией - почему вы используете тот же метод аутентификации с XYZServiceProvider, но не используете интерфейс IServiceProvider, который вы определили?

Проблема с этим, когда у вас есть клиенты, которые вызывают IServiceProvder для аутентификации, они не смогут использовать XYZServiceProvider, но смогут использовать только два других. Если они хотят использовать XYZServiceProvider, им нужно будет указать его по имени (тесно связанное).

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

Если бы у вас был альтернативный вид обслуживания для XYZServiceProvider, я бы рекомендовал создать другой интерфейс, такой как IServiceProvider, который используется для других служб.

+0

Ahh, Ты изменил его, прежде чем я отправил свой ответ. Это лучше – ghg565

+0

Я изменил его, разместив ответ, иначе я бы не понял, что я пропустил. Вы считали, что были действительны для предыдущей версии кода. Спасибо что подметил это. Что вы думаете об обновленном и окончательном коде? – niksofteng

+0

Я все еще думаю, что XYZServiceProvider должен реализовать интерфейс IServiceProvider. Параметр по-прежнему относится к типу IServiceParameterInput, поэтому это позволит вам пройти проверку подлинности на «IServiceProvider.Authenticate (параметры IServiceProviderInput)», а затем сохранить специфику внутри реализации. – ghg565

Смежные вопросы