이것은 단일 책임 원칙을 위반 한 것입니까?
-
06-07-2019 - |
문제
다음 방법과 인터페이스가 있습니다.
public object ProcessRules(List<IRule> rules)
{
foreach(IRule rule in rules)
{
if(EvaluateExpression(rule.Exp) == true) return rule.Result;
}
//Some error handling here for not hitting any rules
}
public interface IRule
{
Expression Exp;
Object Result;
int Precedence;
}
규칙은 우선 순위가 있기 때문에 실제로 순서대로 처리되지 않아야합니다. 이것은 세 가지 솔루션으로 이끌어줍니다.
- 규칙을 평가자로 전달하기 전에 정렬하십시오.
- 매개 변수 유형을 정렬 순서를 시행하는 것으로 변경하십시오.
- 평가자 내에서 정렬하십시오.
옵션 3을 좋아하기 때문에 항상 분류되도록하고 옵션 1이 더 응집력이있는 것처럼 보이기 때문에 옵션 1을 좋아합니다. 옵션 2는 좋은 타협처럼 보입니다.
이 맥락과 같은 시나리오가 구체적/주관적입니까, 아니면 여기에 적용해야 할 모범 사례가 있습니까?
해결책
나는 그것이 Demeter와 캡슐화의 법률 위반과 같다고 생각합니다. 평가 발현은 규칙에 속하는 것처럼 보입니다. 이걸 고려하세요:
public object ProcessRules(List<IRule> rules) {
foreach(IRule rule in rules) {
return rule.EvaluateExpression();
}
}
public interface IRule {
object EvaluateExpression();
}
그렇게하면 EXP 또는 결과와 같은 규칙의 내부를 노출 할 필요가 없습니다.
그렇습니다. 원하는 동작이 선행 순서대로 규칙을 평가하는 경우 정렬 된 지 확인하십시오. 규칙의 책임은 스스로를 평가하는 것이며,이를 평가하기 위해 발신자의 결정입니다.
다른 팁
내 투표는 옵션 3에 적용됩니다. 커플 링을 최소화하기 위해 함수로 전송 된 데이터에 대해 너무 많은 가정을하지 않도록하려고합니다.
다른 클래스가 나중에 이것을 활용해야한다면, 당신은 그들이 우선 순위로 정렬 된 것을 전달한다고 생각하십니까?
이와 같은 시나리오에서는 다음과 같은 작업을 수행합니다.
public class RuleProcessor
{
public void SortRules(List<IRule> rules){}
//You could make this an abstract method
public object ProcessSortedRules(List<IRule> rules)
{
foreach(IRule rule in rules)
{
if(EvaluateExpression(rule.Exp) == true) return rule.Result;
}
//Some error handling here for not hitting any rules
}
public object ProcessRules(List<IRule> rules)
{
SortRules(rules);
ProcessSortedRules(rules);
}
}
당신은 추상 클래스 나 다른 종류의 다른 클래스를 집계 할 수 있습니다.
제휴하지 않습니다 StackOverflow