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

Бессараб Дмитрий #31

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

Conversation

d2em0n
Copy link

@d2em0n d2em0n commented Dec 25, 2024

@glazz200


namespace TagsCloudContainer.TagGenerator
{
public interface ITagsGenerator

Choose a reason for hiding this comment

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

Не совсем понимаю, что будет делать этот элемент. Можешь рассказать подробнее?

Comment on lines 1 to 5
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

Choose a reason for hiding this comment

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

Видимо остались старые ненужные зависимости. Их лучше очищать, чтобы не засорять код

{
public interface ITextProcessor
{
public Dictionary<Word, int> Words(string path, ITextProvider provider, params IWordFilter[] filters);

Choose a reason for hiding this comment

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

Кажется фильтры - это всё-таки информация для конструктора, а не конкретного метода. Почему выбрал делать именно так?

Хотел предложить сделать обработку уже прочитанного текста, а не читать внутри этого же класса из файла. Получается очень жёсткая связь в поведении. У нас есть штука, которая умеет класса подготавливать слова, но получить их может только из файла

var words = new Dictionary<Word, int>();
foreach (var word in GetWordsFromString(provider.ReadFile(path)))
{
var flag = true;

Choose a reason for hiding this comment

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

Очень абстрактное название для переменной. Давай придадим смысла

Comment on lines 20 to 26
foreach (var filter in filters)
{
if (flag == false) break;
if (filter.Skips(word)) continue;
flag = false;
}
if (flag == false) continue;

Choose a reason for hiding this comment

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

Как сложно получилось 😨
Есть предложение реализовать здесь паттерн фильтра (немного отличается от привычного значения) и упростить этот код. А так же дать возможность легко расширять набор этих предусловий
Вот здесьможно почитать про паттерн фильтра. Нашёл хорошую статью только для Java, но она очень похожа на C#. Если будут вопросы, разберём


namespace TagsCloudContainer.WordFilters
{
public class SimpleFilter : IWordFilter

Choose a reason for hiding this comment

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

Может тогда BoringWordFilter?

{
public class SimpleFilter : IWordFilter
{
private readonly HashSet<string> _words =

Choose a reason for hiding this comment

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

Дадим более узкое название этому списку исключений? А то только по операциям над ним становится понятно, что это такое

Font = font;
Color = color;
var rect = g.MeasureString(Value, Font).ToSize();
Frame = new Size(rect.Width + 2, rect.Height + 2);

Choose a reason for hiding this comment

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

Подскажи, для чего нужно добавлять магическое число к размерам?

Choose a reason for hiding this comment

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

Кстати, размеры можно считать "снаружи" и передавать уже готовый size. Тогда это станет record

Comment on lines 10 to 12
var provider = new TxtTextProvider();
var filter = new SimpleFilter();
var processor = new TextProcessor.TextProcessor();

Choose a reason for hiding this comment

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

Комментарий на будущее. DI контейнер заменит это на красивый блок кода, где не нужно будет задумываться над тем, как кого создать

}

[Test]
public void ThrowException()

Choose a reason for hiding this comment

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

Не хватает в названии условия, при котором бросать исключение


public class Config
{
public Type PointGenerator { get; set; }

Choose a reason for hiding this comment

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

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

Comment on lines 15 to 16
public bool RandomColor;
public Color Color { get; set; }

Choose a reason for hiding this comment

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

Названия у этих свойств не очень отражают суть. Получится придать им смысла? И ещё не очень понятно, как быть в ситуации, когда RandomColor=true и цвет тоже указан. Можно посмотреть в сторону nullable типов

var container = new ContainerBuilder();

container.RegisterType(config.PointGenerator)
.AsImplementedInterfaces()

Choose a reason for hiding this comment

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

Писать один раз удобно, но в поддержке тяжело. Поиском не найти, где этот интерфейс применяется и с кем связан. А ещё возможны потенциальные конфликты, так как иногда один класс реализует несколько интерфейсов, и не ясно, к какому его использовать. А ещё вложенное наследование

.AsImplementedInterfaces()
.SingleInstance();
else
{

Choose a reason for hiding this comment

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

Фигурные скобки сильно путают. Если у if их нет, то скорее всего в else тоже они не нужны


namespace TagsCloudContainer.PointGenerators
{
[Label("Спираль")]

Choose a reason for hiding this comment

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

Это интересная техника, хорошо что прочитал. Но здесь на мой взгляд это перебор. Если что-то подобное делать, то нужно использовать локализации, а это уже совсем другая история. Предлагаю остановиться просто на названиях классов или даже цифрах при выборе. Это уже будет определяться реализацией клиента (ui или console)

{
internal class Program
{
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.

Если код ниже - эксперименты - хорошо. Но в итоговом решении его стоит вынести в отдельную реализацию клиента, и в Main вызывать уже его запуск


}

private static void ConfigureColor(Config config)

Choose a reason for hiding this comment

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

А вот вручную вызывать Assembly не нужно. Это ровно противоположное действие использованию DI контейнера. Задать возможные цвета через консоль поможет одна из библиотек парсинга аргументов. Например такой. Это заметно упростит обработку и поддержку кода. Чем более строгая типизация - тем лучше. Думаю, можно прямо на этапе разработки добавить нужные значения в аргументы. Они редко будут меняться. А что самое главное, при их изменении IDE подскажет, где есть использование, что позволит явно проконтролировать обратную совместимость (новая версия не ломает старое использование)

К тому же всё это теряет смысл в момент парсинга цвета, который производится вручную через switch

var pointGenerators = FindImplemetations<IPointGenerator>();
foreach (var point in pointGenerators)
Console.WriteLine(point.Key);
Console.WriteLine("Введите, соблюдая орфографию");
Copy link

@GlazProject GlazProject Jan 3, 2025

Choose a reason for hiding this comment

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

Аналогично предыдущему. Если хочется дать такую гибкую возможность конфигурирования, то можно воспользоваться функцией di возвращать набор зарегистрированных реализаций (container.Resolve<IEnumerable<IPointGenerator>>()). Тогда пользователь сможет выбрать только из того, что заведомо работает и поддерживается.

А ещё писать целиком - это опасное дело. Приятнее для человека указать одну цифру, чем вручную писать целом слово

Font = font;
Color = color;
var rect = g.MeasureString(Value, Font).ToSize();
Frame = new Size(rect.Width + 2, rect.Height + 2);

Choose a reason for hiding this comment

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

Кстати, размеры можно считать "снаружи" и передавать уже готовый size. Тогда это станет record


public Tag(Graphics g, Word word, Font font, Color color)
{
Value = word.Value;

Choose a reason for hiding this comment

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

Точно нужно доставать значение из Word? Можно его сохранить как самодостаточную единицу, вдруг что-то понадобится в него добавить

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