Skip to content

Холстинин Егор#190

Open
Yrwlcm wants to merge 16 commits intokontur-courses:masterfrom
Yrwlcm:master
Open

Холстинин Егор#190
Yrwlcm wants to merge 16 commits intokontur-courses:masterfrom
Yrwlcm:master

Conversation

@Yrwlcm
Copy link

@Yrwlcm Yrwlcm commented Jan 23, 2024

Copy link

@MrTimeChip MrTimeChip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В целом, предпроверка на максимальный балл, но над многим стоит подумать и переделать)
Нравится, что код чистый, но вот архитектурные моменты стоит подправить, разграничить ответственность.

{
public IEnumerable<string> GetInterestingWords(string path, IDullWordChecker dullWordChecker)
{
var readText = File.ReadAllText(path);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сейчас тут просто вылетает эксепшен, что файл не найден, плюс нигде не написано, какой путь надо прописать до файла (абсолютный, относительный и т.д.)
Давай здесь выбрасывать другой эксепшен с комментарием и понятным разъяснением?

Comment on lines +12 to +14
[Argument(0)] [Required] public string InputFilePath { get; set; }

[Argument(1)] [Required] public string OutputFileName { get; set; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Когда вот этих обязательных аргументов нет, вылетает просто, что их нет, без пояснений, что, как, почему.
Плюс, непонятно, как мне узнать, какие аргументы вообще нужны, надо хотя бы инструкцию, чтобы не лазить в код ради этого)

[Option("-fs")] public int FontSize { get; set; } = 50;


private void OnExecute()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сейчас почти все сервисы добавлены синглтоном. Вопрос - почему?)
По умолчанию, нужно начинать с самого маленького скоупа, понимать, подходит ли он, если нет, подумать над большим скоупом, пока не станет ясно, какой подходит. А здесь ситуация обратная - решили сразу поставить максимальный скоуп, хотя каких-то предпосылок я здесь не вижу. Это как по умолчанию все переменные делать глобальными.

services.AddSingleton<IDullWordChecker, NoWordsDullChecker>();
services.AddSingleton<ICloudLayouter>(x =>
new CloudLayouter(x.GetRequiredService<IPointGenerator>(),
x.GetRequiredService<Font>(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь какой-то странное использование DI)
Суть DI в том, что он сам может резолвить зависимости, а ты сюда передаешь их напрямую. Зачем?)

Comment on lines +10 to +17
private class TestDullChecker : IDullWordChecker
{
public bool Check(string word)
{
var testDullWords = new HashSet<string>() { "this", "is" };
return testDullWords.Contains(word);
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему для теста отдельный класс создаем?)
Его же и тестируем по итогу.

public class CloudLayouter : ICloudLayouter
{
private readonly IPointGenerator pointGenerator;
private Dictionary<string, Font> wordsFonts = new();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кажется, что использование Font и других графических сущностей - вообще не обязанность Layouter'а.
Он, собственно, должен раскладывать прямоугольники, а не вот это вот всё.

Comment on lines +30 to +32
using var smallBitmap = new Bitmap(1, 1);
using var graphics = Graphics.FromImage(smallBitmap);
var rectangleSize = graphics.MeasureString(wordFont.Key, wordFont.Value);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь тот же момент. Не должно быть здесь работы с графикой. Графика должна рисовать готовую раскладку, а не делать такие странные махинации при раскладке.

Comment on lines +67 to +71
private class JsonWordAnalysis
{
public string Text { get; set; }
public List<Dictionary<string, string>> Analysis { get; set; }
}
Copy link
Author

@Yrwlcm Yrwlcm Jan 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот есть вопрос насколько вообще правильно создавать такие классы. Просто делать его общим тоже не хочется из-за того как изначальный json выглядит и парсится, а именно: полезная инфа в словаре, а словарь в листе. И каждый раз его доставать звучит ужасно. Поэтому я десериализую в этот приватный класс, а затем уже преобразую в публичный который нормально выглядит

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В целом, такое приемлемо, но, конечно, по возможности стоит избегать. Но в данном контексте - более чем нормально.

Comment on lines +65 to +68
if (SqareAlgorithm)
services.AddTransient<IPointGenerator, LissajousCurvePointGenerator>();
else
services.AddTransient<IPointGenerator, SpiralPointGenerator>();
Copy link
Author

@Yrwlcm Yrwlcm Jan 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот это тоже плохо выглядит, но не смог нагуглить как привязывать сервис в зависимости от условия в microsoft dependency injection

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В целом, нет такой вещи, как зарегистрировать или не зарегистрировать в зависимости от условия.
Тебе надо зарегистрировать PointGenerator'ы все разом, а потом в отдельном классе ты их принимаешь массивом и производишь выбор в зависимости от значения параметра.

{ "ADVPRO", "APRO", "INTJ", "CONJ", "PART", "PR", "SPRO" };

[Option("-square", Description = "Will use another algorithm to generate square tag cloud instead of circular.")]
private bool SquareAlgorithm { get; set; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как-то не очень это расширяемо, а если третий алгоритм добавить?

private void OnExecute()
{
var services = new ServiceCollection();
services.AddTransient<Font>(x => new Font(FontFamily, FontSize));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ладно, здесь немного со скоупом вышел перебор, пожалуй.
Вообще, по дефолту используют Scoped.

new MystemDullWordChecker(RemovedPartsOfSpeech, ExcludedWordsFile));
services.AddScoped<IInterestingWordsParser, MystemWordsParser>();
services.AddScoped<IRectangleLayouter>(
x => new RectangleLayouter(x.GetKeyedService<IPointGenerator>(PointGenerator)));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Интересная штука, KeyedService новая вещь. Но стоит посмотреть, как её правильно использовать.
https://weblogs.asp.net/ricardoperes/net-8-dependency-injection-changes-keyed-services

Comment on lines +77 to +81
{
layoutDrawer
.CreateLayoutImageFromFile(InputFilePath, new Size(ImageWidth, ImageHeight), MinimalFontSize)
.SaveImage(OutputFilePath, SaveImageFormat);
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не уверен насколько сейчас рационально выносить эти поля в TagLayoutSettings, так как сейчас мы не прячем ничего внутрь метода

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants