今日は「教えて!聞かないで!」について考えていました。このコードを試しています。
インターフェース:
interface IValidationContext
{
void AddMessage(string text);
bool IsValid { set; }
}
interface IValidation
{
void ValidateInput(Input input, IValidationContext context);
void ValidateOutput(Output output, IValidationContext context);
}
interface ICalculator
{
Output Calculate(Input input);
}
実装:
class CalculationService
{
private readonly ICalulator _calculator;
private readonly IValidation _validation;
public CalculationService(ICalculator calculator, IValidation validation)
{
_calculator = calculator;
_validation = validation;
}
public Output Calculate(Input input)
{
var context = new CalculationContext();
_validation.ValidateInput(input, context);
if (context.IsValid)
{
var output = _calculator.Calculate(input);
_validation.ValidateOutput(output, context);
return output
}
return null;
}
}
class CalculationContext : IValidationContext
{
public CalculationContext()
{
Messages = new List<string>();
}
public IList<string> Messages { get; private set; }
public void AddMessage(string text)
{
Messages.Add(text);
}
public bool IsValid { set; get; }
}
設計原則に準拠することが常に可能であるとは限らないことを私は知っています。しかし、最終的に私はオブジェクトを求めているこのコードに固執しました:
if (context.IsValid)
{
var output = _calculator.Calculate(input);
_validation.ValidateOutput(output, context);
}
実用的かどうかにかかわらず、それを解決することは可能ですか?
編集 1:
変更してIValidationContext
名前を変更した場合:
interface ICalculationContext
{
void AddMessage(string text);
Output Calculate(ICalculator calculator, Input input);
bool IsValid { set; }
}
コンテキストを尋ねる必要はありません:
public Output Calculate(Input input)
{
_validation.ValidateInput(input, context);
var output = context.Calculate(_calculator, input);
_validation.ValidateOutput(output, context);
return output;
}
現在、コンテキストは内部状態に基づいて計算を呼び出す責任があります。...気分が悪い...
編集2:
「教えて!聞かないで!」についての小さな記事を読みました。オブジェクトにその内部状態を尋ねてから、その状態に応じてオブジェクトに何かを伝えることは、「教えてください! 尋ねないでください!」に違反します。しかし、別のオブジェクトに何かを伝えることは問題ありません。これはここに当てはまりますか?
ところで。と の boolean-isvalid-result を導入しValidateInput
ますValidateOutput
。コードを次のように変更できます。
public Output Calculate(Input input)
{
var isValid = _validation.ValidateInput(input, context);
if (isValid)
{
var output = _calculator.Calculate(input);
_validation.ValidateOutput(output, context);
return output
}
return null;
}