Вы неправильно реализуете шаблон стратегии. Пожалуйста, прочитайте еще раз о шаблонах стратегий и попытайтесь понять, как их использовать. Я постараюсь указать на проблемы здесь. Идея состоит в том, чтобы внедрить логи c в вашу кодовую базу на основе ввода или состояния, наиболее важной его части, типа ввода или вывода не меняется.
Задача 1 , контекст никогда не должен знать, что доступно несколько стратегий. Он знает только о том, что у него есть реализация стратегии, и ему нужно использовать стратегию для выполнения какого-либо действия и возврата результата.
Итак, класс контекста
public object TryParse(string filePath, TypeToParse typeToParse)
{
object parsedContent = new object();
try
{
switch (typeToParse)
{
case TypeToParse.A:
SetParsingStrategy(new ParseA());...
break;
case TypeToParse.B:
SetParsingStrategy(new ParseB());...
break;
}
}
....
}
является нарушением этого. У него есть распределительный шкаф, который знает о типах, что невозможно. Правильная реализация будет выглядеть примерно так:
public object TryParse(string filePath, TypeToParse typeToParse)
{
object parsedContent = _this._stategy.Parse(filePath); //it should never know which implementation is supplied, in other words wich strategy is applied. Only at runtime t will be decided.
}
Задача 2 . Реализация стратегии двух классов имеет следующие реализации:
class ParseA : IParseStrategy
{
public object Parse(string filePath) => new ConcurrentQueue<ParseAData>();
}
class ParseB : IParseStrategy
{
public object Parse(string filePath) => new Dictionary<string, ParseBData>();
}
Что также нарушение. Почему ты спрашиваешь? Потому что код, вызывающий отдельные классы, должен знать, что они возвращают. Шаблон стратегии является шаблоном, ему все равно, поддерживает ли c# его или нет. object
- это c# специфика c вкусностей, которые вы можете использовать для типизации любого объекта. Но это не значит, что использование объекта решает все. Даже если возвращаемые типы одинаковы (object
), базовые фактические объекты не являются и, следовательно, это не может быть реализацией шаблона стратегии. Стратегии внедряются динамически, и поэтому никто не должен иметь жестко закодированных зависимостей от них. Одна из возможных реализаций может быть -
interface IData
{
}
class ParseAData : IData
{
public int Id { get; set; }
public string Name { get; set; }
}
class ParseBData : IData
{
private byte[] data;
public byte[] GetData()
{
return data;
}
public void SetData(byte[] value)
{
data = value;
}
}
public interface IParsedObject
{
void process(<Some other dependencies>);
}
public class ConcurrentQueue<T> : IParsedObject where T: ParseAData
{
}
public class ParsedDictionary<T> : IParsedObject where T: ParseBData
{
}
public interface IParseStrategy
{
IParsedObject Parse(string filePath);
}
//the method will be somesiliar to this
public IParsedObject TryParse(string filePath, TypeToParse typeToParse)
{
IParsedObject parsedContent = _this._stategy.Parse(filePath); //it should never know which implementation is supplied, in other words wich strategy is applied. Only at runtime t will be decided.
}
class ParseA : IParseStrategy
{
public IParsedObject Parse(string filePath) => new ConcurrentQueue<ParseAData>();
}
class ParseB : IParseStrategy
{
public IParsedObject Parse(string filePath) => new Dictionary<string, ParseBData>();
}
с этими модификациями, которые вы теперь можете написать -
static void Main(string[] args)
{
var contextA = new Context();
contentA.SetParsingStrategy(new ParseA());
var contextB = new Context();
contextB.SetParsingStrategy(new ParseB());
var contentOfA = contextA.TryParse("file1.whatever", TypeToParse.A);
var contentOfB = contextB.TryParse("file2.whatever", TypeToParse.B);
}
или
static void Main(string[] args)
{
var context = new Context();
contentA.SetParsingStrategy(new ParseA());
var contentOfA = context.TryParse("file1.whatever", TypeToParse.A);
context.SetParsingStrategy(new ParseB());
var contentOfB = context.TryParse("file2.whatever", TypeToParse.B);
}
Info шаблон стратегии работает только в том случае, если ваши классы, использующие стратегию, не жестко кодируют зависимости, и в этом вся идея.
Ваш пример, вероятно, не подходит для паттерна стратегии. Я постарался исправить это как можно больше, чтобы вы лучше поняли, что не так в вашей реализации. Не все шаблоны поддерживают все сценарии ios. Вот пример реализации шаблона стратегии, который очень похож на ваш https://refactoring.guru/design-patterns/strategy/csharp/example.
Надеюсь, это поможет.
Примечание Код, который я предоставил, не работает. Они, вероятно, даже не скомпилируются, они просто существуют для 1057 * идеи, лежащей в основе стратегии. Правильная реализация будет иметь разные коды для каждого из классов ParseA
и ParseB
Подробнее Паттерны стратегии и Io C, (Inversion of Cntrol) идут рука об руку. Попробуйте выучить Io C, и вы поймете, что шаблон стратегии намного легче выучить. https://en.wikipedia.org/wiki/Inversion_of_control