Modello di strategia
Il modello di strategia definisce una famiglia di algoritmi, incapsula ciascuno e li rende intercambiabili. La strategia consente all'algoritmo di variare in modo indipendente dai client che lo utilizzano.
Ecco alcuni esempi eccellenti del modello di strategia
Come puoi vedere dal primo link qui sopra, puoi individuare il tipo di file nell'intestazione nel tuo metodo principale, quindi inserire la versione corretta della strategia nel contesto e quindi chiamare il contesto.
Se vuoi davvero, puoi scrivere un metodo di fabbrica per creare automaticamente il tuo contesto.
Quindi potresti chiamare qualcosa come la seguente
var context = FileFactory.CreateContext(myFile);
context.Parse();
Un metodo factory potrebbe essere un po 'eccessivo per questo, tuttavia, questo sarebbe un giudizio da parte tua. Tuttavia, l'utilizzo del modello di strategia come sopra offre la flessibilità di aggiungere qualsiasi numero di nuovi tipi di file da analizzare. Inoltre, la fabbrica ti darà la possibilità di astrarre tutto il polimorfismo dal tuo codice logico.
Modifica
Ecco cosa si otterrebbe utilizzando un modello di strategia combinato con un metodo di fabbrica.
public interface IFileParserStrategy
{
IList<Person> Parse(String path);
}
public class FileFormatNo1 : IFileParserStrategy
{
private string _path;
public FileFormatNo1(String path){
_path = path;
}
public IList<Person> Parse()
{
// Actual Logic for handling File Format #1
// and returning a IList<Person>
}
}
public class FileFormatNo2 : IFileParserStrategy
{
private string _path;
public FileFormatNo1(String path){
_path = path;
}
public IList<Person> Parse(String path)
{
// Actual Logic for handling File Format 2
// and returning a IList<Person>
}
}
public interface IFileParserContext
{
public IList<Person> Parse();
}
public class FileParserContext : IFileParserContext
{
private IFileParserStrategy _strategy;
public FileParserContext(IFileParserStrategy fileParserStrategy)
{
_strategy = fileParserStrategy;
}
public IList<Person> Parse()
{
return _strategy.Parse();
}
}
public static class FileParserFactory
{
public static IFileParserContext CreateContext(String path)
{
FileParserContext context = null;
var checkFileFormat = File.ReadAllLines();
if(checkFileFormat.Contains("FileFormatNo1"))
context = new FileParserContext(new FileFormatNo1(path));
if(checkFileFormat.Contains("FileFormatNo2"))
context = new FileParserContext(new FileFormatNo2(path));
if(context == null)
throw new FileFormatException("File is not in a readable state");
return context;
}
}
public static void Main()
{
var filePath = "someFile.txt";
var context = FileParserFactory.CreateContext(filePath);
var personList = context.Parse();
}
Aggiorna
È possibile modificare la strategia precedente per passare un FileStream se si desidera aprire il file solo una volta. È possibile modificare FileParserFactory.CreateContext per accettare un FileStream come parametro e rifattorizzare le strategie per accettare FileStream anziché filePath.
public static void Main()
{
var filePath = "someFile.txt";
List<Person> personList;
using(var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var context = FileParserFactory.CreateContext(fileStream);
personList = context.Parse();
}
}