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

Муканов Арман #203

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

Conversation

MNYOU
Copy link

@MNYOU MNYOU commented Jan 25, 2024

No description provided.

private const double FullCircle = Math.PI * 2;
private const int SpiralStepThreshold = 10;

public CircularCloudLayouter(ImageSettings imageSettings)

Choose a reason for hiding this comment

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

давай будем зависеть от абстракций а не от конкретики

spiralStep = 1;
}

public IReadOnlyList<Rectangle> AddedRectangles => rectangles;

Choose a reason for hiding this comment

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

лишнее

@@ -0,0 +1,8 @@
namespace TagsCloudContainer.Settings;

public class CloudData

Choose a reason for hiding this comment

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

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

.Select(inf => inf.Split('=').First().ToLower());
UpdateCloud(words);

return cloudData;

Choose a reason for hiding this comment

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

у тебя здесь очень грязный код
ты изменяешь состояние зависимости пришедшей извне, а возвращаемое значение метода вообще не используешь
сейчас из интерфейса вообще это не очевидно

private readonly MyStem myStem;
private readonly AnalyseSettings settings;

public TextPreprocessor(CloudData cloudData, MyStem myStem, AnalyseSettings settings)

Choose a reason for hiding this comment

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

используй абстракции


public interface ITagsCloudGenerator
{
public IEnumerable<Tag> Generate();

Choose a reason for hiding this comment

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

опять какой то магический интерфейс который делает всю работу внутри, от чего должен генерировать изображение такой интерфейс?

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

Choose a reason for hiding this comment

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

хорошо что выделил в отдельную сборку CUI

@@ -0,0 +1,15 @@
namespace TagsCloudContainer.Tests;

public class TagsCloudGeneratorTests

Choose a reason for hiding this comment

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

у тебя же должны были остаться тесты после предыдущего блока с генератором облака, почему хотя бы те тесты не перенес сюда?


internal class Program
{
public static void Main(string[] args)

Choose a reason for hiding this comment

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

если ты создаешь CUI то позаботься о том чтобы пользователь мог пользоваться твоей тулзой, если она запускается с какими то аргументами то должна быть осмысленная исчерпывающая подсказка по этим аргументам, если ты делаешь некое подобие shell то подсказка так же обязана быть, смотри туториалы по CommanLineParser, там все это доступно из коробки

сейчас без чтения кода вообще нет никакого понимания как пользоваться такой тулзой


public interface IOptionsHandler<in TOptions> : IOptionsHandler where TOptions : IOptions
{
public void Map(TOptions options);

Choose a reason for hiding this comment

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

так, давай рассказывай почему везде используешь грязные методы и все взаимодействие происходит через изменения состояния каких то других контрактов?
а так же давай подумаем почему это плохо, потому что это не первый раз встречается в твоем коде

чем это все отличается от вот такого интерфейса? (сейчас все интерфейсы у тебя по сути можно заменить на этот)

public inteface IDoEverything
{
    void Do();
}

public class TagsCloudGenerator: ITagsCloudGenerator
{
private readonly ITagTextMeasurer tagTextProvider;
private ICloudLayouterProvider cloudLayouterProvider;

Choose a reason for hiding this comment

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

readonly

@@ -0,0 +1,6 @@
namespace TagsCloudContainer;

public class AnalyzeData

Choose a reason for hiding this comment

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

  1. что инкапсулирует такой класс?
  2. Analyze - глагол, такое название подошло бы методу а не названию контракта

Frequency = frequency;
}

public static bool CanMap(string wordInfo)

Choose a reason for hiding this comment

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

почему ответственность за парсинг данных из утилиты mystem лежит здесь а не в препроцессоре?


namespace TagsCloudContainer.TextAnalysers;

public class TextPreprocessor: ITextPreprocessor

Choose a reason for hiding this comment

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

этот класс надо декомпозировать

  1. занимается фильтрацией частей речи из MyStem
  2. убирает скучные слова
  3. подсчитывает частоты

что если мы захотим добавить еще фильтрацию не по частям речи а еще, например, по количеству букв, по первым буквам слов? в этом случае придется изменять поведение этого класса

if (string.IsNullOrWhiteSpace(wordInfo))
return true;

var data = wordInfo.Split('=');

Choose a reason for hiding this comment

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

там split, здесь split. еще в worddata split причем тех же самых данных, нарушаешь DRY


public class AppSettings: IAppSettings
{
public string InputFile { get; set; } = @"C:\Users\mukan\Documents\Учёба\ShPORA\di\TagsCloudContainer\Data\Input.txt";

Choose a reason for hiding this comment

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

а на чужом компе будет работать?
и если оно все равно перезапишется то зачем тут эти значения


public class TagsCloudContainer: ITagsCloudContainer
{
private readonly FileReader fileReader;

Choose a reason for hiding this comment

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

юзай абстракции

commandLineReader.ParseFromConsole();
}

public static void ConfigureService(ContainerBuilder builder)

Choose a reason for hiding this comment

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

  1. обычно все таки регистрация зависиомстей происходит не ручками, представь что у тебя сотни классов, надо будет каждый зарегать и еще убедиться что никто не пропущен, для этого у autofac существует отдельный метод RegisterAllAssemblyTypes, но для этого надо еще правильно уметь правильно указывать сборки для регистрации, а вот там где нужно что то хитрое, какая то особая регистрация - вот в тех только местах и регистрировать явно
  2. чтобы не хранить в одной копилке все регистрации, в больших проектах это довольно тяжело поддерживать, у autofac есть очень хороший инструмент - модули, это позволит в CUI оставить только регистрацию связанную непосредственно с CUI или характенрную только для этой сборки, а в либу вынести то что связано только с ней

{
public string ReadFile(string filePath)
{
return File.ReadAllText(filePath);

Choose a reason for hiding this comment

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

что если файла не будет/доступа нет/несуществующий путь итд


public interface IOptionsHandler
{
public bool CanParse(object options);

Choose a reason for hiding this comment

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

почему тут object а не IOptions?

Choose a reason for hiding this comment

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

можно вынести тип обрабатываемой опции, по нему через словарь матчить необходимый хендлер раз вызов идет только здесь

но вообще канеш по хорошему сборка зависимостей должна быть в точке входа, а не просто на старте приложения, в твоем случае в момент когда управление переходит в либу из шелла по команде generate

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