C #-오버 킬과 같은 킬은 없습니다
우선, GiMmEtHaCoDeZ에게, 당신의 임무를 세분화 해 봅시다 :
- 숫자를 읽으십시오
- 그들을 정렬
- 정렬 된 숫자를 출력합니다.
소프트웨어 문제로 작업 할 때 "분할 및 정복"이 매우 중요한 전략이므로 한 번에 하나씩 해결
1. 독서
소프트웨어의 또 다른 중요한 문제는 다양성입니다. 사용자가 숫자를 입력하는 방법이 지정되어 있지 않기 때문에 콘솔, 파일, 웹 서비스 등을 통해 발생할 수 있습니다. 현재로서는 생각할 수없는 방법 일 수도 있습니다. 따라서 솔루션이 다양한 유형의 입력을 수용 할 수 있어야합니다. 이를 달성하는 가장 쉬운 방법은 중요한 부분을 인터페이스로 추출하는 것입니다.
public interface IDoubleArrayReader
{
IEnumerable<double> GetDoubles();
DoubleArrayReaderType Type {get;}
}
DoubleArrayReaderType
와 함께 열거가 어디에 있습니까?
public enum DoubleArrayReaderType
{
Console,
File,
Database,
Internet,
Cloud,
MockService
}
또한 소프트웨어를 처음부터 테스트 할 수 있도록하는 것이 중요하므로 인터페이스 구현은 다음과 같습니다.
public class MockServiceDoubleArrayReader : IDoubleArrayReader
{
IEnumerable<double> IDoubleArrayReader.GetDoubles()
{
Random r = new Random();
for(int i =0; i<=10; i++)
{
yield return r.NextDouble();
}
}
DoubleArrayReaderType IDoubleArrayReader.Type
{
get
{
return DoubleArrayReaderType.MockService;
}
}
}
다음으로 논리적 질문은 IDoubleArrayReader
코드에 적절한 것을로드하는 방법을 알 수 있습니다. 간단한 팩토리를 사용하는 한 쉽습니다.
public static class DoubleArrayInputOutputFactory
{
private static Dictionary<DoubleArrayReaderType, IDoubleArrayReader> readers;
static DoubleArrayInputOutputFactory()
{
readers = new Dictionary<DoubleArrayReaderType, IDoubleArrayReader>();
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
try
{
var instance = Activator.CreateInstance(type);
if (instance is IDoubleArrayReader)
{
readers.Add((instance as IDoubleArrayReader).Type,
(instance as IDoubleArrayReader));
}
}
catch
{
continue;
}
}
}
public static IDoubleArrayReader CreateDoubleArrayReader(DoubleArrayReaderType type)
{
return readers[type];
}
}
리플렉션을 사용하여 모든 활성 리더를로드하므로 향후 확장 기능을 자동으로 사용할 수 있습니다.
IDoubleArrayReader reader = DoubleArrayInputOutputFactory
.CreateDoubleArrayReader(DoubleArrayReaderType.MockService);
var doubles = reader.GetDoubles();
2. 가공 (분류)
이제 우리는 처리, 즉 우리가 얻은 숫자를 정렬해야합니다. 이 단계는 서로 완전히 독립적이므로 정렬 하위 시스템의 경우 숫자 입력 방법은 중요하지 않습니다. 또한 정렬 동작도 변경 될 수 있습니다. 예를 들어보다 효율적인 정렬 알고리즘을 입력해야 할 수도 있습니다. 당연히 인터페이스에서 요청 된 처리 동작을 추출합니다.
public interface IDoubleArrayProcessor
{
IEnumerable<double> ProcessDoubles(IEnumerable<double> input);
DoubleArrayProcessorType Type {get;}
}
public enum DoubleArrayProcessorType
{
Sorter,
Doubler,
Tripler,
Quadrupler,
Squarer
}
정렬 동작은 인터페이스를 구현합니다.
public class SorterDoubleArrayProcessor : IDoubleArrayProcessor
{
IEnumerable<double> IDoubleArrayProcessor.ProcessDoubles(IEnumerable<double> input)
{
var output = input.ToArray();
Array.Sort(output);
return output;
}
DoubleArrayProcessorType IDoubleArrayProcessor.Type
{
get
{
return DoubleArrayProcessorType.Sorter;
}
}
}
물론 처리 인스턴스를로드하고 관리하는 팩토리가 필요합니다.
public static class DoubleArrayProcessorFactory
{
private static Dictionary<DoubleArrayProcessorType, IDoubleArrayProcessor> processors;
static DoubleArrayProcessorFactory()
{
processors = new Dictionary<DoubleArrayProcessorType, IDoubleArrayProcessor>();
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
try
{
var instance = Activator.CreateInstance(type);
if (instance is IDoubleArrayProcessor)
{
processors.Add((instance as IDoubleArrayProcessor).Type, (instance as IDoubleArrayProcessor));
}
}
catch
{
continue;
}
}
}
public static IDoubleArrayProcessor CreateDoubleArrayProcessor(DoubleArrayProcessorType type)
{
return processors[type];
}
}
3. 출력물 쓰기
이것은 입력을 반영하는 프로세스이므로 여기서 할 말이 없습니다. 실제로, 우리는 다음과 같이 읽기 및 쓰기 팩토리를 단일로 결합 할 수 있습니다 DoubleArrayInputOutputFactory
.
public interface IDoubleArrayWriter
{
void WriteDoublesArray(IEnumerable<double> doubles);
DoubleArrayWriterType Type {get;}
}
public enum DoubleArrayWriterType
{
Console,
File,
Internet,
Cloud,
MockService,
Database
}
public class ConsoleDoubleArrayWriter : IDoubleArrayWriter
{
void IDoubleArrayWriter.WriteDoublesArray(IEnumerable<double> doubles)
{
foreach(double @double in doubles)
{
Console.WriteLine(@double);
}
}
DoubleArrayWriterType IDoubleArrayWriter.Type
{
get
{
return DoubleArrayWriterType.Console;
}
}
}
public static class DoubleArrayInputOutputFactory
{
private static Dictionary<DoubleArrayReaderType, IDoubleArrayReader> readers;
private static Dictionary<DoubleArrayWriterType, IDoubleArrayWriter> writers;
static DoubleArrayInputOutputFactory()
{
readers = new Dictionary<DoubleArrayReaderType, IDoubleArrayReader>();
writers = new Dictionary<DoubleArrayWriterType, IDoubleArrayWriter>();
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
try
{
var instance = Activator.CreateInstance(type);
if (instance is IDoubleArrayReader)
{
readers.Add((instance as IDoubleArrayReader).Type, (instance as IDoubleArrayReader));
}
}
catch
{
continue;
}
}
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
try
{
var instance = Activator.CreateInstance(type);
if (instance is IDoubleArrayWriter)
{
writers.Add((instance as IDoubleArrayWriter).Type, (instance as IDoubleArrayWriter));
}
}
catch
{
continue;
}
}
}
public static IDoubleArrayReader CreateDoubleArrayReader(DoubleArrayReaderType type)
{
return readers[type];
}
public static IDoubleArrayWriter CreateDoubleArrayWriter(DoubleArrayWriterType type)
{
return writers[type];
}
}
함께 모아서
마지막으로, 우리의 주요 프로그램은 우리가 이미 구축 한이 굉장함을 모두 사용하므로 코드는 다음과 같습니다.
var doubles = reader.GetDoubles();
doubles = processor.ProcessDoubles(doubles);
writer.WriteDoublesArray(doubles);
여기서, 예를 들어, 우리는 정의 할 수 있습니다 reader
, writer
및 processor
사용
IDoubleArrayReader reader = DoubleArrayInputOutputFactory.CreateDoubleArrayReader(DoubleArrayReaderType.MockService);
IDoubleArrayProcessor processor = DoubleArrayProcessorFactory.CreateDoubleArrayProcessor(DoubleArrayProcessorType.Sorter);
IDoubleArrayWriter writer = DoubleArrayInputOutputFactory.CreateDoubleArrayWriter(DoubleArrayWriterType.Console);