C # - Không có giết như quá mức cần thiết
Trước hết, GiMmEtHaCoDeZ thân mến, chúng ta hãy cố gắng phá vỡ nhiệm vụ của bạn:
- Đọc số
- Sắp xếp chúng
- Xuất các số được sắp xếp.
Vì "Phân chia và chinh phục" là chiến lược rất quan trọng khi làm việc với các vấn đề phần mềm, hãy giải quyết từng vấn đề một
1. Đọc
Một vấn đề quan trọng khác trong phần mềm là tính linh hoạt. Vì nó không được chỉ định cách người dùng sẽ nhập số, điều đó có thể xảy ra thông qua bảng điều khiển, qua tệp, qua dịch vụ web, v.v. Thậm chí có thể là một số phương pháp mà chúng ta không thể nghĩ ra vào lúc này. Vì vậy, điều quan trọng là giải pháp của chúng tôi sẽ có thể đáp ứng các loại đầu vào khác nhau. Cách dễ nhất để đạt được điều đó sẽ là trích xuất phần quan trọng vào giao diện, giả sử
public interface IDoubleArrayReader
{
IEnumerable<double> GetDoubles();
DoubleArrayReaderType Type {get;}
}
nơi DoubleArrayReaderType
được một điều tra đưa ra với
public enum DoubleArrayReaderType
{
Console,
File,
Database,
Internet,
Cloud,
MockService
}
Điều quan trọng nữa là làm cho phần mềm có thể kiểm tra được từ đầu, vì vậy việc triển khai giao diện sẽ là
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;
}
}
}
Tiếp theo, câu hỏi logic là làm thế nào chúng ta sẽ biết để tải phần thích hợp IDoubleArrayReader
vào mã. Điều đó thật dễ dàng miễn là chúng ta sử dụng một nhà máy đơn giản:
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];
}
}
Lưu ý rằng, chúng tôi sử dụng sự phản chiếu để tải tất cả các trình đọc đang hoạt động, do đó, mọi tiện ích mở rộng trong tương lai sẽ tự động có sẵn Bây giờ, trong phần chính của mã ngoài chúng tôi chỉ cần làm:
IDoubleArrayReader reader = DoubleArrayInputOutputFactory
.CreateDoubleArrayReader(DoubleArrayReaderType.MockService);
var doubles = reader.GetDoubles();
2. Xử lý (sắp xếp)
Bây giờ chúng ta cần xử lý, tức là sắp xếp các số chúng ta có được. Lưu ý rằng các bước hoàn toàn độc lập với nhau, do đó, đối với hệ thống con sắp xếp, việc nhập số như thế nào không quan trọng. Ngoài ra, hành vi sắp xếp cũng là một thứ có thể thay đổi, ví dụ chúng ta có thể cần phải nhập một thuật toán sắp xếp hiệu quả hơn. Vì vậy, một cách tự nhiên, chúng tôi sẽ trích xuất hành vi xử lý được yêu cầu trong một giao diện:
public interface IDoubleArrayProcessor
{
IEnumerable<double> ProcessDoubles(IEnumerable<double> input);
DoubleArrayProcessorType Type {get;}
}
public enum DoubleArrayProcessorType
{
Sorter,
Doubler,
Tripler,
Quadrupler,
Squarer
}
Và hành vi sắp xếp sẽ chỉ thực hiện giao diện:
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;
}
}
}
Tất nhiên, chúng ta sẽ cần một nhà máy để tải và quản lý các trường hợp xử lý.
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. Viết đầu ra
Không có gì nhiều để nói ở đây, vì đây là một quá trình phản ánh đầu vào. Trên thực tế, chúng ta có thể kết hợp các nhà máy đọc và viết thành một DoubleArrayInputOutputFactory
, như thế này:
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];
}
}
Để tất cả chúng cùng nhau
Cuối cùng, chương trình chính của chúng tôi sẽ sử dụng tất cả những điều tuyệt vời này mà chúng tôi đã xây dựng, vì vậy mã sẽ chỉ là:
var doubles = reader.GetDoubles();
doubles = processor.ProcessDoubles(doubles);
writer.WriteDoublesArray(doubles);
ở đâu, ví dụ như chúng ta có thể xác định reader
, writer
và processor
sử dụng
IDoubleArrayReader reader = DoubleArrayInputOutputFactory.CreateDoubleArrayReader(DoubleArrayReaderType.MockService);
IDoubleArrayProcessor processor = DoubleArrayProcessorFactory.CreateDoubleArrayProcessor(DoubleArrayProcessorType.Sorter);
IDoubleArrayWriter writer = DoubleArrayInputOutputFactory.CreateDoubleArrayWriter(DoubleArrayWriterType.Console);