Overkill gibi öldürmek yok
Öncelikle, sevgili GiMmEtHaCoDeZ, görevinizi parçalamaya çalışalım:
- Numaraları oku
- Onları sırala
- Sıralanan sayıların çıktısını alın.
“Böl ve ele geçir” yazılım problemleriyle çalışırken çok önemli bir strateji olduğundan, her seferinde bunlarla başa çıkabilmenizi sağlar
1. Okuma
Yazılımdaki bir diğer önemli konu çok yönlülüktür. Kullanıcının, konsoldan, bir dosyadan, bir web servisinden, vb. Sayıları nasıl gireceği belirtilmediğinden, belki de şu anda düşünemediğimiz bir yöntem bile olabilir. Bu nedenle, çözümümüzün çeşitli girdi türlerini barındırabilmesi önemlidir. Bunu başarmanın en kolay yolu, önemli kısmı bir arayüze çıkarmak olacaktır.
public interface IDoubleArrayReader
{
IEnumerable<double> GetDoubles();
DoubleArrayReaderType Type {get;}
}
DoubleArrayReaderType
ile verilen bir numara nerede
public enum DoubleArrayReaderType
{
Console,
File,
Database,
Internet,
Cloud,
MockService
}
Yazılımın sıfırdan test edilebilir hale getirilmesi de önemlidir, bu nedenle arabirimin bir uygulaması olacaktır.
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;
}
}
}
Daha sonra, mantıksal soru, uygun IDoubleArrayReader
kodu koda yüklemeyi nasıl bileceğimizdir . Basit bir fabrika kullandığımız sürece kolay.
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];
}
}
Tüm aktif okuyucuları yüklemek için yansıma kullandığımızı unutmayın, bu nedenle gelecekteki uzantılar otomatik olarak kullanıma sunulacaktır.
IDoubleArrayReader reader = DoubleArrayInputOutputFactory
.CreateDoubleArrayReader(DoubleArrayReaderType.MockService);
var doubles = reader.GetDoubles();
2. İşleme (sıralama)
Şimdi işlem yapmamız gerekiyor, yani edindiğimiz sayıları sıralayın. Adımların birbirinden tamamen bağımsız olduğuna dikkat edin, bu nedenle sıralama alt sistemine, sayıların nasıl girildiği önemli değildir. Ek olarak, sıralama davranışı aynı zamanda değişime tabi olan bir şeydir, örneğin yerine daha verimli bir sıralama algoritması girmemiz gerekebilir. Doğal olarak, istenen işleme davranışını bir arayüzde çıkaracağız:
public interface IDoubleArrayProcessor
{
IEnumerable<double> ProcessDoubles(IEnumerable<double> input);
DoubleArrayProcessorType Type {get;}
}
public enum DoubleArrayProcessorType
{
Sorter,
Doubler,
Tripler,
Quadrupler,
Squarer
}
Ve sıralama davranışı sadece arayüzü uygulayacaktır:
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;
}
}
}
Tabii ki, işleme örneklerini yüklemek ve yönetmek için bir fabrikaya ihtiyacımız olacak.
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. Çıktıyı yazmak
Burada söylenecek fazla bir şey yok, çünkü bu girdiyi yansıtan bir süreç. Aslında, okuma ve yazma fabrikalarını tek bir üründe birleştirebilirdik, DoubleArrayInputOutputFactory
şöyle:
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];
}
}
Hepsini bir araya koy
Sonunda, ana programımız zaten kurduğumuz tüm bu uygunsuzlukları kullanacak, bu yüzden kod şu şekilde olacaktır:
var doubles = reader.GetDoubles();
doubles = processor.ProcessDoubles(doubles);
writer.WriteDoublesArray(doubles);
nerede, örneğin biz tanımlayabiliriz reader
, writer
ve processor
kullanma
IDoubleArrayReader reader = DoubleArrayInputOutputFactory.CreateDoubleArrayReader(DoubleArrayReaderType.MockService);
IDoubleArrayProcessor processor = DoubleArrayProcessorFactory.CreateDoubleArrayProcessor(DoubleArrayProcessorType.Sorter);
IDoubleArrayWriter writer = DoubleArrayInputOutputFactory.CreateDoubleArrayWriter(DoubleArrayWriterType.Console);