Это хорошо, потому что вы можете убить двух зайцев одним выстрелом: уменьшить или исключить наследование и использовать инъекцию зависимостей.
Вместо создания метода protected
представьте себе, что метод делает какабстракция, от которой зависит ваш класс.
Вместо
protected bool AnotherMethodOfA()
Представьте себе
public interface IThingThatDoesSomethingAndReturnsABoolean
{
bool MethodThatReturnsBool();
}
или
public delegate bool FunctionThatReturnsBool();
Затем перепишите класс A
следующим образом:
public class A
{
private readonly IThingThatDoesSomethingAndReturnsABoolean _thing;
public A(IThingThatDoesSomethingAndReturnsABoolean thing)
{
_thing = thing;
}
protected bool AnotherMethodOfA()
{
bool anotherReturnValue = false;
bool operationCheck = _thing.MethodThatReturnsBool();
if (operationCheck)
{
//do something to set the value of anotherReturnValue
}
return anotherReturnValue;
}
}
Если вам нужно изменить реализацию того, что возвращает значение bool
, вам не нужно делать это путем наследования от A
.Это обычная модель, но она имеет тенденцию запутываться и создавать проблемы, в том числе ту, о которой вы спрашиваете.
Вместо этого все, что вам нужно сделать, - это предоставить другую реализацию IThingThatDoesSomethingAndReturnsABoolean
.
Теперь все проверяемо.Вы можете проверить A
, предоставив макет интерфейса.Вы хотели, чтобы метод, который возвращает bool
, был тестируемым, и теперь это потому, что он больше не является protected
методом какого-либо другого класса.
Это называется предпочтением композиции над наследованием.Вместо того, чтобы классы работали вместе, наследуя друг от друга, вы пишете отдельные классы, которые делают разные вещи и объединяют их для совместной работы.
Если вашему классу зависимостей нужны значения, «принадлежащие» A
, к которым он ранее обращалсяв качестве свойств или полей вы можете сделать их аргументами метода.Это позволяет легко увидеть, сколько именно информации требуется методу из A
.
. Существуют случаи, когда наследование имеет смысл, но рекомендуется разделять функциональные возможности на зависимости, а не встраивать их в иерархию наследования.сделает ваш код тестируемым и предотвратит другие головные боли, которые могут возникнуть позже.