Недавно я обнаружил, читая некоторые темы блогов в Интернете, что 90% строк кода, которые я создал за свою карьеру, были процедурными, а не ориентированными на ООП (большой удар по голове). Итак, теперь я пытаюсь лоботомировать свой мозг, чтобы производить только коды ООП. Проблема в том, что у меня много вопросов о практике ООП.
Вот один из них:
У меня есть фабрика, RawLineCollectionFactoryкоторая берет строковые строки и создает из них объект домена с именем RawLineCollection. Мой вопрос касается передачи типа аргумента Createметоду.
Должен ли я передать ему объект ( IDataSource), который позволяет мне получать такие строковые строки:
public class RawLineCollectionFactory : IRawLineCollectionFactory
{
public IRawLineCollection Create(IDataSource dataSource)
{
ICollection<RawLine> lineGroup = new List<RawLine>();
if (dataSource.GetLines() != null)
{
foreach (string line in dataSource.GetLines())
{
lineGroup.Add(new RawLine(line));
}
}
return new RawLineCollection(lineGroup);
}
}
Или позвонить getLines()из dataSourceобъекта на более высоком уровне абстракции , и передать результат в качестве аргумента Createметода?
public class RawLineCollectionFactory : IRawLineCollectionFactory
{
public IRawLineCollection Create(IEnumerable<string> lines)
{
ICollection<RawLine> lineGroup = new List<RawLine>();
if (lines != null)
{
foreach (string line in lines)
{
lineGroup.Add(new RawLine(line));
}
}
return new RawLineCollection(lineGroup);
}
}
Редактировать :
Контекст очень близок к точке входа в приложение. RawLine - это объектное представление строки в файле, который содержит настройки данных для создания игры.
public class RawLine
{
private string value;
public RawLine(string value)
{
this.value = value;
}
public IEnumerable<string> Split(string separator)
{
if (string.IsNullOrEmpty(separator))
{
throw new ArgumentException("The separator is required");
}
if (!string.IsNullOrEmpty(value))
{
return value
.Replace(" ", "", StringComparison.CurrentCulture)
.Split(separator)
.Where(item => !string.IsNullOrEmpty(item));
}
return Array.Empty<string>();
}
}
Поведение этого класса состоит в том, чтобы разделить фактическое представление своего состояния для целей правил конкретного приложения, в то время как RawLineCollection является коллекцией этого типа сущности.
public class RawLineCollection : IRawLineCollection
{
private readonly IEnumerable<RawLine> lines;
private readonly string separator = "-";
public RawLineCollection(IEnumerable<RawLine> lines)
{
this.lines = lines;
}
public SplittedLineCollection Split()
{
ICollection<IEnumerable<string>> result = new List<IEnumerable<string>>();
if (IsValidStringGroup(lines))
{
foreach (RawLine line in lines)
{
if (line.Split(separator).Any())
{
result.Add(line.Split(separator));
}
}
}
return new SplittedLineCollection(result);
}
private bool IsValidStringGroup(IEnumerable<RawLine> settingsToSplit)
{
return settingsToSplit != null && settingsToSplit.Any();
}
}
RawLineCollectionFactory используется только один раз, как метод DataSource.GetLines ().
Спасибо за вопрос. IMHO, преобразование процедурного кода в объектно-ориентированный код - отличная практика. Поздравляю с прозрением!
В общем, проблема сохранения данных вашей игры - это проблема сериализации. Я предлагаю вам изучить, могут ли встроенные в .NET функции "настройки" удовлетворить ваши потребности. Кроме того, стоит обратить внимание на стандартную сериализацию в JSON или XML.
Если вы настаиваете на «собственной» сериализации, вы, безусловно, можете сделать это объектно-ориентированным способом. Мой взгляд на начало работы ниже.
Если у вас есть сложные данные, такие как определения уровней игры, вы можете сериализовать довольно много данных, что было бы еще большей причиной для использования стандартного формата, такого как JSON или XML.
Для сериализации и десериализации относительно простого файла конфигурации вы, вероятно, можете пропустить фабричный шаблон. Но если конфигурация охватывает несколько файлов, включая большие двоичные изображения и т. Д., То стоит подумать о «Фабрике конфигурации».
Я бы рекомендовал создать один (или несколько) классов для правильного моделирования фактических свойств конфигурации и сериализовать / десериализовать их вместо обработки всего в виде строк.
Например:
public class Config
{
public string PlayerName {get; set;}
public DateTime LastPlayed {get; set;}
public int HighScore {get; set;}
}
В приведенном ниже примере используется «гибридный» подход. Он идет дальше, чем обработка необработанных строк с помощью using KeyValuePair, но не достигает полностью типизированного Configкласса (как показано выше).
Еще один быстрый совет: Вместо того RawLineCollection, я бы назвал его RawLines, или даже лучше, Lines.
Добро пожаловать в мир ООП. В некоторых других моих ответах на обзор кода я более подробно изучаю принципы, которыми я руководствуюсь в своей практике ООП.
Вот пример (этот код компилируется, но я его не тестировал):
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class App_ConfigFile
{
/* Config file example
player1Name:Jane
player2Name:Joe
difficulty:medium
lastPlayed:04/20/2020
lastLevel:5
highScore:31000
*/
public void Run()
{
var file = new ConfigFile(@"c:\myGame\config.txt");
var config = file.ToConfigData();
var player1name = config.GetByName("player1Name");
var lastPlayed = DateTime.Parse(config.GetByName("lastPlayed"));
var highScore = int.Parse(config.GetByName("highScore"));
}
}
public class ConfigFile
{
private string path;
private List<Line> lines;
public List<Line> Lines => lines ?? (lines = getLines());
public bool HasContent => Lines.Count > 0;
public ConfigFile(string path) => this.path = path;
public ConfigData ToConfigData(char separator = ':') => new ConfigData(Lines.Select(l => l.ToKvp(separator)).ToList());
private List<Line> getLines() => File.ReadAllLines(path).Select(l => new Line(l)).ToList();
}
public class Line
{
public string Raw { get; private set; }
public Line(string line) => Raw = line;
public KeyValuePair<string, string> ToKvp(char separator)
{
var tokens = Raw.Split(separator);
return new KeyValuePair<string, string>(tokens.First(), tokens.Last());
}
}
public class ConfigData
{
private List<KeyValuePair<string, string>> data;
private Dictionary<string, string> _dictionary;
private Dictionary<string, string> dictionary => _dictionary ?? (_dictionary = data.ToDictionary(d => d.Key, d => d.Value, StringComparer.OrdinalIgnoreCase));
public ConfigData(List<KeyValuePair<string, string>> data) => this.data = data;
public string GetByName(string key) => dictionary[key];
public bool TryGetByName(string key, out string value) => dictionary.TryGetValue(key, out value);
}
}
Яна Дуггар открыто говорила о своих поисках любви. Вот все, что она сказала на эту тему и о своем пятилетнем окне для замужества.
Звезда «Чужестранки» Сэм Хьюэн недавно рассказал, что он возьмет со съемочной площадки, чтобы вспомнить Джейми Фрейзера, роль, которая сделала его звездой.
«She Loves You» была написана за час, записана за день и стала песней The Beatles с одним из лучших исполнений в их карьере.
У Долли Партон и ее бабушки Бесси были особые отношения. Бабушка Партон была очень больна, но это не мешало Долли разыгрывать ее.
Вы можете подумать, что дуб или гикори — прочные породы дерева, но когда речь идет о самой твердой древесине в мире, они даже близко не стоят.
Океан полон красоты, но он также скрывает одних из самых страшных морских существ на планете. Многие из этих животных скрываются глубоко под поверхностью океана, в тёмном, полном давления мире морских глубин.
Если вы сражаетесь с враждебными мобами или готовитесь к PvP-боям, знание лучших чар для мечей в Minecraft может дать вам серьёзное преимущество. Зачарование мечей позволяет наносить больше урона, увеличивать количество выпадающих мобов и продлевать срок службы меча.
Когда говорят о социалистических странах, часто представляют себе полный государственный контроль и отсутствие частной собственности. Но на практике социалистические экономики сильно различаются.
В «Детях» появится громкая камео и несколько разрушительных новостей
Утверждается, что этот RAV4 находится в отличном состоянии и готов к игре в музыкальные стулья.
На кадрах, снятых с дрона, видно, как пожарные изо всех сил пытаются потушить пламя.
«Глаза Ваканды» напрямую связаны с MCU, а также обновления о «Людях Икс '97», «Что, если...», «Сорвиголова» и многом другом.
Ава Гарднер была замужем за Микки Руни и Фрэнком Синтрой, и встречалась с несколькими другими голливудскими звездами. Вот взгляд назад на историю знакомств Авы Гарднер.
Джон Клиз женился на Дженнифер Уэйд в 2012 году. Вот все, что нужно знать о жене Джона Клиза, Дженнифер Уэйд.
Олимпийская чемпионка Эллисон Феликс вышла замуж за своего мужа Кеннета Фергюсона в 2018 году. Вот все, что нужно знать о муже Эллисон Феликс, Кеннете Фергюсоне.
Мена Сувари замужем за своим мужем Майклом Хоупом с 2018 года. Вот все, что нужно знать о муже Мены Сувари.
Это поражает меня Внезапно, как это часто бывает, Это снова и снова на полпути <Нет, не то, что в Тихом океане, ты темно-бордовый, то, что на карнавале> Каждый громкий заголовок…..
В 2022 году, с выпуском GPT-3, навыки письма, кажется, стали менее важными. С помощью ИИ люди с плохим письмом также могут генерировать качественный персонал.
В современном быстро меняющемся и конкурентном мире карьера играет важную роль в личностном росте, финансовой стабильности и общей удовлетворенности жизнью. Однако многие люди оказываются в безжалостном цикле застоя и неудовлетворенности, постепенно угасая в своей профессиональной жизни.
На прошлой неделе я заметил пресс-релиз, разосланный через PressGazette (новостной веб-сайт британских СМИ). В статье сообщалось, что Acast, скандинавская компания по размещению и рекламе подкастов, возглавит консорциум «вероятно, самых влиятельных» издателей подкастинга.