Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open

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