티스토리 뷰
코드가 입력에 따라 다르게 실행되지만 질문에있는 것과 같은 일반적인 출력을 생성하는 if / switch 문이있을 때마다 일반적으로 리팩토링을 수행해야한다는 신호입니다.
이 경우 가장 좋은 옵션은 인터페이스 기반 디자인을 사용하고 다양한 보고서를 실행하기위한 논리를 고유 한 유형으로 이동하는 것입니다. 이렇게하면 기존 코드를 건드리지 않고도 필요에 따라 추가 보고서를 더 잘 관리 할 수 있습니다.
public interface IReporter {
void GenerateReport();
}
public class ReporterA : IReporter {
public void GenerateReport() { /* execute report */}
}
public class ReporterB : IReporter {
public void GenerateReport() { /* execute report */}
}
public class ReporterC : IReporter {
public void GenerateReport() { /* execute report */}
}
// The responsibilty of the factory is only to create the correct reporter based on the request
public class ReporterFactory{
public IReporter CreateReporter(string input){
/* the logic here can vary, you can get creative with Attributes
and name each report type and use reflection to create the
correct report type. You can also use an Enum and use that as an attribute value over
each Reporter type. There are many ways to handle it.
*/
}
}
/* your refactored method */
public static void GenerateReport(string report)
{
/* again, creation pattern could be based on something other than a string. It depends on how you want to differentiate your reporters*/
var reporter = new ReporterFactory().CreateReporter(report);
reporter.GenerateReport();
}
-------------------이를 위해 제네릭이나 유형 감지 기능이있는 switch 문이 필요하지 않습니다 ... 대신 각 유형에 대해 메서드 오버로딩을 사용하고 작업 부분을 자체 메서드에 유지합니다 .
public static void GenerateReport(ReportA a) { /*do stuff*/ }
public static void GenerateReport(ReportB b) { /*do stuff*/ }
public static void GenerateReport(ReportC c) { /*do stuff*/ }
-------------------제네릭 에 대한 요점은 당신이하고있는 일이 각 final에 대해 대략 동일T
하지 않다면 실제로 제네릭 이 아니며 그렇게해서는 안된다는 것입니다.
여기에 좋은 후보는 다음과 같습니다.
- 열거 형
- 다형성 (a
virtual
/abstract
방법) Type
인스턴스 전달
하지만 ... 제네릭은 아닙니다. 언어가 당신을 돕지 않는 이유는 이것이 잘 맞지 않기 때문입니다. 즉, 다음과 같이 할 수 있습니다.
if(typeof(T) == typeof(Foo)) {
// foo
} else if (typeof(T) == typeof(Bar)) {
// bar
} ...
그러나; 제네릭의 요점이 다소 누락되었습니다.
-------------------다음과 같이 할 수 있습니다.
public static void RunIfEqual<TLeft, TRight>(Action action)
{
if (typeof(TLeft) == typeof(TRight))
{
action();
}
}
...
RunIfEqual<T, ReportA>(()=> ...);
RunIfEqual<T, ReportB>(()=> ...);
RunIfEqual<T, ReportC>(()=> ...);
또는 더 나은 방법 은이 유형에 사용할 생성기를 선택하고 반환하는 ReportGeneratorFactory를 정의 할 수 있습니다. 그런 다음 GenerateReport 를 호출 하면됩니다.
출처
https://stackoverflow.com/questions/39920009
댓글