Deutsch

C# - pattern matching - many discards

9414  1 2 3 4 5 6 7 8 9 10 все
alex445 коренной житель20.02.24 16:20
20.02.24 16:20 
Последний раз изменено 20.02.24 16:36 (alex445)

Вопрос про оформление и красивости. И можно ли вообще так написать.


Вобщем, понадобилось проверить объект на кучку разномастных условий. Например, на налл весь объект, на значение одно из свойств, если объект не налл, и вернуть что-то другое, если какие-то ещё условия. И хочу спросить, как удобнее сделать, чтобы не писать простыную из вложенных ифов. Пусть мы получили где-то объект row кастомного типа и хотим сделать подобные проверки. Как вы находите такую запись - удобной, читаемой, или лучше пачку вложенных ифов?


var result = row switch
{
    null => MyEnum.NotAllowed,
    _ when row.Age > 100 => MyEnum.Died,
    _ => MyEnum.StillAlive,
};


Тут результат быдет перечислением MyEnum.

Насколько я знаю, все выражения в выражении свича проверяются по порядку написания до первого соответствия, так что первая проверка на налл всего объекта - нормально. Меня смутило только возможность сделать несколько дискардов, т.к. полный объект мне не нужен. Ну или может можно как-то без дискардов обойтись.


Я могу так переписать, но мне что-то первый вариант больше нравится - можно добавить проверок других свойств row, и тогда логично, что входной параметр свича это весь объект. Но в любом случае есть пачка дискардов - не смущает ли она?


var result = row.Age switch
{
    _ when row == null => MyEnum.NotAllowed,
    > 100 => MyEnum.Died,
    _ => MyEnum.StillAlive,
};


Альтернатива в ифах


MyEnum result;
if (row != null)
{
    if (row.Age > 100)
    {
        result = MyEnum.Died;
    }
    else
    {
        result = MyEnum.StillAlive;
    }
}
else
{
    result = MyEnum.NotAllowed;
}


Ситуация с ифами ухудшается, если количество проверок увеличивается. А в сопоставлениях с образцом - просто добавляется одна строчка на проверку.

#1 
alex445 коренной житель20.02.24 16:40
NEW 20.02.24 16:40 
в ответ alex445 20.02.24 16:20, Последний раз изменено 20.02.24 16:42 (alex445)

Древовидная структура ифов легко трансформируется в линейную структуру сопоставлений, просто порядок соблюдать надо - сначала одну ветку ифов последовательно в сопоставлениях пишем, потом другую. Разве что если условий становится больше десятка, как и вложенностей - по 3-4 и больше. Но и тогда на мой взгляд сопоставления лучше - они хотя бы на экран влезут, а дерево ифов явно расползётся куда дальше. Ну и всегда можно отделить группы кейсов в сопоставлениях форматированием - добавить между ними пустую строчку, например. А в ифах уже и так места нет, так ещё их удлинять.

#2 
alex445 коренной житель20.02.24 16:44
NEW 20.02.24 16:44 
в ответ alex445 20.02.24 16:20
var result = row.Age switch
{
    _ when row == null => MyEnum.NotAllowed,
    > 100 => MyEnum.Died,
    _ => MyEnum.StillAlive,
};

Не уверен, но тут, по-моему, может NullReferenceException вылететь уже на row.Age, если row налл. Ну можно тогда так написать row?.Age.

#3 
7495 старожил20.02.24 17:35
7495
NEW 20.02.24 17:35 
в ответ alex445 20.02.24 16:20
var result


Вот 3 варианта получить "result" на чистом сишарповском языке. Результат везде одинаков.

Вопросы и Ответы - Программируем калькулятор пособий для беженцев вместе.
#4 
AlexNek патриот20.02.24 19:51
AlexNek
NEW 20.02.24 19:51 
в ответ alex445 20.02.24 16:40

Похоже мы опять изобретаем очередной велосипед.

Этих реализаций дофига, например

https://docs.fluentvalidation.net/en/latest/start.html

https://github.com/Blazored/FluentValidation

https://code-maze.com/complex-model-validation-in-blazor/


и свитч и ифы не подходят, если уж свое сильно хочется.

#5 
AlexNek патриот20.02.24 19:56
AlexNek
alex445 коренной житель21.02.24 00:00
NEW 21.02.24 00:00 
в ответ AlexNek 20.02.24 19:51

Валидаторы тут не причём. Я спросил, как насчёт такой конструкции с образцами, где несколько дискардов идут - нормально выглядит, или вы знаете способ лучше? Объект с его полями тут лишь для примера, и валидация ему не нужна.

#7 
AlexNek патриот21.02.24 18:04
AlexNek
NEW 21.02.24 18:04 
в ответ alex445 21.02.24 00:00
Я спросил, как насчёт такой конструкции с образцами, где несколько дискардов идут - нормально выглядит

Просто ужасно, даже и без дискардов


Вариант fluent validation намного лучше

#8 
Отпускник завсегдатай21.02.24 18:57
NEW 21.02.24 18:57 
в ответ AlexNek 21.02.24 18:04

приведи свой вариант решения.

#9 
AlexNek патриот21.02.24 19:29
AlexNek
NEW 21.02.24 19:29 
в ответ Отпускник 21.02.24 18:57, Последний раз изменено 21.02.24 19:45 (AlexNek)

ну так написал же... Пишешь просто набор правил

    RuleFor(x => x.Surname).NotEmpty();
    RuleFor(x => x.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(x => x.Discount).NotEqual(0).When(x => x.HasDiscount);
    RuleFor(x => x.Address).Length(20, 250);
    RuleFor(x => x.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");


RuleFor(x => x.Name).NotEmpty().WithMessage("name cannot be null");

RuleFor(x => x.Phone).NotEmpty();

RuleFor(x => x.Other).GreaterThan(0).WithMessage("other must be great than 0");;

#10 
alex445 коренной житель21.02.24 19:41
NEW 21.02.24 19:41 
в ответ AlexNek 21.02.24 19:29, Последний раз изменено 21.02.24 19:44 (alex445)
ну так написал же... Пишешь просто набор правил

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


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

Можно бы было произвольные условия проверки писать - обошёлся бы без этого костыля. Но произвольно в паттерн матчинг пока не завезли.

#11 
AlexNek патриот21.02.24 19:46
AlexNek
NEW 21.02.24 19:46 
в ответ alex445 21.02.24 19:41

Во первых, всё уже написано,

во вторых, был вопрос как нравится

#12 
Отпускник завсегдатай21.02.24 19:55
NEW 21.02.24 19:55 
в ответ AlexNek 21.02.24 19:29

причем тут твои правила? Напиши эквивалент вот этому коду:

var result = row.Age switch
{
    _ when row == null => MyEnum.NotAllowed,
    > 100 => MyEnum.Died,
    _ => MyEnum.StillAlive,
};
#13 
alex445 коренной житель21.02.24 20:30
NEW 21.02.24 20:30 
в ответ AlexNek 21.02.24 19:46

Во первых, всё уже написано,

во вторых, был вопрос как нравится

Вы не поняли - проверки могут быть где угодно, а не лишь внутри ваших безнес-правил. И там не обязательно объект с полями, а может быть просто скажем строка. Проверяем её на налл, длину, наличие такого или иного символа или их сочетания... Ну понятно, вы и тут правила свои напишете - в виде расширения класса строк. Любой лапшекод, лишь бы паттерн матчинг не использовать )))

#14 
NightWatch коренной житель21.02.24 22:59
NightWatch
NEW 21.02.24 22:59 
в ответ alex445 20.02.24 16:20
Ситуация с ифами ухудшается, если количество проверок увеличивается. А в сопоставлениях с образцом - просто добавляется одна строчка на проверку.

Перепиши if так, чтобы была одна строчка на проверку.

MyEnum result;
if (row == null) result = MyEnum.NotAllowed;
else if (row.Age > 100) result = MyEnum.Died;
else result = MyEnum.StillAlive;
#15 
alex445 коренной житель22.02.24 01:17
NEW 22.02.24 01:17 
в ответ NightWatch 21.02.24 22:59, Последний раз изменено 22.02.24 01:28 (alex445)

Тоже можно. Но текста куда больше из-за засилья словесных операторов и присвоения в каждой строчке.

С другой стороны, в моём варианте используются ненужные мне дискарды в качестве костылей. В идеале должно быть [условие] => [возврат].


Вот красным отметил информационный мусор в моём и вашем вариантах


#16 
Murr патриот22.02.24 01:57
Murr
NEW 22.02.24 01:57 
в ответ alex445 22.02.24 01:17

В идеале должно быть [условие] => [возврат].

------

Об этом мы спорили во времена Аксесс 2.

есть плюсы... есть и минусы...

Самый простой вопрос - у тебя два и более различаемых условий независящих от переменной в свитче - что писать будешь?

Чуть более сложный - что с производительностью при большом числе правил?

#17 
alex445 коренной житель22.02.24 13:58
NEW 22.02.24 13:58 
в ответ Murr 22.02.24 01:57, Последний раз изменено 22.02.24 14:04 (alex445)
Самый простой вопрос - у тебя два и более различаемых условий независящих от переменной в свитче - что писать будешь?

Свободно можно использовать. Как я выше написал - сначала нужен костыль-значение с типом переменной, или дискард, а затем "when" и далее любые проверки с любыми переменными из контекста, в котором находится данный свитч. Разве что результат такой проверки должен быть булевым.


Про производительность не знаю. По-моему, раз все эти проверки условий (if-else, switch) взаимозаменяемы, то они генерятся в одинаковый исполняемый код. Их разные записи - лишь для удобства использования в разных случаях. А значит вопрос производительности того или другого высокоуровневого кода не стоит - стоит вопрос производительности итогового исполняемого кода. Ну, думаю, там какую-нибудь хеш-таблицу замутили на все обозначенные программистом комбинации условий, так что при проходе по ветке условий сразу нужная имплементация выполняется.

#18 
Murr патриот22.02.24 14:12
Murr
NEW 22.02.24 14:12 
в ответ alex445 22.02.24 13:58

то они генерятся в одинаковый исполняемый код.

------

не обязательно...

#19 
AlexNek патриот22.02.24 19:26
AlexNek
NEW 22.02.24 19:26 
в ответ alex445 21.02.24 20:30
проверки могут быть где угодно

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


Я бы еще посчитал, что нам потребуется для предыдущего кода во всех местах.


вы и тут правила свои напишете

единого решения для всех случаев жизни не существует

#20 
AlexNek патриот22.02.24 22:33
AlexNek
NEW 22.02.24 22:33 
в ответ alex445 20.02.24 16:44

Два дискарда это нехорошо для switch expression

Отчего хотя - бы так? или более привычно через switch statement

            var ret = row switch
                {
                    Row { Age: > 100 } => MyEnum.Died,
                    Row { Age: <= 100 } => MyEnum.StillAlive,
                    _ => MyEnum.NotAllowed
                };
#21 
alex445 коренной житель22.02.24 22:34
NEW 22.02.24 22:34 
в ответ AlexNek 22.02.24 19:26
ну тогда и ничего обсуждать о подобной программе, делайте как нравится и будет счастливы.

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

#22 
alex445 коренной житель22.02.24 22:38
NEW 22.02.24 22:38 
в ответ AlexNek 22.02.24 22:33

Не, это ещё больший костыль - объекты создавать лишь для сравнения с константой.

А этот паттерн с созданием нового объекта с проверкой при инициализации - он вообще трудночитаем. Без подробного пояснения, что там происходит, непонятно.

Дискард с условием when проще и понятнее.

#23 
AlexNek патриот22.02.24 22:47
AlexNek
NEW 22.02.24 22:47 
в ответ alex445 22.02.24 22:38
объекты создавать лишь для сравнения с константой.


где создание объекта? шок


Можно и так написать

            var ret = row switch
                {
                    { Age: > 100 } => MyEnum.Died,
                    { Age: <= 100 } => MyEnum.StillAlive,
                    _ => MyEnum.NotAllowed
                };
#24 
AlexNek патриот22.02.24 22:49
AlexNek
NEW 22.02.24 22:49 
в ответ alex445 22.02.24 22:38
Дискард с условием when проще и понятнее.

еще большая белиберда смущ

#25 
alex445 коренной житель22.02.24 22:57
NEW 22.02.24 22:57 
в ответ AlexNek 22.02.24 22:47

Это же и есть создание объекта, только анонимного. Нет?

#26 
alex445 коренной житель22.02.24 23:08
NEW 22.02.24 23:08 
в ответ AlexNek 22.02.24 22:49
Дискард с условием when проще и понятнее.

еще большая белиберда смущ

Скажем так - дискард с when позволяет провести проверку, не привязанную к параметру свича.

#27 
AlexNek патриот22.02.24 23:39
AlexNek
NEW 22.02.24 23:39 
в ответ alex445 22.02.24 23:08
дискард с when позволяет провести проверку, не привязанную к параметру свича.

Не совсем так... Извращаться можно по разному


int a = 2;
MyEnum ret = row switch
{
    { Age: > 100 } when a == 2 => MyEnum.Died,
    { Age: <= 100 } => MyEnum.StillAlive,
    _ => MyEnum.NotAllowed
}
#28 
alex445 коренной житель23.02.24 21:25
NEW 23.02.24 21:25 
в ответ AlexNek 22.02.24 23:39, Последний раз изменено 23.02.24 21:26 (alex445)
Скажем так - дискард с when позволяет провести проверку, не привязанную к параметру свича...

...и при этом иметь меньше мусора и извращений. Добавить не нужный мне здесь символ подчёркивания - меньшее из зол.

#29 
AlexNek патриот23.02.24 21:42
AlexNek
NEW 23.02.24 21:42 
в ответ alex445 23.02.24 21:25
Добавить не нужный мне здесь символ подчёркивания

Это и есть очень большая проблема. discard pattern ... that doesn't have the corresponding member of the Direction enumeration

https://learn.microsoft.com/en-us/dotnet/csharp/language-r...

То бишь, это то, что должно выполнятся когда ничего не совпадает. И енто обычно одно и только одно.

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

#30 
Срыв покровов патриот24.02.24 00:07
NEW 24.02.24 00:07 
в ответ alex445 23.02.24 21:25

я чот не пойму, а что в этом варианте не по фен-шую?

var result = row?.Age switch
{
    null => MyEnum.NotAllowed,
    > 100 => MyEnum.Died,
    _ => MyEnum.StillAlive,
};
#31 
Murr патриот24.02.24 02:40
Murr
NEW 24.02.24 02:40 
в ответ AlexNek 23.02.24 21:42

И енто обычно одно и только одно.

-------

хи-хи... Я его об этом уже спрашивал...

Решение, кстати, есть.Но! оно - медленное...

#32 
AlexNek патриот24.02.24 11:28
AlexNek
NEW 24.02.24 11:28 
в ответ Murr 24.02.24 02:40
Решение, кстати, есть

решение чего? Но всё равно - давай.

#33 
alex445 коренной житель24.02.24 12:13
NEW 24.02.24 12:13 
в ответ AlexNek 23.02.24 21:42
Вместо одного ожидаемого дискарда их фиг знает сколько и ради чего?

А вдруг...?

#34 
alex445 коренной житель24.02.24 12:20
NEW 24.02.24 12:20 
в ответ Срыв покровов 24.02.24 00:07
я чот не пойму, а что в этом варианте не по фен-шую?

Я тоже не пойму. Вот и спрашиваю - у кого тут это не по феншую?

#35 
alex445 коренной житель24.02.24 12:25
NEW 24.02.24 12:25 
в ответ Murr 24.02.24 02:40, Последний раз изменено 24.02.24 12:38 (alex445)
И енто обычно одно и только одно.
-------
хи-хи... Я его об этом уже спрашивал...
Решение, кстати, есть.Но! оно - медленное...

Я вроде отвечал - иногда охото сравнить разнотиповые значения, а вернуть - одого типа. Скажем, проверить одну переменную double на пачку диапазонов, и вторую строковую переменную - на пару значений. А вернуть что-то из enum, например. Или вот тут что непонятного - делаю проверку всего объекта на налл, затем свойства этого объекта - ещё как-то, и кейс для всех остальных вариантов? И делаю это не пачкой if-else, а в несколько компактных строчек. Усложнил свой первоначальный пример - сколько это расписывать деревом if-else?


var (result, message) = (row, flag) switch
{
    (null, _) => (MyEnum.NotAllowed, null),
    (_, Flags.CantDie) when row.Age > 100 => (MyEnum.Immortal, LocalizedStrings.Immortal),
    (_, _) when row.Age > 100 => (MyEnum.Died, LocalizedStrings.Died),    
    (_, _) => (MyEnum.StillAlive, LocalizedStrings.Alive),
};
#36 
AlexNek патриот24.02.24 12:25
AlexNek
NEW 24.02.24 12:25 
в ответ alex445 24.02.24 12:13
А вдруг...?

ну так для этого есть нормальные условия. А иначе получается следующее:

switch(x){
  case b:... break;
  case c:... break;
...
  default when(a==5):...break;
  default :...break;

}
#37 
alex445 коренной житель24.02.24 12:35
NEW 24.02.24 12:35 
в ответ AlexNek 24.02.24 12:25, Последний раз изменено 24.02.24 12:39 (alex445)
А вдруг...?
ну так для этого есть нормальные условия

Не всегда условия нормальные...


#38 
Срыв покровов патриот24.02.24 13:43
NEW 24.02.24 13:43 
в ответ alex445 24.02.24 12:20
Вот и спрашиваю - у кого тут это не по феншую?

это я твой код чуть переделал, остался только один дискард. Комар AlexNek носа не подточит

#39 
Murr патриот24.02.24 14:31
Murr
NEW 24.02.24 14:31 
в ответ AlexNek 24.02.24 11:28

решение чего?

-------

Проблемы двух и более срабатывающих кэйсов в одном свитче.

А решение - последовательное вычисление каждого условия... и - да - результат начинает зависеть от положения селектора, но прикладники сказали что им пофиг...

#40 
AlexNek патриот24.02.24 20:27
AlexNek
NEW 24.02.24 20:27 
в ответ Срыв покровов 24.02.24 00:07
я чот не пойму, а что в этом варианте не по фен-шую?

Очень даже много смущ

1. Проверяется всего лишь одно поле, жирно слишком будет, по свитчу на каждое поле.

2. Если Age будет нуллабле и мне нужно будет отличать варианты или объект null или возраст null (не указан), то приплыли.

3. Происходит инверсия понятий - дискард вешается на "нормальный" вариант. Можно конечно и так, но это тогда должно быть везде. И если еще какой-то отрицательный вариант был забыт, то получаем по умолчанию Ок, что не есть правильно.

#41 
Fleitist прохожий24.02.24 20:48
NEW 24.02.24 20:48 
в ответ alex445 20.02.24 16:20

Если вопрос про красивости, то такой код на код-ревью я бы не принял. Во-первых затраты на его понимание превышают пределы чтения тривиальной проверки на null и тернарного оператора ?:. Во-вторых, а соответствует ли он Kodierrichtlinien? В третих, такая нотация предполагает знание Linq в контексте SQL, что является избыточным для тривиального куска кода общего назначения. Короче, привнесена специфика туда, где она даром не нужна; не будет сходу всем понятна и на нее нужно тратить время. Но это ИМХО конечно же.

#42 
alex445 коренной житель24.02.24 21:16
NEW 24.02.24 21:16 
в ответ Срыв покровов 24.02.24 13:43
это я твой код чуть переделал, остался только один дискард. Комар AlexNek носа не подточит

Теперь ещё мой вариант с кортежами переделайте, чтобы тоже не подточил.

#43 
alex445 коренной житель24.02.24 21:28
NEW 24.02.24 21:28 
в ответ Murr 24.02.24 14:31

решение чего?

-------

Проблемы двух и более срабатывающих кэйсов в одном свитче.

А решение - последовательное вычисление каждого условия... и - да - результат начинает зависеть от положения селектора, но прикладники сказали что им пофиг...

Если у вас срабатывают более одного кейса, значит у вас должно быть больше кейсов - где-то вы не поделили один кейс на несколько. А я предложил то же решение, что и у вас, но вместо последовательного перечисления одного кейса за раз, а проверяю кейсы попарно, потройно и т.д. за счёт ключевого слова when. Это позволяет объединить проверки в группы по их логике. Плюс кортежи - ещё удобнее.


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

#44 
alex445 коренной житель24.02.24 21:41
NEW 24.02.24 21:41 
в ответ Fleitist 24.02.24 20:48, Последний раз изменено 24.02.24 21:42 (alex445)
Во-первых затраты на его понимание превышают пределы чтения тривиальной проверки на null и тернарного оператора ?:.

Проверка на налл и этот ваш оператор могут максимум 4 кейса проверить. Кроме того, в вашем случае вы смешиваете разные операторы - сначала if-else (на налл), затем ?:. У меня всё проверено единообразно в 3-5 строчек, а не на треть экрана расписано. По сути у меня понятная и удобная таблица истинности, а не кучка разномастных операторов.


Во-вторых, а соответствует ли он Kodierrichtlinien?

Смотря какие linien. Но странно, если они будут запрещать использовать свичи и вообще всё новое из новых версий Дотнета, хотя проект именно на этих версиях написан. Зачем на новые версии переходить тогда? Последняя Виндовс поддерживает в том числе и старые версии Дотнета - старпёрь, не хочу.


В третих, такая нотация предполагает знание Linq в контексте SQL, что является избыточным для тривиального куска кода общего назначения. Короче, привнесена специфика туда, где она даром не нужна; не будет сходу всем понятна и на нее нужно тратить время. Но это ИМХО конечно же.

Линка там нет. А кто не знает язык - его проблемы. Может, мне на второй версии Дотнета писать, а то кто-то в 20-летней давности застрял? Объективно, у меня нет никаких ребусов, над которыми надо было бы ломать голову, а кортежи и свичи - это уже считайте азы.


Насчёт сходу всем понятна - те, кто изучают язык с последних версий, могут как раз не понять портянку if-else вместо удобной таблицы истинности, записанной свичом, постоянные проверки на налл через те же if-else вместо null propagation. Вобщем, всё относительно. Но идти на поводу у старпёров, которые дальше второй-третьей версии Дотнета и языка не ушли, нет смысла. Особенно, когда сам проект на одной из последних версий.


"Красивости" это только звучит "даром не нужно". Но если это позволяет записать код в 3 раза короче, умещая на один экран, то это делает его зачастую и понятнее, т.к. не надо скроллить туда-сюда, теряя контекст.

#45 
AlexNek патриот24.02.24 22:18
AlexNek
NEW 24.02.24 22:18 
в ответ alex445 24.02.24 21:41
По сути у меня понятная и удобная таблица истинности

Есть такое предположение, что она будет понятна и удобна исключительно автору смущ

#46 
alex445 коренной житель24.02.24 22:23
NEW 24.02.24 22:23 
в ответ AlexNek 24.02.24 22:18

Мы вам перезвоним...

#47 
Fleitist прохожий24.02.24 22:55
NEW 24.02.24 22:55 
в ответ alex445 24.02.24 21:41

Ну я же упомянул ИМХО, не злитесь. Когда-то Страуструп сказал, что мы не может ориентироваться на невежество читателя в написании кода (что-то в этом духе), но к сожалению эти времена прошли. Сейчас времена аджайла, среднестатистического разработчика, спринты, тайм ту маркет и вообще приближение индустрии 4.0. Гении не нужны - "Не дядя Вова, скрипач не нужен"

#48 
Fleitist прохожий24.02.24 23:18
NEW 24.02.24 23:18 
в ответ alex445 24.02.24 21:41

Я думаю, мы в целом о разных вещах говорим. Если вы остаетесь в рамках некоей технической реализации, то ок, ваш код имеет место быть - ваше право и ваш креатив. Если же мы пытаемся его интегрировать, то нужно рассматривать другие аспекты, например, скажут ли вам спасибо все остальные читатели вашего кода в рамках вашего проекта. Ну и старперы, куда уж без них.

#49 
alex445 коренной житель24.02.24 23:29
NEW 24.02.24 23:29 
в ответ Fleitist 24.02.24 23:18, Последний раз изменено 24.02.24 23:32 (alex445)

Свитч выражения введены в 8 версии Сишарпа в 2019 году, с первой версии Дотнет Коре. Зачем нам переходить на Коре, если мы сидим на скажем третьей версии (2006 год)?


Видел команды, которые пишут на WPF как на формах - не используя привязки, шаблоны, стили, словари ресурсов, команды - вобщем, ничего из MVVM. Просто фигачат в code-behind, вместо стилей повторяют все настройки представления для каждого элемента копипастингом, если они одинаковые. Крутые сеньёры, уже много лет поддерживающие крупный проект для крупных фирм. Походу, они и разметку не использовали, а лишь визуальный редактор форм - что генерилось в разметке, их не интересовало. Непонятно, зачем им нужен был WPF. И вот такие чудаки обкладываются всякими linien - сами нормально не пишут, и другим не дают.

#50 
Fleitist прохожий25.02.24 00:08
NEW 25.02.24 00:08 
в ответ alex445 24.02.24 23:29
Зачем нам переходить на Коре, если мы сидим на скажем третьей версии (2006 год)?

Кстати да, а зачем переходить? Какие-то есть обоснования к переходу? Мы закроем какие-то бизнес-кейсы? Или давайте просто потратим деньги?


Видел команды, которые пишут на WPF как на формах - не используя привязки, шаблоны, стили, словари ресурсов, команды - вобщем, ничего из MVVM

Легаси код. Интересный вопрос: нужен ли редизайн или мы остаемся консистентными? Как сами думаете?


сами нормально не пишут, и другим не дают

Вот жеж ... нехорошие люди. Как жить-то? Нужен манифест джунов, ибо им там не здесь, не посрамим и т.п. Вам самому не смешно?

#51 
Срыв покровов патриот25.02.24 00:20
NEW 25.02.24 00:20 
в ответ AlexNek 24.02.24 22:18
Есть такое предположение, что она будет понятна и удобна исключительно автору

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

#52 
Срыв покровов патриот25.02.24 00:28
NEW 25.02.24 00:28 
в ответ AlexNek 24.02.24 20:27
Проверяется всего лишь одно поле, жирно слишком будет, по свитчу на каждое поле.

вообще пофиг. Если решение занимает вместо 15 строк всего 5, то я за

Если Age будет нуллабле и мне нужно будет отличать варианты или объект null или возраст null (не указан), то приплыли.

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

Происходит инверсия понятий - дискард вешается на "нормальный" вариант.

в какой-то библии написано, что дискард обязательно должен обрабатывать нештатные ситуации? Рассматривай его как обычный else, не забивай себе голову.

#53 
alex445 коренной житель25.02.24 09:25
NEW 25.02.24 09:25 
в ответ Fleitist 25.02.24 00:08, Последний раз изменено 25.02.24 09:35 (alex445)
Зачем нам переходить на Коре, если мы сидим на скажем третьей версии (2006 год)?
Кстати да, а зачем переходить? Какие-то есть обоснования к переходу? Мы закроем какие-то бизнес-кейсы? Или давайте просто потратим деньги?

Если долго не переходить, то потом можно закрыть не бизнес кейсы, а бизнес вообще.


У нас тоже лет 15-20 не переходили, а потом МС поддержку IE зарубила, и пришлось всё приложение переписывать. Ну зато копеечки по постепенному и планомерному переходу экономили. А сейчас - срочно нужно вбухать много денег и в темпе вальса свинга переписать почти всё, а что не переписать - то есть застарелое самописное дерьмо, хреново косящее под Entity Framework. Т.е. это тоже надо переписать, а точнее безопасно удалить и заменить на EF.

#54 
alex445 коренной житель25.02.24 09:27
NEW 25.02.24 09:27 
в ответ Fleitist 25.02.24 00:08
нужен ли редизайн или мы остаемся консистентными?

бронзовыми

#55 
alex445 коренной житель25.02.24 09:31
NEW 25.02.24 09:31 
в ответ AlexNek 24.02.24 20:27
2. Если Age будет нуллабле и мне нужно будет отличать варианты или объект null или возраст null (не указан), то приплыли.

Ничё не понял. Напишите пример. Если у вас есть пачка if-else или что подобное, то любая такая древовидная структура трансформируется в пачку кейсов свича (и обратно). Только не увлекайтесь этими развесистыми деревьями - когда у вас эта хрень начнёт уезжать за экран, вам предъявят, и вы сами захотите изменить со свичём.

#56 
alex445 коренной житель25.02.24 09:34
NEW 25.02.24 09:34 
в ответ Срыв покровов 25.02.24 00:28, Последний раз изменено 25.02.24 09:34 (alex445)
дискард обязательно должен обрабатывать нештатные ситуации? Рассматривай его как обычный else

Любой else (т.е. дискард, дефолт и прочее "всё, что не предыдущее") может быть дальше расширен сколько угодно, если поступят такие требования. У Алекснека же требования всё возрастают - наллы во все поля повводил?

#57 
MrSanders коренной житель25.02.24 11:17
NEW 25.02.24 11:17 
в ответ Срыв покровов 25.02.24 00:28
вообще пофиг. Если решение занимает вместо 15 строк всего 5, то я за

Не согласен. Не в общем случае. Есть разные строчки. Посмотри на пёрл. Вот где разгул для сокращателей. Только месяц спустя сам автор не мог объяснить что же он своим !__$@x.{__?$%x} хотел сказать. Зато одно строчка вместо 3.

5 if-else заменить на switch? Отлично. Но если мне для этого придётся писать brainfuck-подобный код, то лучше остаться с ифами.

#58 
AlexNek патриот25.02.24 11:54
AlexNek
NEW 25.02.24 11:54 
в ответ Срыв покровов 25.02.24 00:20
потом мы удивляемся, почему в Германии не создаются никакие продуктов мирового масштаба.

Точно, вы открыли мне глаза, теперь я знаю отчего в Германии не очень высокая рождаемость.

Недостаток женщин с пирсингом - это же так круто и бабанькам с закостенелым мозгом это не нужно.

#59 
AlexNek патриот25.02.24 12:11
AlexNek
NEW 25.02.24 12:11 
в ответ Срыв покровов 25.02.24 00:28
Рассматривай его как обычный else, не забивай себе голову.

дело то не в этом.

Во первых, switch expression лучше сравнивать с switch statement. И как часто, в части "по умолчанию", используется "это нормально".

Во вторых, условие - "всё что не проверено это хорошо" часто не очень хороший выбор. Ну вот, что будет если возраст будет отрицательным и мы это не проверили?


#60 
AlexNek патриот25.02.24 12:15
AlexNek
NEW 25.02.24 12:15 
в ответ alex445 25.02.24 09:31
Ничё не понял. Напишите пример.

int? Age; - так понятней или нужно всё расписать?


Только не увлекайтесь этими развесистыми деревьями

Даже и в этом варианте всё может выглядеть прилично

if(person.HasValidAge())...

#61 
AlexNek патриот25.02.24 12:25
AlexNek
NEW 25.02.24 12:25 
в ответ alex445 25.02.24 09:34
Любой else (т.е. дискард, дефолт и прочее "всё, что не предыдущее")

не нужно всё мешать в одну кучу.

И можно смотреть на проблему с разных сторон или с разной "высоты". Домик на земле выглядит совсем по другому, чем с высоты птичьего полета.

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


Или - работаю ли я один или в команде. Как мы будет решать подобные проблемы в будущем?


#62 
alex445 коренной житель25.02.24 13:29
NEW 25.02.24 13:29 
в ответ MrSanders 25.02.24 11:17

Не согласен. Не в общем случае. Есть разные строчки. Посмотри на пёрл. Вот где разгул для сокращателей. Только месяц спустя сам автор не мог объяснить что же он своим !__$@x.{__?$%x} хотел сказать. Зато одно строчка вместо 3.

5 if-else заменить на switch? Отлично. Но если мне для этого придётся писать brainfuck-подобный код, то лучше остаться с ифами.

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

#63 
alex445 коренной житель25.02.24 13:31
NEW 25.02.24 13:31 
в ответ AlexNek 25.02.24 11:54
потом мы удивляемся, почему в Германии не создаются никакие продуктов мирового масштаба.

Точно, вы открыли мне глаза, теперь я знаю отчего в Германии не очень высокая рождаемость.

Недостаток женщин с пирсингом - это же так круто и бабанькам с закостенелым мозгом это не нужно.

Не оффтопте своими скелетами в шкафах, а то я начну про домик у моря!

#64 
alex445 коренной житель25.02.24 13:33
NEW 25.02.24 13:33 
в ответ AlexNek 25.02.24 12:11
Во вторых, условие - "всё что не проверено это хорошо" часто не очень хороший выбор. Ну вот, что будет если возраст будет отрицательным и мы это не проверили?

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

#65 
alex445 коренной житель25.02.24 13:35
NEW 25.02.24 13:35 
в ответ AlexNek 25.02.24 12:15, Последний раз изменено 25.02.24 13:36 (alex445)
Ничё не понял. Напишите пример.
int? Age; - так понятней или нужно всё расписать?

Нет, вы напишите, как вы будете свои налловые сосиски (типа person?.Age?.) проверять на разные условия для Age. А я потом подумаю, как это удобно в свиче записать. А то вы просто сказали, что у вас всё налл, а как вы с этим обращаетесь - не сказали.


if(person.HasValidAge())...

А портянка внутри HasValidAge как выглядит?

#66 
AlexNek патриот25.02.24 14:11
AlexNek
NEW 25.02.24 14:11 
в ответ alex445 25.02.24 13:31
Не оффтопте

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

А про домик у моря мы уже вроде всё знаем бебе

#67 
AlexNek патриот25.02.24 14:13
AlexNek
NEW 25.02.24 14:13 
в ответ alex445 25.02.24 13:33
В математике, например

А мы обсуждаем тут математику или что то другое?

#68 
AlexNek патриот25.02.24 14:33
AlexNek
NEW 25.02.24 14:33 
в ответ alex445 25.02.24 13:35
А портянка внутри HasValidAge как выглядит?

Во первых, при чтении данной части кода не интересует что там внутри.

Во вторых, будет выглядеть не сложнее кода снаружи.

В третьих, извращения занести будет сложнее.

#69 
AlexNek патриот25.02.24 14:58
AlexNek
NEW 25.02.24 14:58 
в ответ alex445 25.02.24 13:35
а как вы с этим обращаетесь - не сказали.

говорилось...

https://foren.germany.ru/showmessage.pl?Number=40802311&Bo...

Можно еще условие на налл добавить

#70 
alex445 коренной житель25.02.24 16:29
NEW 25.02.24 16:29 
в ответ AlexNek 25.02.24 14:58, Последний раз изменено 25.02.24 16:30 (alex445)

Т.е. проверка Age на налл делается легко и непринуждённо ещё одним кейсом.


И ещё раз - дискард с when я использую лишь в качестве костыля. Когда создатели языка дадут возможность добавлять кейсы, не привязанные к типу параметра свича, я избавлюсь от этого костыля, и станет снова всё по вашему феншую - один дискард на свич. С точки зрения компилятора, у меня и сейчас всё по феншую - один дефолтный кейс на свич. Дискард с when это не дефолтный кейс.

#71 
AlexNek патриот25.02.24 17:36
AlexNek
NEW 25.02.24 17:36 
в ответ alex445 25.02.24 16:29
Когда создатели языка дадут возможность добавлять кейсы, не привязанные к типу параметра свича

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

#72 
alex445 коренной житель25.02.24 21:39
NEW 25.02.24 21:39 
в ответ AlexNek 25.02.24 17:36

Где, как?

#73 
Murr патриот25.02.24 21:44
Murr
NEW 25.02.24 21:44 
в ответ AlexNek 25.02.24 14:11

А про домик у моря мы уже вроде всё знаем бебе

--------

Не-не, мы точно знаем не все!!!

а вот сколько не знаем - точно не знаем. безум


#74 
AlexNek патриот25.02.24 21:46
AlexNek
NEW 25.02.24 21:46 
в ответ alex445 25.02.24 21:39
Где, как?

уже и пример давал с when смущ без дискарда

#75 
AlexNek патриот25.02.24 22:07
AlexNek
NEW 25.02.24 22:07 
в ответ Murr 25.02.24 21:44
а вот сколько не знаем

Это всё фигня - надо кричать, что гитом в студии опасно пользоваться.

Всё время делал без студии, выбираешь любой файл и откатываешь все последние изменения. Но проблемо.


А тут работаю с компонентом у которого есть еще "подфайлы": код, разметка стилей и ява скрипт.

Ну думаю, откачу компонент (тест не сработал), так эта гадина откатила всё на исходное состояние и код и яву скрипт и стили зло

#76 
alex445 коренной житель25.02.24 22:14
NEW 25.02.24 22:14 
в ответ Murr 25.02.24 21:44

А про домик у моря мы уже вроде всё знаем бебе

--------

Не-не, мы точно знаем не все!!!

а вот сколько не знаем - точно не знаем.

Я когда узнал, что вам минимум 5 спален подавай... Но я про что-то такое и думал. ))

#77 
alex445 коренной житель25.02.24 22:16
NEW 25.02.24 22:16 
в ответ AlexNek 25.02.24 21:46
Где, как?

уже и пример давал с when смущ без дискарда

Ну значит всё в порядке, и можно снова добавлять дискарды по вкусу.

#78 
alex445 коренной житель25.02.24 22:21
NEW 25.02.24 22:21 
в ответ AlexNek 25.02.24 22:07, Последний раз изменено 25.02.24 22:26 (alex445)

Т.е. вы в окошке Git Changes (справа) не можете выбрать только один файл компонента для откатывания?


В окне проектов эти части компонента могут располагаться в древовидной структуре. Но в директории они лежат все в плоской структуре, и никак не связаны. Гит отслеживает изменения не по компонентам, а по файлам. Не надо тыкать компонент в окне проектов и отменять там через контекстное меню Гита. Надо в окне изменений Гита, и отменять для каждого файла в отдельности.


Видите, те файлы, которые в окне проектов представлены типа связанными, в окне изменений - все по отдельности




#79 
AlexNek патриот25.02.24 22:26
AlexNek
NEW 25.02.24 22:26 
в ответ alex445 25.02.24 22:21, Последний раз изменено 25.02.24 22:27 (AlexNek)

на кой еще и окошко, так я могу и в другой проге сделать.

В Solution explorer есть контекстное меню и выбирается один файл

#80 
alex445 коренной житель25.02.24 22:28
NEW 25.02.24 22:28 
в ответ AlexNek 25.02.24 22:26, Последний раз изменено 25.02.24 22:28 (alex445)

Вот неправильно юзать для компонентов это контекстное меню. Надо из окошка Гита выбирать каждый файл в отдельности.


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

#81 
AlexNek патриот25.02.24 22:30
AlexNek
NEW 25.02.24 22:30 
в ответ alex445 25.02.24 22:21
Не надо тыкать компонент в окне проектов и отменять там через контекстное меню Гита.

ну так именно в этом и есть удобство - никуда не нужно переходить.

#82 
alex445 коренной житель25.02.24 22:31
NEW 25.02.24 22:31 
в ответ AlexNek 25.02.24 22:30

Когда надо отменить всё для целого компонента, тогда да - удобно. Но вы же себя за локоть пытаетесь укусить, поэтому вам нужно через окошко изменений. ))

#83 
AlexNek патриот25.02.24 22:34
AlexNek
NEW 25.02.24 22:34 
в ответ alex445 25.02.24 22:28
Надо из окошка Гита выбирать каждый файл в отдельности.

А на кой мне тогда гит спаренный со студией? Так я могу и в моей любимой проге работать.


команды гитовские в консоли набираете

Как подобная глупость могла прийти в голову? смущ Вместо контекстного меню то.

#84 
AlexNek патриот25.02.24 22:36
AlexNek
NEW 25.02.24 22:36 
в ответ alex445 25.02.24 22:31
Когда надо отменить всё для целого компонента

Надо предупреждать, никогда еще подобное не нужно было

#85 
alex445 коренной житель25.02.24 22:39
NEW 25.02.24 22:39 
в ответ AlexNek 25.02.24 22:34
Как подобная глупость могла прийти в голову? смущ Вместо контекстного меню то.

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



#86 
AlexNek патриот25.02.24 22:51
AlexNek
NEW 25.02.24 22:51 
в ответ alex445 25.02.24 22:39
Нафига копаться в развесистом контекстном меню,

там не так уж и много. И файл вот он рядом.

А что бы добраться до кнопочки, нужно открыть/перейти в нужное окно и найти нужный файл. Вроде и фигня но лишние действия.

Тем более, что из студии делал всегда только это единственное действие - откат одного файла.

#87 
alex445 коренной житель25.02.24 23:48
NEW 25.02.24 23:48 
в ответ AlexNek 25.02.24 22:51
А что бы добраться до кнопочки, нужно открыть/перейти в нужное окно и найти нужный файл.

У вас коммиты всегда на десятки файлов, что вы в изменённых файлах путаетесь?


На нормальном рабочем месте все нужные окошки всегда открыты. Т.е. нужно просто передвинуть мышку и жмакнуть.

#88 
MrSanders коренной житель26.02.24 09:48
NEW 26.02.24 09:48 
в ответ AlexNek 25.02.24 22:34
Как подобная глупость могла прийти в голову? смущ Вместо контекстного меню то.

Гы-гы. В пятницу прибегали такие тыркатели. "Мы чо-то натыркали и там всё-всё паламаласяаааа!" Не туда ткнули когда мерж конфликты разрешали, один щелчок не на том пункте контекстного меню и мы уже выбираем "бери ours для всех". Пришлось коммиты копировать, чтобы историю не корячить. И почему мне платят в полтора раза больше чем этим тыркателям, даже не знаю :)

#89 
alex445 коренной житель26.02.24 15:56
NEW 26.02.24 15:56 
в ответ MrSanders 26.02.24 09:48

То ли дело не та команда, введённая в консоли вручную - всё совсем по-другому. Про опечатки и не говорю - их не бывает в принципе.

#90 
AlexNek патриот26.02.24 18:19
AlexNek
NEW 26.02.24 18:19 
в ответ alex445 25.02.24 23:48
На нормальном рабочем месте

У каждого свои критерии нормальности. Никакие гитовские окна мне в студии нафиг не нужны.

#91 
AlexNek патриот26.02.24 18:23
AlexNek
NEW 26.02.24 18:23 
в ответ MrSanders 26.02.24 09:48
Гы-гы. В пятницу прибегали такие тыркатели.

ну вроде уже огромное количество раз обсуждали.

Кому-то WinDiff нравится, кому то нет. А ошибки могут быть в любом случае, причем предполагаю, в случае с командой строкой более серьезные.

#92 
MrSanders коренной житель26.02.24 20:21
NEW 26.02.24 20:21 
в ответ alex445 26.02.24 15:56
Про опечатки и не говорю - их не бывает в принципе.

Я тебе глаза открою - если опечатаешься, команда не выполнится. Адекватные разработчики делают параметры такими, чтобы "апичатки" не были действительными: --delete это параметр, а --dwlete - нет.

В гите я наблюдаю очень чёткую корелляцию:тупые гуисты и адекватные консольщики. У нас есть и те и те. Не значит что консольщики не делают ошибок. Но у них в 99,99% случаев хватает мозгов на запушить их на ремоут.

#93 
alex445 коренной житель26.02.24 23:31
NEW 26.02.24 23:31 
в ответ MrSanders 26.02.24 20:21

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


В гите я наблюдаю очень чёткую корелляцию:тупые гуисты и адекватные консольщики. У нас есть и те и те. Не значит что консольщики не делают ошибок. Но у них в 99,99% случаев хватает мозгов на запушить их на ремоут.

А если консольщики всё же какают, то исключительно бабочками. ))

#94 
Murr патриот27.02.24 11:29
Murr
NEW 27.02.24 11:29 
в ответ MrSanders 26.02.24 09:48

В пятницу прибегали такие тыркатели.

-------

Папа! а что означает "Format drive C: complete!"?

#95 
alex445 коренной житель27.02.24 11:31
NEW 27.02.24 11:31 
в ответ Murr 27.02.24 11:29

Это означает, что перепутал консольные команды.

#96 
alex445 коренной житель01.03.24 13:35
NEW 01.03.24 13:35 
в ответ alex445 27.02.24 11:31, Последний раз изменено 01.03.24 13:41 (alex445)

О, дополнение к кортежам. Вместо того, чтобы писать свой тип для простого объединения пачки данных, можно воспользоваться кортежем:


public (int TheInteger, string TheString, bool TheBoolean)? Data { get; set; } = new(999, "blah blah", true);

var a = Data?.TheString;


Даже record не нужен.

Единственный минус видится (ещё не пробовал) - передать такой тип данных куда-то - надо указывать всю портянку кортежа - типа

MyMethod((int, string, bool) methodParameter);

#97 
Fleitist прохожий02.03.24 20:33
NEW 02.03.24 20:33 
в ответ alex445 01.03.24 13:35

Попытайтесь ввести кортежу псевдоним... Это покажет, что даже компилятор не воспринимает данный синтаксический сахар, как нечто серьезное. Фоновое локальное решение - ок, прячем в недрах фреймворка - всем пох. Но когда такое вылазит в паблик, особенно с внешними стекхолдерами, у меня для вас плохие новости - вам останется только петь про старперов:)

#98 
alex445 коренной житель03.03.24 05:42
NEW 03.03.24 05:42 
в ответ Fleitist 02.03.24 20:33

Это вопрос привычки. Пока есть старпёры, которым удобнее писать развесистую лапшу с дополнительными типами, служащими лишь для хранения передаваемых данных (DTO), и длинные списки параметров методов - они будут это делать. Придут новички, которые пишут с новым синтаксисом изначально - для них код старпёров будет странным и непонятным. Как я сейчас смотрю, что человек упорно и раз за разом пишет 5-10-строчные проперти с банальными проверками на налл и присвоением параметра value, вместо использования однострочного оператора ??=. Или городит стопицот слоёв, свои прослойки, фреймворки, конвертеры и фабрики фабрик для случай "а вдруг мы заменим базу данных? а вдруг мы заменим UI-фреймворк?". Все его построения заменяются банальной трёхзвенкой, и если что будет заменено в будущем, то просто эта часть переписывается. Оттого, что он понаписал километры лапши с фабриками фабрик, он не становится умным, он становится ЗАумным. Когда он уйдёт с проекта, новый лид не будет разбираться в его лапше, а просто перепишет всё по-своему, поэтому все эти старания по размножению слоёв не стоят потраченного труда.


Что там внутри под сахаром происходит - вообще пофиг. Компилятор кучу и "старого привычного" кода превращает в свои конструкции - и что? Некоторые называют "сахаром" любые непривычные им вещи. Даже если эти новые вещи позволяют сократить запись по сравнению со старым кодом, что приводит к его большей компактности и пониманию. Т.е. используют этот термин просто как ругательство. Тогда по идее, надо бы наоборот - старую лапшу назвать "сахаром", а новые подходы - единственными и неповторимыми "тру".

#99 
AlexNek патриот03.03.24 10:11
AlexNek
NEW 03.03.24 10:11 
в ответ alex445 03.03.24 05:42
эти новые вещи позволяют сократить запись по сравнению со старым кодом, что приводит к его большей компактности и пониманию

Опять подняли знамёна и идем вперед с барабанным боем?

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

AlexNek патриот03.03.24 13:22
AlexNek
NEW 03.03.24 13:22 
в ответ alex445 03.03.24 05:42
Все его построения заменяются банальной трёхзвенкой, и если что будет заменено в будущем, то просто эта часть переписывается.

Не следует всё радикализировать. Каждый случай имеет аргументы за и против. А смотреть на всё исключительно со своей колокольни не есть оптимальный вариант.

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


Вот помню, кому-то страшно понравилось использовать синглтоны "для связи" различных частей программы - просто и не нужно ни о чём думать.

Но вот понадобилось "отвязать" одну часть...

alex445 коренной житель03.03.24 15:20
NEW 03.03.24 15:20 
в ответ AlexNek 03.03.24 13:22, Последний раз изменено 03.03.24 15:31 (alex445)

Пример моего проекта. Изначально был написан какими-то надмозгами - полстапроектов в солюшене. Куча слёв. Всё модульное, динамичное, расширяемое шопипец. Те, кто писали проект, продали его крупной фирме и удалились. Эта крупная фирма сама поддерживала проект лишь в части написания бизнес-логики, а вся остальная кухня эксплуатировалась почти без изменений примерно 15-20 лет, пока не прекратилась поддержка платформы, на которой крутилось гуёвая часть. Никакими расширениями никто не воспользовался. Вместо этого забронзовевший код не позволял использовать современные сторонние решения, т.к. никто не знал, как заменить скажем свою самописную ORM на нормальную современную, чтобы ничего не сломалось. Надмозги несколько лет писали спагетти-архитектуру, которая во многом оказалась не нужна. И трудноподдерживаема, если ты сам не тот надмозг, который её создавал.


В результате сильно позже и другие разработчики стали в авральном темпе переписывать всё на новое, удивляясь применяемым 20 лет назад решениям. Но тоже костыльным способом - сначала самые понятные и не сильно зависимые части, чтобы чего не сломать. Т.е. пишем новый гуй на современных технологиях, но с подходами старыми, создавая кучу подгоняющей обвязки - чтобы совместимость с другими слоями осталась. И пока сохраняем самописную ORM. Когда всё будет заменено, придётся эти подгоночные костыли убирать. Т.е. переписывать проект придётся в несколько проходов по одним и тем же слоям. Гораздо проще, понятнее и быстрее было бы постепенно обновлять все части приложения, переписывая их на современный манер и выкидывая самописные костыли и оказавшиеся ненужными переусложнённые вещи. А теперь придётся делать примерно то же самое, но не постепенно, а в авральном режеме.


Так что я вашу многослойность, модули и расширяемость труба шатал. За 15-20 лет устаревает сама архитектура и её подходы - все модули и слои скопом отправляются в помойку. Не к чему подключать, нечего расширять.


Fleitist прохожий03.03.24 16:22
NEW 03.03.24 16:22 
в ответ alex445 03.03.24 05:42

Да уж, накипело у вас... Я даже не поверил сначала, что вы всерьез все это пишете.


Понапридумывают этих ваших архитектур, а людям мучаться. Действительно, проще же все переписать:)

Срыв покровов патриот03.03.24 17:53
NEW 03.03.24 17:53 
в ответ Fleitist 03.03.24 16:22

Так он прав.

AlexNek патриот03.03.24 18:39
AlexNek
NEW 03.03.24 18:39 
в ответ alex445 03.03.24 15:20
Так что я вашу многослойность, модули и расширяемость...

Так о чём я и говорю, не надо всё радикализировать и обобщать. То что вам попался вариант неудачной архитектуры не означает, что везде всё так плохо с архитектурой. А вот то, что любой проект за 15-20 лет можно изменить до неузнаваемости в худшую сторону - это весьма и весьма вероятно. По крайней мере, обратного еще не попадалось.


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

Опять голубые мечты... сами же написали: "сначала самые понятные и не сильно зависимые части, чтобы чего не сломать."

А что делать с непонятными и сильно зависимыми частями?

Fleitist прохожий03.03.24 18:44
NEW 03.03.24 18:44 
в ответ Срыв покровов 03.03.24 17:53

Мне непонятно, как структурированный код можно называть спагетти? Это что ошибка в терминологии? Мне непонятно стремление к переписыванию всего и вся (весь мир пытается использовать код повторно и экономить деньги). Мне не импонирует агрессивное невежество. Проекты не живут в вакууме, и тимлид, которого тут так уничижительно поминали, должен учитывать всевозможные аспекты проекта. Даже те, которые не видны с низкого горизонта джуниоров и просто не могут быть ими осознаны, в силу отсутствия опыта. Наличие множества слоев (Layered Architecture), как раз признак, того что тимлид прекрасно отдает себе отчет, что такое менеджмент изменений и как можно редуцировать риски и затраты на поддержку. Это как раз называется зрелость, один из критериев качества продукта по ISO 25010, кстати.


Тут много еще чего можно написать, но мне просто лень.:)

Fleitist прохожий03.03.24 18:50
NEW 03.03.24 18:50 
в ответ AlexNek 03.03.24 18:39, Последний раз изменено 03.03.24 18:53 (Fleitist)
То что вам попался вариант неудачной архитектуры

Я думаю, что архитектура соответствовала своему времени и вполне отвечала требованиям. Потом ее бросили (ушел архитектор) и она стала дрифтовать, накапливался technische Schuld и т.д. Потом технологическая платформа устарела и всех бросили на "починку". Обычная история:)


Кстати удачность или неудачность оценивается в процессе ревью и другим архитектором. А не так как тут, поплевали на руки и оценили на раз:)

AlexNek патриот03.03.24 20:00
AlexNek
NEW 03.03.24 20:00 
в ответ Fleitist 03.03.24 18:50
Я думаю, что архитектура соответствовала своему времени и вполне отвечала требованиям

Бессмысленно обсуждать событие основываясь на показаниях одного не очень объективного свидетеля. смущ

Можно гадать долго и нудно.

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


архитектура соответствовала своему времени

просто ради интереса и язык немного почесать спок

А насколько устарел труд Эрика Эванса? Или хотя бы "Алгоритмы и структуры данных" Вирта от 1984 года?


В мусор и не вспоминать?

Fleitist прохожий03.03.24 20:43
NEW 03.03.24 20:43 
в ответ AlexNek 03.03.24 20:00
просто ради интереса и язык немного почесать спок

Конечно, а как же иначе. Не на серьезных щах же все обсуждать:)

AlexNek патриот03.03.24 21:27
AlexNek
NEW 03.03.24 21:27 
в ответ Fleitist 03.03.24 20:43
Не на серьезных

Можете подойти и по серьёзному, если так нравится.

7495 старожил03.03.24 21:52
7495
NEW 03.03.24 21:52 
в ответ Fleitist 03.03.24 18:44
Мне непонятно, как структурированный код можно называть спагетти? Это что ошибка в терминологии? Мне непонятно стремление к переписыванию всего и вся (весь мир пытается использовать код повторно и экономить деньги). Мне не импонирует агрессивное невежество. Проекты не живут в вакууме, и тимлид, которого тут так уничижительно поминали, должен учитывать всевозможные аспекты проекта. Даже те, которые не видны с низкого горизонта джуниоров и просто не могут быть ими осознаны, в силу отсутствия опыта. Наличие множества слоев (Layered Architecture), как раз признак, того что тимлид прекрасно отдает себе отчет, что такое менеджмент изменений и как можно редуцировать риски и затраты на поддержку. Это как раз называется зрелость, один из критериев качества продукта по ISO 25010, кстати.


Тут много еще чего можно написать, но мне просто лень.:)



Если бы вы знали юзера alex445 получше, то не задавались такими вопросами, его здесь на форуме пинают все кому не лень! зло


Он то университеты "Лиги плюща" - наперсточниками обзовёт, то Маска и криптомиллиардеров со своими фекалиями сравнивает.


Но достаточно посмотреть на какой стыдной машине он ездит и всё ясно и понятно, при этом очерняет Теслу и другие электрокары!


Даже на автора библии сишарпников, на Джон Скита поплеваться успел... что слишком много книжек пишет! За ответ на стековерфлоу.

Вопросы и Ответы - Программируем калькулятор пособий для беженцев вместе.
alex445 коренной житель03.03.24 22:31
NEW 03.03.24 22:31 
в ответ Fleitist 03.03.24 16:22, Последний раз изменено 03.03.24 22:41 (alex445)
Да уж, накипело у вас... Я даже не поверил сначала, что вы всерьез все это пишете.
Понапридумывают этих ваших архитектур, а людям мучаться. Действительно, проще же все переписать:)

Архитектуры работают там, где их используют правильно и со знанием дела, регулярно подновляют, заменяют в них старые технологии новыми. Т.е. когда у приложения есть хозяин, который за ним постоянно следит. Обычно это продукт, поддерживаемый одной командой без радикальной смены хозяев, на протяжении долгого времени. Т.е. это очень малое количество случаев. Во всех остальных случях сложные навороченные архитектуры, написанные по всем канонам разных "чистых кодов" и прочих "библий" программирования, в основном не работают и даже вредят, усложняют и тормозят процесс. В "библиях" об этом забывают упомянуть, рассказать неофитам правду жизни. "Ребята, вы прочитали "что такое хорошо, и что такое плохо" из мира программирования? А теперь забудьте - в большинстве случаев в вашей жизни это применяться и работать не будет." Поэтому переписать - зачастую самое правильное решение. Особенно при смене владельца, команды. Оно, вобщем-то, и используется. А все прежние старания и навороты идут прахом, какими бы гениальным и правильными они ни были.

alex445 коренной житель03.03.24 22:37
NEW 03.03.24 22:37 
в ответ AlexNek 03.03.24 18:39, Последний раз изменено 03.03.24 22:55 (alex445)
То что вам попался вариант неудачной архитектуры не означает, что везде всё так плохо с архитектурой.

Архитектура-то как раз отличная была. Для своего времени. Я же говорю, писали надмозги. В хорошем смысле слова. Хоть и полста проектов в солюшене, но само приложение было далеко не монолит, а как сегодня модно - куча разных сервисов, работающих на разных серверах и общающихся между собой. Были сервисы, создающие динамические типы данных на лету из конфигурационных файлов, послылающие потом их на сервер приложений и создающие там эти типы активаторами. Свой сериализуемый язык запросов и самописная ORM, которые в то время (начало 2000-х) только начали пробивать себе дорогу. Свой гуёвый фреймворк, хоть и основанный на контролах ASP.NET, но сильно их расширяющий. Своё управление состоянием, когда то, что на вебсайте понавводили в формы, можно сохранить в сессию, затем в базу данных, и потом загрузить снова. И на всё это - пачка разных клиентских приложений - от веб-сайтов, до десктопа и PDA. Но времена изменились, и "гениальные" раньше подходы теперь выглядят костылями. Я поначалу тоже думал, глядя на это - кто эту хрень понаписал, зачем, люди себе работу придумывали? Потом посмотрел на технологии, почитал про них в Википедии, на года, когда они были придуманы и применялись. - Да, в своё время это выглядело революционно, на острие прогресса. А сейчас - лютая дичь, которую нужно просто выкинуть в помойку. И не поможет ей никакая архитектура, модульность, расширяемость и интерфейсы по все поля.

alex445 коренной житель03.03.24 22:39
NEW 03.03.24 22:39 
в ответ Fleitist 03.03.24 18:44
Мне непонятно, как структурированный код можно называть спагетти?

Есть спагетти-код, а есть спагетти-архитектура. На каждом уровне можно намутить своё спагетти.

alex445 коренной житель03.03.24 23:09
NEW 03.03.24 23:09 
в ответ AlexNek 03.03.24 20:00, Последний раз изменено 03.03.24 23:09 (alex445)
А насколько устарел труд Эрика Эванса? Или хотя бы "Алгоритмы и структуры данных" Вирта от 1984 года?


В мусор и не вспоминать?

Общие рекомендации вида "делай хорошо и не делай плохо" конечно не устаревают. Устаревают конкретные реализации этих рекомендаций. "Гладко было на бумаге..."

AlexNek патриот03.03.24 23:17
AlexNek
NEW 03.03.24 23:17 
в ответ alex445 03.03.24 22:37
Архитектура-то как раз отличная была. Для своего времени... Потом посмотрел на технологии

Мне кажется, мы говорим о немного разных вещах.

Если приложение написано хорошо, то со временем оно не портится само по себе, его можно только испортить. Ну и используемые технологии могут устареть.

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

Мне часто встречается именно комбинация и первого и второго.

AlexNek патриот03.03.24 23:27
AlexNek
NEW 03.03.24 23:27 
в ответ alex445 03.03.24 23:09
Устаревают конкретные реализации этих рекомендаций.

Ну давайте возьмем, что-то хорошо написанное, но старое.

Вот сколько раз "Никсы" с нуля переписывались заново за последние 20 лет?

alex445 коренной житель03.03.24 23:28
NEW 03.03.24 23:28 
в ответ AlexNek 03.03.24 23:17, Последний раз изменено 03.03.24 23:32 (alex445)

Карета отличная! Оси заменили, ободья на колёсах тоже новые, свежий лак по дереву, диваны внутри перетянули и снова набили новым пухом! Легко прошла полную реконструкцию, благодаря изначальной продуманности и модульности, заложенной в неё мастером ещё сто пятьдесят лет занад. На ней можно было бы ездить и сегодня... Только нахрен не нужно.


Задача - сделать из такой кареты современный автомобиль. Благодаря модульности, можно заменять всё по частям, и всё будет продолжать работать. Но лучше просто сделать автомобиль с нуля, а карету на помойку или в музей.


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

AlexNek патриот03.03.24 23:48
AlexNek
NEW 03.03.24 23:48 
в ответ alex445 03.03.24 23:28, Последний раз изменено 03.03.24 23:49 (AlexNek)
Задача - сделать из такой кареты современный автомобиль

Ну так это устаревшие технологии. Сам то принцип построения остается без изменений.


что в моём случае карета таки должна продолжать работать, а автомобиль из неё будут лепить, заменяя модули. При этом буквально по ходу движения кареты.

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

Ничего не напоминает?


Программист коренной житель04.03.24 08:33
NEW 04.03.24 08:33 
в ответ alex445 01.03.24 13:35
Единственный минус видится (ещё не пробовал) - передать такой тип данных куда-то - надо указывать всю портянку кортежа - типа
MyMethod((int, string, bool) methodParameter);

Открой для себя интерфейсы :)

Кортежи - это хреновила исключительно для локального использования.

Программист коренной житель04.03.24 08:41
NEW 04.03.24 08:41 
в ответ alex445 03.03.24 05:42
Пока есть старпёры, которым удобнее писать развесистую лапшу с дополнительными типами, служащими лишь для хранения передаваемых данных (DTO), и длинные списки параметров методов - они будут это делать.

Пока есть те, кто заинтересован в тестируемом коде, "старперы" будут бить "новичков" по рукм. Больно. Очень больно :)

MrSanders коренной житель04.03.24 09:49
NEW 04.03.24 09:49 
в ответ Программист 04.03.24 08:41

У нас сейчас весёлая борьба нанайских мальчиков. Я предложил погромиздам голосовать за отдельные правила написания кода, они радостно имитировади бурную деятельность, предлагали правила, обсуждали и голосовали. Принятые варианты собрал им в Code Convention, а теперь... Не даю мержить изменения, нарушающие договорённости.

Полярная лиса подкралась к коболистам незаметно. Они думали что будет как обычно. Что написано в проектной документации никого не интересует :)

И теперь два 50+ мальчика обиделись. Страдают над тикетами, к которым я уже две недели как написал всё, что они должны поправить. Но править их код у них... Нет времени. Они уже всё написали, а гадкий я не пускаю в релиз. Это провокация! Из-за меня в релиз не уйдёт супер важная фича!


Ходим по кругу. Сегодня 3й раз "побеседовали":
- когда аппрувишь мой код?

- когда приведёшь в соответствии с требованиями.

- а кто тебе дал право требовать!!!???

- команда. Мы сами установили наши требования и свели их в code conventions

- а у меня нет время на эти глупости!

- ну, найди время

- а я не должен!

- Должен. Код не пройдёт в релиз, пока не будет соответствовать правилам. Если хочешь поменять правила, на следующем ретро можешь обсудить.

- я буду жаловаться! (так и хочется добавить "прокурору!" :))


Две недели назад первый раз так побеседовали. Потом тишина на неделю, и новая итерация. Романтика.

Fleitist прохожий04.03.24 10:19
NEW 04.03.24 10:19 
в ответ MrSanders 04.03.24 09:49, Последний раз изменено 04.03.24 10:21 (Fleitist)

Что-то у вас не то с атмосферой в команде... Не выглядит здоровой:)

Программист коренной житель04.03.24 10:29
NEW 04.03.24 10:29 
в ответ MrSanders 04.03.24 09:49

Жесть конечно. Ну и климат у вас похоже токсичный....

MrSanders коренной житель04.03.24 10:34
NEW 04.03.24 10:34 
в ответ Fleitist 04.03.24 10:19

Она не то что не выглядит... Она у нас как в привокзальном туалете. Руками пощупать можно. У нас просто 4 Олёша-подобных разработчиков. Самые умные. "Чо ты мне своей арзитектурой тычешь". Которые 10-20 лет писали на коболе, потом за 3 дня "научились" писать на яве и теперь уже 5 лет пишут так, как научились за эти три дня.

Но так как у них лужёные глотки и "авторитет" они задавили всех остальных, что те не крякают. Сидят как мышь под веником, не отсвечивают. Но никто не понимает что же эти 4 гения написали. В результате остальные "разрабатывают" с помощью копипасты.


А я пытаюсь это сломать. Заставляю гениев писать документацию, чтобы другие понимали что же делает этот метод с 7 параметрами. В процессе написания гении даже приходили к мнению что оказывается все 7 и не нужны... И (о боже!) заставляю их переименовывать переменные, методы и классы, чтобы имя хоть немного соответствовало тому, что они делают. В общем отношусь без должного пиитета. У олёшенек подгорает и они устравивают подковёрную борьбу :)

Срыв покровов патриот04.03.24 12:04
NEW 04.03.24 12:04 
в ответ MrSanders 04.03.24 09:49

можно пример кода, который ты не пускаешь в прод из-за нарушений конвенции?

Программист коренной житель04.03.24 12:27
NEW 04.03.24 12:27 
в ответ Срыв покровов 04.03.24 12:04

Это может быть совершенно обычный код без криминала.

У нас например в кодинг стандартах написано, что сначала должны быть перечислены все using System.*, потом все остальные. Разумное это требование или нет - вообще не важно.


Есть стандарт кода и ему надо следовать. Если не нравится - нет проблем, стандарты кода можно поменять, но им все равно надо следовать.


В данном случае скоманда сама сформулировала для себя требования к коду, но некоторые члены комманды считают себя ровнее :)

Murr патриот04.03.24 13:12
Murr
NEW 04.03.24 13:12 
в ответ AlexNek 03.03.24 18:39

любой проект за 15-20 лет можно изменить до неузнаваемости в худшую сторону

------

Хи-хи... Покажи мне хоть один. который активно эксплуатируется, модифицируется и остается в том же качестве...

Murr патриот04.03.24 13:26
Murr
NEW 04.03.24 13:26 
в ответ AlexNek 03.03.24 23:17

то таким он и должен быть остаться.

---------------

почему?

мой заводик помнишь? переход с оракла на постгрее... и коннективити под постгрее обрабатывающая ошибки... оракла.

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

Murr патриот04.03.24 13:39
Murr
NEW 04.03.24 13:39 
в ответ MrSanders 04.03.24 09:49

Должен.

-----

Угу...

Как то с бывшим шефом бодались - где рабочий код? - бо, у обоих локально что-то работает - постановили - в соурсэйве! - потом сильно помогало по жизни.

Murr патриот04.03.24 13:41
Murr
NEW 04.03.24 13:41 
в ответ Программист 04.03.24 12:27

должны быть перечислены все using System.*

-----

а как учитывается то, что в .НЕТ не только System.*?

Программист коренной житель04.03.24 14:10
NEW 04.03.24 14:10 
в ответ Murr 04.03.24 13:41
а как учитывается то, что в .НЕТ не только System.*?

Никак. Требование - сначала System.*


Но можно ввести и иерархию:

1) System.*

2) Все 3rd party

3) Свои

alex445 коренной житель04.03.24 14:14
NEW 04.03.24 14:14 
в ответ MrSanders 04.03.24 09:49

У нас сейчас весёлая борьба нанайских мальчиков. Я предложил погромиздам голосовать за отдельные правила написания кода, они радостно имитировади бурную деятельность, предлагали правила, обсуждали и голосовали. Принятые варианты собрал им в Code Convention, а теперь... Не даю мержить изменения, нарушающие договорённости.

Полярная лиса подкралась к коболистам незаметно. Они думали что будет как обычно. Что написано в проектной документации никого не интересует :)

И теперь два 50+ мальчика обиделись. Страдают над тикетами, к которым я уже две недели как написал всё, что они должны поправить. Но править их код у них... Нет времени. Они уже всё написали, а гадкий я не пускаю в релиз. Это провокация! Из-за меня в релиз не уйдёт супер важная фича!


Ходим по кругу. Сегодня 3й раз "побеседовали":
- когда аппрувишь мой код?

- когда приведёшь в соответствии с требованиями.

- а кто тебе дал право требовать!!!???

- команда. Мы сами установили наши требования и свели их в code conventions

- а у меня нет время на эти глупости!

- ну, найди время

- а я не должен!

- Должен. Код не пройдёт в релиз, пока не будет соответствовать правилам. Если хочешь поменять правила, на следующем ретро можешь обсудить.

- я буду жаловаться! (так и хочется добавить "прокурору!" :))


Две недели назад первый раз так побеседовали. Потом тишина на неделю, и новая итерация. Романтика.

Прямо "Санта-Барбара".

alex445 коренной житель04.03.24 14:16
NEW 04.03.24 14:16 
в ответ MrSanders 04.03.24 10:34, Последний раз изменено 04.03.24 14:18 (alex445)
В процессе написания гении даже приходили к мнению что оказывается все 7 и не нужны... И (о боже!) заставляю их переименовывать переменные, методы и классы, чтобы имя хоть немного соответствовало тому, что они делают.

А время на конструирование абстрактных фабрик для абстрактных фабрик остаётся? Если ещё скажете, сколько примерно зарабатывают ваши "ветераны", будет совсем хорошо.


Чёта мне кажется, что даже у меня ситуация получше. ))

alex445 коренной житель04.03.24 14:20
NEW 04.03.24 14:20 
в ответ Программист 04.03.24 12:27, Последний раз изменено 04.03.24 14:28 (alex445)
Это может быть совершенно обычный код без криминала.
У нас например в кодинг стандартах написано, что сначала должны быть перечислены все using System.*, потом все остальные. Разумное это требование или нет - вообще не важно.
Есть стандарт кода и ему надо следовать. Если не нравится - нет проблем, стандарты кода можно поменять, но им все равно надо следовать.

Разве нет штуки, которая сама сортирует юзигни по вашему шаблону после любой команды автоформата (ctrl + K, D, например)?


У меня обычно этими юзингами почти полный экран засориться может. Ещё после рефакторинга могут быть дырки между ними (после удаления строк). Я всю портянку с юзингами просто сворачиваю. После появления в Студии фичи автодобаления юзингов, я туда даже смотреть перестал. Максимум, если какой конфликт имён классов. Но это тоже не требует уделять внимание юзингам - просто соглашаешься на какой-нибудь предложенный Студией рефакторинг, типа добавить полное имя класса.


Вот бы кто подсказал, как в Студии удалить строку без замены её на пустую строку. Я обычно использую окошко "найти-заменить", где в "заменить" оставляю пустое место. Но это оставляет пустые строки в коде.

Murr патриот04.03.24 14:21
Murr
NEW 04.03.24 14:21 
в ответ Программист 04.03.24 14:10

Значит постоянные терки по поводу что тут, что там...

alex445 коренной житель04.03.24 14:26
NEW 04.03.24 14:26 
в ответ Программист 04.03.24 14:10
а как учитывается то, что в .НЕТ не только System.*?

Никак. Требование - сначала System.*


Но можно ввести и иерархию:

1) System.*

2) Все 3rd party

3) Свои

Наф оно нужно вообще? Это ещё тупее, чем "пробелы против табов".

Программист коренной житель04.03.24 14:42
NEW 04.03.24 14:42 
в ответ alex445 04.03.24 14:26
Наф оно нужно вообще?

От куда ж мне знать? :) Но требование такое есть. Будь любезен исполнять.


Это ещё тупее, чем "пробелы против табов".

Пробелы против табов - это как раз не тупо. Тут важно, чтобы у всех были одинаковые настройки. Если у кого-то настройки отличаются, то трындец.

MrSanders коренной житель04.03.24 14:54
NEW 04.03.24 14:54 
в ответ Срыв покровов 04.03.24 12:04
можно пример кода, который ты не пускаешь в прод из-за нарушений конвенции?

Как уже отметили, совершенно обычный код, без особого криминала. Просто нарушающий принятые соглашения. Если я с криминалом нахожу, мне никакие конвеншены не нужны :)
Например, вот такая фигня (кто на яве пишет, поймёт, остальным поясню, имя класса поменял, мало ли, Datenschutz и всё такое):

/**
 * identisch zu
 * @param adresse AdresseMitLand
 */
public Boolean identischZu(AdresseMitLand adresse) {
    return true;
}

Начинаем с вопроса - а нафига мне метод сравнения, которые ничего не сравнивает? Нет ответа. Почему в документации не написано, мол, временная реализация, в настоящий момент, говорит что все всем равны, но надо использовать там-то и там-то потому что в будущем будет заменено.
Где описание параметра, где описание результата? Метод-то публичный.
Почему Boolean? (объект - оболочка вокруг примитивного типа boolean). Он может быть null. Зачем нам такое счастье? Мы (даже в конвенции написали) "используем примитивные типы если нет причин использовать врэпперы, причина описывается в документации".


До сих пор всё такое счастье тупо коммитилось, потом проходило 3 года и все сидели чесали репу а нафига ж такое сотворили, и чего хотели этим сказать.

Murr патриот04.03.24 15:50
Murr
NEW 04.03.24 15:50 
в ответ MrSanders 04.03.24 14:54

нафига мне метод

------

Как зачем?

Дырку в интерфейсе затыкает...


даже в конвенции написали

------

Ну это только из-за объема писанины/поддержки.

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

AlexNek патриот04.03.24 17:50
AlexNek
NEW 04.03.24 17:50 
в ответ Murr 04.03.24 13:12
Покажи мне хоть один

Попадался один такой, хоть 10 лет еще не прошло.

alex445 коренной житель04.03.24 17:52
NEW 04.03.24 17:52 
в ответ Программист 04.03.24 14:42

Наф оно нужно вообще?

От куда ж мне знать? :) Но требование такое есть. Будь любезен исполнять.

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

alex445 коренной житель04.03.24 17:53
NEW 04.03.24 17:53 
в ответ MrSanders 04.03.24 14:54
/**
 * identisch zu
 * @param adresse AdresseMitLand
 */
public Boolean identischZu(AdresseMitLand adresse) {
    return true;
}

За неанглийский код нужно убивать. Долго и мучительно.

Murr патриот04.03.24 17:57
Murr
NEW 04.03.24 17:57 
в ответ AlexNek 04.03.24 17:50

Ну так это один владелец, не битая, не крашеная...

alex445 коренной житель04.03.24 17:57
NEW 04.03.24 17:57 
в ответ MrSanders 04.03.24 14:54, Последний раз изменено 04.03.24 18:02 (alex445)
Где описание параметра, где описание результата? Метод-то публичный.

Зачем разливать воду там, где и по названию метода всё понятно?


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

Murr патриот04.03.24 18:03
Murr
NEW 04.03.24 18:03 
в ответ alex445 04.03.24 17:57

Зачем разливать воду там, где и по названию метода всё понятно?

-----

А шо, ты таки действительно не знаешь? Ну тады шмакай Ф1.

MrSanders коренной житель04.03.24 19:50
NEW 04.03.24 19:50 
в ответ Murr 04.03.24 15:50
Как зачем? Дырку в интерфейсе затыкает..

Не угадал. Если б он метод из интерфейса имплементировал, у него аннотация @Override была бы.

AlexNek патриот04.03.24 19:57
AlexNek
NEW 04.03.24 19:57 
в ответ Murr 04.03.24 13:26
Все всегда делается в меру понимания исполнителем и чаще всего исполнитель не интересуется архитектурой

Угу,.. исправить, исправили, сейчас работает, а что будет потом уже не интересует.

Обращаешь внимание, - а какого переписывать и так всё работает.

Murr патриот04.03.24 20:32
Murr
NEW 04.03.24 20:32 
в ответ MrSanders 04.03.24 19:50

аннотация @Override была бы

-------

В шарпе?

Срыв покровов патриот04.03.24 21:45
NEW 04.03.24 21:45 
в ответ MrSanders 04.03.24 14:54
До сих пор всё такое счастье тупо коммитилось, потом проходило 3 года и все сидели чесали репу а нафига ж такое сотворили, и чего хотели этим сказать.

Спасибо
Только это скорей правила оформления кода, чем coding standards. Тут старперы наверняка вперед всех.

Fleitist прохожий04.03.24 22:28
NEW 04.03.24 22:28 
в ответ alex445 04.03.24 17:52, Последний раз изменено 04.03.24 22:29 (Fleitist)
Проверка на лояльность? Типа, скажи ему регулярно повторять какую-нибудь ненужную фигню, чтобы отнимала время и действовала на нервы. Если согласится, значит покладистый - берём

А кто оценивает нужность / ненужность фигни? :) Безотносительно этого примера.

alex445 коренной житель05.03.24 07:47
NEW 05.03.24 07:47 
в ответ Fleitist 04.03.24 22:28, Последний раз изменено 05.03.24 07:47 (alex445)

С нужностью-ненужностью фигни как с кодом - если через какое-то время никто не может объяснить, зачем эта фигня нужна, значит что-то не так со стандартами этих ваших фигней. Если при этом все продолжают делать эту фигню (потому что "так деды завещали"), то не так уже и с вами. При этом мантра "работает? - не трогай!" не работает.

MrSanders коренной житель05.03.24 13:54
NEW 05.03.24 13:54 
в ответ Murr 04.03.24 20:32
В шарпе?

Чукча не читатель, понимаю. "кто на яве пишет, поймёт"

MrSanders коренной житель05.03.24 14:40
NEW 05.03.24 14:40 
в ответ Срыв покровов 04.03.24 21:45, Последний раз изменено 05.03.24 14:44 (MrSanders)
Только это скорей правила оформления кода, чем coding standards. Тут старперы наверняка вперед всех.

Я под "правилами оформления кода" понимаю правила вроде "строчка не длиннее 140 символов", или "сначала в классе идут публичные, потом приватные" или "после } перенос строки". Но всё равно всё это тоже Coding Convention.

Тут старперы наверняка вперед всех.

Если б. У них у каждого своё мнение. Каждый пишет как ему нравится. Но именно в оформлении без больших расхождений. Потому что разобраться не смогли как настройки форматтера в эклипсе поменять :)

Программист коренной житель05.03.24 14:40
NEW 05.03.24 14:40 
в ответ Murr 04.03.24 20:32
В шарпе?

В шарпе

/// <inheritdoc />
Программист коренной житель05.03.24 14:45
NEW 05.03.24 14:45 
в ответ alex445 04.03.24 17:52
Проверка на лояльность? Типа, скажи ему регулярно повторять какую-нибудь ненужную фигню, чтобы отнимала время и действовала на нервы. Если согласится, значит покладистый - берём

Все эти детали полезны для того, чтобы избежать вкусовщины.

Один вставит юзинг и забудет. Другой будет сортировать изинги по длине. Третий по алфавиту. Четвертый по каким-нибудь другим признакам. И жопа начнется, когда все эти люди начнут (а рано или поздно они начнут) форматировать уже написанное под себя.

AlexNek патриот05.03.24 19:16
AlexNek
NEW 05.03.24 19:16 
в ответ MrSanders 05.03.24 14:40
разобраться не смогли как настройки форматтера в эклипсе поменять

А тут меньше чем надо? Один раз настроил и пользуй везде. Для шарпа сделано довольно хорошо, предполагаю, что для явы не хуже.

https://www.jetbrains.com/help/idea/configuring-code-style...

alex445 коренной житель05.03.24 19:19
NEW 05.03.24 19:19 
в ответ MrSanders 05.03.24 14:40, Последний раз изменено 05.03.24 19:19 (alex445)
Я под "правилами оформления кода" понимаю правила вроде "строчка не длиннее 140 символов", или "сначала в классе идут публичные, потом приватные" или "после } перенос строки". Но всё равно всё это тоже Coding Convention.

Тогда это хрень полная. Вы бетонируете какие-то фарисейские принципы, зачастую мешающие нормальной работе. В некоторых случаях удобно писать, группируя по смыслу - поля и свойства, например. Т.е. приватную и публичную часть рядом друг с другом. А иногда и методы туда же - в инициализацию объекта пихаю реализацию делегата, созданную тут же через лямбду. Типа такого (отвлечённый пример на Сишарпе)


Person somePerson;
public Person SomePerson => somePerson ??= new()
{
    Age = 20,
    Name = _ => Age > 5 ? Person.DefaultName : "Baby",
    Condition = (Guid id, string defaultCondition) =>
    {
        var realAge = GetRealAge(id);
        return realAge > 100 ? "died" : defaultCondition;
    },
};


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


А не так давно мы ещё выяснили, что такая запись многим неприемлема - нужно расписать всё с явными геттерами, явной проверкой на налл (без оператора ??=) и без лямбд. Т.е. накатать кода где-то на полэкрана, разнесённого в три разных места класса.

alex445 коренной житель05.03.24 19:28
NEW 05.03.24 19:28 
в ответ alex445 05.03.24 19:19, Последний раз изменено 05.03.24 19:34 (alex445)

Мне это ещё в плюсах не нравилось - чтобы понять, как работает класс, где у него что находится, нужно открыть минимум ДВА файла. Может, в 80-90-е это и было круто, но сейчас и уже давно это смотрится как костыльный анахронизм, мешающий работать.

AlexNek патриот05.03.24 20:47
AlexNek
NEW 05.03.24 20:47 
в ответ alex445 05.03.24 19:19
Тогда это хрень полная. В некоторых случаях удобно писать...

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

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


Ну а про приведенный код я лучше промолчу смущ

alex445 коренной житель05.03.24 21:10
NEW 05.03.24 21:10 
в ответ AlexNek 05.03.24 20:47, Последний раз изменено 05.03.24 21:13 (alex445)

Код отвлечённый, как я сказал. Просто нужен был любой пример с методом без параметров и с парой параметров, однострочный и в несколько строчек. Главное, что методы не определяются где-то в другом месте класса, а пишутся тут же лямбдами. А ленивая инициализация - это вообще уже давно привычная тема. Чем код не нравится?


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

Мой код можно понять очень быстро, т.к. всё компактно и в одном месте. А вот если распихать его кусками по всему классу, то придётся прыгать по нему, теряя контекст.


Если метод большой - 5+ строчек, то я выношу его отдельно. А так у меня в проекте часто встречается, что нужно инициализировать объект в том числе кучкой коротких методов (делегаты). Выписывать их где-то вдалеке, а не по месту - просто плодить лапшу в коде.

alex445 коренной житель05.03.24 21:27
NEW 05.03.24 21:27 
в ответ alex445 05.03.24 21:10, Последний раз изменено 05.03.24 21:27 (alex445)

Если не нравится конкретный код, вот можно более абстрактный


Person somePerson;
public Person SomePerson => somePerson ??= new()
{
    Property1 = 20,
    Property2 = _ => ...,
    Property3 = (param1, param2) =>
    {
        ...
        ...
        ...
    },
};
AlexNek патриот05.03.24 21:51
AlexNek
NEW 05.03.24 21:51 
в ответ alex445 05.03.24 21:10, Последний раз изменено 05.03.24 21:53 (AlexNek)
Мой код можно понять очень быстро

Пропущено "МНЕ". Обычно код читается за один проход без задержек. Здесь же нужно задумываться на любой строке.

alex445 коренной житель05.03.24 22:57
NEW 05.03.24 22:57 
в ответ AlexNek 05.03.24 21:51, Последний раз изменено 05.03.24 22:59 (alex445)
Обычно код читается за один проход без задержек.

Что-то тривиальное.

Фабрика фабрик у вас тоже за один проход, без задержек?


Здесь же нужно задумываться на любой строке.

У вас вызывают затруднения одна однострочная функция и одна двухстрочная? Или в присвоении константы вы видите скрытые смыслы? Может, оператор ??= слишком нов и загадочен для вас? Ленивая инициализация - откровение? ))

AlexNek патриот05.03.24 23:12
AlexNek
NEW 05.03.24 23:12 
в ответ alex445 05.03.24 22:57

Общую концепцию я бы не стал трогать, как и правильную последовательность вызовов.


Но подобную конструкцию вижу в первый раз "Property2 = _ =>"

И каким образом

public Func<object, string> Property2 { get; set; }

превращается в

public string Property2 { get; set; }

пока не додумался смущ Как и откуда берутся параметры для Property3?


AlexNek патриот05.03.24 23:20
AlexNek
NEW 05.03.24 23:20 
в ответ alex445 05.03.24 22:57
Фабрика фабрик у вас тоже за один проход

Подобные конструкции создают извращенцы, которые пока по счастью не попадались.


alex445 коренной житель06.03.24 01:18
NEW 06.03.24 01:18 
в ответ AlexNek 05.03.24 23:12, Последний раз изменено 06.03.24 01:34 (alex445)
Общую концепцию я бы не стал трогать, как и правильную последовательность вызовов.
Но подобную конструкцию вижу в первый раз "Property2 = _ =>"
И каким образом
public Func Property2 { get; set; }

превращается в
public string Property2 { get; set; }

пока не додумался смущ Как и откуда берутся параметры для Property3?

Всё там нормально - никаких

public string Property2 { get; set; }

там нет. Name и Condition это делегаты, возвращающие строки. Просто название неудачное, что непонятно, что это не просто свойства.


Параметры берутся при вызове этих делегатов:

string name = SomePerson.Name(anyAge);
string condition = SomePerson.Condition(id, "alive");


Я вам ещё раз говорю - не привязывайтесь сильно к коду. Я лишь хотел показать, как будет выглядеть то или иное использование. Первый случай - нужен делегат с параметров, а у меня есть вариант метода или лямбды без параметра. Ну я и использую дискард. Второй случай - не совсем верно я по памяти написал. Но тут просто хотел показать вариант, когда метод не однострочный и с более, чем одним параметром - т.е. вроде бы громоздко должно выглядеть, но на самом деле не очень.


По идее, если всё свойство или метод укладываются в один экран, то вы не теряете контекст работы этого свойства - вы видите всё от и до. А вот когда у вас ссылки на методы, разбросанные по классу, то вам надо прыгать на эти ссылки, чтобы глянуть, что там происходит - вы теряете контекст.


Фабрика фабрик у вас тоже за один проход
Подобные конструкции создают извращенцы, которые пока по счастью не попадались.

Да ладно? А по мне, так подавляющая часть всяких инверсий зависимостей - это как раз извращения. Чтобы понять, как работает та или иная хрень, написанная с помощью инверсий, нужно либо попрыгать по классам, либо иметь возможность открыть штук 5-10 окон с кодом в параллельном режиме (не знаю ни одной IDE с такой возможностью), чтобы видеть весь код сразу. Особенно этим страдают всякие инжекции и шаблонные методы. Оно может хорошо работает, но понять эту хрень зачастую очень сложно, особенно когда создатель почти не оставил комментариев. И особенно если эти инженкции не в чистом виде, как в рафинированных примерах, а разбавлены прочим кодом и паттернами.

alex445 коренной житель06.03.24 01:38
NEW 06.03.24 01:38 
в ответ alex445 06.03.24 01:18, Последний раз изменено 06.03.24 01:46 (alex445)

В примере моего реального приложения там были объекты-модели для гуёвых контролов, и у каждой такой модели была пачка делегатов для установки свойств гуёвого контрола в зависимости от условий. И вот методы для этих делегатов были в основном 1-4 строчными. И мне было проще и понятнее писать эти методы прямо в создании этих моделей для контролов, чем раскидывать их по модели всей гуёвой формы. Т.е. не так


FormModel
{
    Control1
    Control2
    ...
    
    Methods for Control1
    Methods for Control2
    ...
}


а вот так


FormModel
{
    Control1
    {
        Methods for Control1    
    }
    
    Control2
    {
        Methods for Control2
    }
    ...
}


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

Программист коренной житель06.03.24 08:12
NEW 06.03.24 08:12 
в ответ alex445 05.03.24 19:19
Типа такого (отвлечённый пример на Сишарпе)

Убить хочется :D

alex445 коренной житель06.03.24 11:27
NEW 06.03.24 11:27 
в ответ Программист 06.03.24 08:12

Приведите свой пример - сравним.

Программист коренной житель06.03.24 12:15
NEW 06.03.24 12:15 
в ответ alex445 06.03.24 11:27, Последний раз изменено 06.03.24 12:16 (Программист)

Свой пример чего? :)

Твой пример - неместируемое говно.


А если учесть, что

Name и Condition это делегаты

так это еще и хрен поймешь в каком месте программы и за что отвечает сей объект.


Person somePerson;
public Person SomePerson => somePerson ??= new()
{
    Age = 4,
    Name = _ => Age == 4 ? "car" : "some other vehicle",
    Condition = (Guid id, string defaultCondition) =>
    {
        return id.GetHashcode() % 2 == 0 ? "Tank Full" : "Damaged engine";
    },
}

а потом так:


Person somePerson;
public Person SomePerson => somePerson ??= new()
{
    Age = 2,
    Name = _ => Age > 0 ? "Lion" : "Bird",
    Condition = (Guid id, string defaultCondition) =>
    {
        var realAge = GetWhatEverById(id);
        return realAge > 100 ? "Healthy" : "Pink";
    },
};


Флаг в руги к крест на могилу при отладке этого говна.

alex445 коренной житель06.03.24 14:58
NEW 06.03.24 14:58 
в ответ Программист 06.03.24 12:15, Последний раз изменено 06.03.24 15:03 (alex445)

Я спросил ваш вариант, если у объекта есть делегаты, которые нужно инициализировать. Вы же не против делегатов в принципе? У меня делегаты инициализируются лямбдами прямо в инициализаторе объекта, при этом инициализация ленивая. Ещё можно написать отдельные методы и назначить их делегатам. Можно в инициализаторе объекта, а можно после вызова конструктора. Тут не вопрос, будут ли делегаты в принципе - они есть, и вы с этим поделать ничего не можете.


В чём проблема отладки? У вас отладчик в этих строчках кода не остановится?


Чтобы вы не придирались к возможному наобум придуманному конкретному коду, я написал более абстрактно, где обозначил, что важно лишь то, где определены функции, которыми инициализируются объекты. Но вы все проигнорировали это, а стали прицепляться к невылизанности кода. Вместо этого конкретного кода может быть любой другой. Поэтому я и сказал - вставьте свой по вкусу, ваш вариант. Главное, что тут у объекта свойство-делегат, и нужно ему назначить какой-то метод.

Программист коренной житель06.03.24 15:35
NEW 06.03.24 15:35 
в ответ alex445 06.03.24 14:58
Вы же не против делегатов в принципе?

Я против делегатов. Делегаты дают настолько большую свободу использования и интерпритации, что ну его нахрен. Вообще, я не припомню ни одного случая, когда было бы разумно использовать делегаты... ну кроме пожалуй call back функций, которые не используются уже лет 500.


и вы с этим поделать ничего не можете.

Убить того, кто везде с поводом и без ляпая делегаты :)


В чём проблема отладки? У вас отладчик в этих строчках кода не остановится?

Отладчик в этих строчках остановится. А вот в каких местах эти делегаты будут вызваны? Какие там зависимости? Как и самое главное что при таком подходе отлаживать?

Собственно говоря, с таким подходом вообще не нужены ни классы, ни структура, ни архитектура. Просто желаешь God-объект и добавляешь в него делегаты с разными параметрами. Дальше твоя задача просто вызывать эти делегаты в нужной последовательности. Ну и проинициализировать твой God-объект :)

alex445 коренной житель06.03.24 16:15
NEW 06.03.24 16:15 
в ответ Программист 06.03.24 15:35, Последний раз изменено 06.03.24 16:20 (alex445)
Я против делегатов. Делегаты дают настолько большую свободу использования и интерпритации, что ну его нахрен. Вообще, я не припомню ни одного случая, когда было бы разумно использовать делегаты... ну кроме пожалуй call back функций, которые не используются уже лет 500.

Гуй. В том числе гуёвые модели в паттернах типа MVVM, MVP, MVC и т.п.


И в принципе все случаи, когда надо реагировать на какое-то событие - пришли данные в канал, добавились данные в БД, какой-то чувак нажал на кнопку. Альтернатива какая событиям? В бесконечном цикле отслеживать флаги наступления этих событий?

alex445 коренной житель06.03.24 16:17
NEW 06.03.24 16:17 
в ответ Программист 06.03.24 15:35, Последний раз изменено 06.03.24 16:23 (alex445)
и вы с этим поделать ничего не можете.
Убить того, кто везде с поводом и без ляпая делегаты :)

А я люблю делегаты! Я их на хлеб каждое утро мажу, и даже засыпаю с парой больших плюшевых делегатов в обнимку.


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

Программист коренной житель06.03.24 16:32
NEW 06.03.24 16:32 
в ответ alex445 06.03.24 16:15
Гуй. В том числе гуёвые модели в паттернах типа MVVM, MVP, MVC и т.п.

Там используются event'ы. Эвенты используют делегаты, но разница между ними огромна.


Альтернатива какая событиям?

Эвенты используют делегаты, но разница между ними огромна.

Если в 2-х словах:

An Event declaration adds a layer of abstraction and protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list and only allows adding or removing targets from the invocation list.
Программист коренной житель06.03.24 16:35
NEW 06.03.24 16:35 
в ответ alex445 06.03.24 16:17

Просто для сеньоров-помидоров SOLID не пустой звук.

AlexNek патриот06.03.24 17:46
AlexNek
NEW 06.03.24 17:46 
в ответ alex445 06.03.24 14:58
Тут не вопрос, будут ли делегаты в принципе - они есть, и вы с этим поделать ничего не можете.

Вот в этом и есть главная проблема.


Когда в Си пользовали косвенные вызовы процедур/функций, то это как то еще можно было понять (и простить улыб)

Но в шарпе? и повсеместно... шок


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

AlexNek патриот06.03.24 18:02
AlexNek
NEW 06.03.24 18:02 
в ответ alex445 06.03.24 01:18
А по мне, так подавляющая часть всяких инверсий зависимостей - это как раз извращения.

Когда и я так думал, когда привык ставить точку останова в конструкторе и смотреть откуда приходят все параметры.

Но времена меняются и слабое связывание оказывается гораздо полезнее.


Наверняка и MediatR и FluentValidation и пр. считаете извращениями вместе с чистым кодом и чистой архитектурой. Народ просто хочет подзаработать и махает этим перед носом тупых осликов.

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


Параметры берутся при вызове этих делегатов:

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

AlexNek патриот06.03.24 18:19
AlexNek
NEW 06.03.24 18:19 
в ответ alex445 06.03.24 01:38
там были объекты-модели для гуёвых контролов, и у каждой такой модели была пачка делегатов для установки свойств гуёвого контрола в зависимости от условий.

Ладно, не будем придираться что МОДЕЛЬ имеет КОНТРОЛЫ. Но получается, что каждый контрол работает по разному в зависимости от того где он используется. Что по идее приводит к тому, что и контролы и модели становятся сильно связанными.

alex445 коренной житель06.03.24 20:15
NEW 06.03.24 20:15 
в ответ Программист 06.03.24 16:32

Эвенты используют делегаты, но разница между ними огромна.

Если в 2-х словах:

An Event declaration adds a layer of abstraction and protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list and only allows adding or removing targets from the invocation list.

Надо такой вопрос на собесах задавать, когда хочешь кого-то завалить. Особенно пояснить за "огромна", хотя всё объясняется в "двух словах".

alex445 коренной житель06.03.24 20:18
NEW 06.03.24 20:18 
в ответ Программист 06.03.24 16:35, Последний раз изменено 06.03.24 20:43 (alex445)
Просто для сеньоров-помидоров SOLID не пустой звук.

Там больше половины - маркетинг для сектантов, чтобы по сцене ходить и втирать, и лишь небольшая оставшаяся часть катит. ))


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

alex445 коренной житель06.03.24 20:24
NEW 06.03.24 20:24 
в ответ AlexNek 06.03.24 17:46
Уверен, что если Вы чуть больше подумаете в этом направлении (убрать нахрен эти делегаты), то наверняка найдете более разумное решение.

Делегаты лучше ваших сраных инжекций, т.к. не требуют создания дополнительного объекта для вызова функций. Можно цеплять функции напрямую. Вообще, есть поверье, что инжекции изобрели (или развили до маразма) всякие джависты, у которых на заре Джавы не было нормальных инструментов в языке, типа делегатов. А может и сейчас нет - кто этих отщепенцев знает. ))

Fleitist прохожий06.03.24 20:44
NEW 06.03.24 20:44 
в ответ alex445 05.03.24 19:19
В некоторых случаях удобно писать, группируя по смыслу - поля и свойства, например. Т.е. приватную и публичную часть рядом друг с другом.

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

alex445 коренной житель06.03.24 20:47
NEW 06.03.24 20:47 
в ответ Fleitist 06.03.24 20:44, Последний раз изменено 06.03.24 20:49 (alex445)

И для чего же? Для внешнего потребителя класса пофиг, как там внутри всё расставлено - он видит лишь публичную часть. А для разработчика этого класса всё должно быть расставлено так, как ему удобно, а не как кто-то со сцены наплёл.


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

Fleitist прохожий06.03.24 20:48
NEW 06.03.24 20:48 
в ответ alex445 06.03.24 20:24
Вообще, есть поверье, что инжекции изобрели (или развили до маразма) всякие джависты, у которых на заре Джавы не было нормальных инструментов в языке, типа делегатов.

Бррр, как все запущено:)

alex445 коренной житель06.03.24 21:02
NEW 06.03.24 21:02 
в ответ Fleitist 06.03.24 20:48, Последний раз изменено 06.03.24 21:07 (alex445)

12 год - да наф нам не нужон этот ваш делегат.

14 год - Джава 8 представляет лямбды и ссылки на методы.


Можно ещё тут почитать срачи.

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

AlexNek патриот06.03.24 21:29
AlexNek
NEW 06.03.24 21:29 
в ответ alex445 06.03.24 20:24
Делегаты лучше ваших сраных инжекций, ...

откуда такая агрессия?

Если считаете, что ваше решение самое лучшее, ну так пожалуйста, нам не жалко.

Жалко будет тех кто придёт потом, но это также не наша проблема.

Я думал, что всегда хорошо глянуть на проблему с разных сторон.

AlexNek патриот06.03.24 21:37
AlexNek
NEW 06.03.24 21:37 
в ответ alex445 06.03.24 20:47
для разработчика этого класса всё должно быть расставлено так, как ЕМУ удобно,

Вот пожалуй в этом и есть вся суть данной дискуссии.


А удобно то должно быть команде, как текущей так и следующей. И это самый минимум, что хочется иметь от хорошего кода.


AlexNek патриот06.03.24 21:40
AlexNek
NEW 06.03.24 21:40 
в ответ alex445 06.03.24 21:02
Короче, городили паттерны богу паттерны из-за отсутствия нормальных инструментов

Понятно. Банда четырёх с автоматами еще не попадалась на пути спок

alex445 коренной житель06.03.24 21:51
NEW 06.03.24 21:51 
в ответ AlexNek 06.03.24 21:29, Последний раз изменено 06.03.24 21:54 (alex445)
откуда такая агрессия?

Это не агрессия, это "добавить перчику в бульон - для вкуса". Это я только в интернете такой, а в жизни ваще нифига не агрессивный. ))


Если считаете, что ваше решение самое лучшее, ну так пожалуйста, нам не жалко.

Мне этого мало. Я хочу влезть в чужой монастырь, разнести там всё, и заставить всех плясать под свою дудку. Шутка.

AlexNek патриот06.03.24 22:00
AlexNek
NEW 06.03.24 22:00 
в ответ alex445 06.03.24 21:51
Это я только в интернете такой

Реального персонажа дано знать не всем, поэтому впечатления остаются интернетные.

Ну типа: Ложки-то нашлись, а осадок остался

alex445 коренной житель06.03.24 22:05
NEW 06.03.24 22:05 
в ответ AlexNek 06.03.24 21:40
Короче, городили паттерны богу паттерны из-за отсутствия нормальных инструментов

Понятно. Банда четырёх с автоматами еще не попадалась на пути

Почему не попадалась? Где-то в таком месте встречал.

alex445 коренной житель06.03.24 22:06
NEW 06.03.24 22:06 
в ответ AlexNek 06.03.24 22:00, Последний раз изменено 06.03.24 22:08 (alex445)
Это я только в интернете такой
Реального персонажа дано знать не всем, поэтому впечатления остаются интернетные.
Ну типа: Ложки-то нашлись, а осадок остался

Так вы не узнаете, что это я к вам пришёл. Мало ли всяких Алексов вокруг шляется. Ну или можете сделать вид, что не узнали.

AlexNek патриот06.03.24 22:15
AlexNek
NEW 06.03.24 22:15 
в ответ alex445 06.03.24 22:05
Где-то в таком месте встречал.

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

Fleitist прохожий06.03.24 22:58
NEW 06.03.24 22:58 
в ответ alex445 06.03.24 22:06
Так вы не узнаете, что это я к вам пришёл.

Узнаем, узнаем. Тут один приходил на интервью, говорил, что лучший разработчик в мире, так как его на гитхабе котируют дюже. Токсичный, наглый, короче всех старперами обзывал и революцию в матрице обещал. Не взяли, увы. Не вы были?:)

alex445 коренной житель06.03.24 23:51
NEW 06.03.24 23:51 
в ответ Fleitist 06.03.24 22:58

Не, то был не я. Я у вас за спиной стою. НЕ ОБОРАЧИВАЙТЕСЬ!

Срыв покровов патриот07.03.24 06:41
NEW 07.03.24 06:41 
в ответ alex445 06.03.24 23:51

да, Алекс, тяжело тебе со староверами общаться, сочувствую.


Я на русском программирование не учил, делегаты это все что Func<…> и Action<…>?

Программист коренной житель07.03.24 08:04
NEW 07.03.24 08:04 
в ответ alex445 06.03.24 20:15
Надо такой вопрос на собесах задавать, когда хочешь кого-то завалить.

Если кандидат не знает почему для нотификации следует использовать эвенты, а не делегаты, то гнать в шею надо такого кандидата :)

А если программист повсеместно использует делегаты, то надо гнать в шею такого программиста. Все просто.

Программист коренной житель07.03.24 08:07
NEW 07.03.24 08:07 
в ответ alex445 06.03.24 20:24, Последний раз изменено 07.03.24 08:08 (Программист)
Делегаты лучше ваших сраных инжекций, т.к. не требуют создания дополнительного объекта для вызова функций. Можно цеплять функции напрямую.

Еще раз. Зачем у тебя вообще есть разные классы?

Сделай себе контейнер с делегатами и замени 99% кода на этот контейнер.


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

Инжекты нужны для того, чтобы была возможность подменять объекты. Это активно используется как продуктивном коде, так и в тестировании.

alex445 коренной житель07.03.24 08:13
NEW 07.03.24 08:13 
в ответ Срыв покровов 07.03.24 06:41, Последний раз изменено 07.03.24 08:25 (alex445)
Я на русском программирование не учил, делегаты это все что Func<…> и Action<…>?

Оно и на английском делегаты - delegates. ))


Делегаты это делегаты. Func и Action это готовые определённые типы делегатов, которые широко используются внутри Дотнет фреймворка. Ну и их можно использовать, чтобы не писать велосипеды - в конце-концов, для всех методов с одним входных параметром и без возврата достаточно типа Action<T>. Но судя по коду, что я встречаю, почти все пишут свои определения для банальных делегатов. Вобщем, народ букварей не читает, чего во фреймворке есть не отдупляет, но на собесах по бумажкам какую-то заумь спрашивает. ))

alex445 коренной житель07.03.24 08:23
NEW 07.03.24 08:23 
в ответ Программист 07.03.24 08:04
Надо такой вопрос на собесах задавать, когда хочешь кого-то завалить.

Если кандидат не знает почему для нотификации следует использовать эвенты, а не делегаты, то гнать в шею надо такого кандидата :)

А если программист повсеместно использует делегаты, то надо гнать в шею такого программиста. Все просто.

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

MrSanders коренной житель07.03.24 09:19
NEW 07.03.24 09:19 
в ответ alex445 06.03.24 21:02
12 год - да наф нам не нужон этот ваш делегат.

На всякий случай, Ололёшеньке всё равно, он у нас дурачок, по-англицки читать это не его, но вдруг кого удивило.

Во-первых, статья 1997-8 года. Не позднее. Java 1.2 не упоминается. Ну, ашипся ололёшенька. Бывает. (Статья про J++. Кто такое мелкомягкое уродство помнит?)

Во-вторых, суть статьи "нафиг усложнять VM ссылками на методы, если есть внутренние классы".

Ну и, в-третьих, ...

14 год - Джава 8 представляет лямбды и ссылки на методы.

"Ссылка на метод" в 8-й Яве это не "delegate". Это синтаксический сахар. Который компилятором преобразуется... во внутренний класс. Как и лямбда.

alex445 коренной житель07.03.24 10:26
NEW 07.03.24 10:26 
в ответ MrSanders 07.03.24 09:19, Последний раз изменено 07.03.24 10:41 (alex445)
Во-первых, статья 1997-8 года. Не позднее. Java 1.2 не упоминается

Согласен, спутал - в 2012 году это было заархивировано, а не выпущено. Но сути это не меняет - до последнего "нам не нужны делегаты", а потом резко "но если очень надо, то вот вам имитирующие костыли".


Так никто и не говорит, что в Джаве есть нормальные делегаты и лямбды. Так, лишь жалкая пародия. Непонятно, зачем их ввели в такую лучшую и совершенную Джаву - наверное, зумеры заколебали - "а вот в Сишарпе и других современных языках...", вот им и бросили кость. А так бы старпёры до сих пор сидели на старых версиях и довольно рыгали бы на форумах - "а нам даже за поддержку старого говна платят больше, чем вам, гы-гы!". Просто Оракл понял, что если сейчас не оторвать свою жопу от насиженного дивана, то Джава окончательно сдохнет вместе со своими старпёрами. Старпёрам может до пенсии бы их зарплат хватило, а вот Ораклу - нет, если он намерен этих старпёров пережить без сокращения бизнеса. По сути, единственная существенная тростинка, на которой она до сих пор держится - Гугл со своим Андроидом. Без него и новых версий Джавы со всем этим сахаром вакухи по Джаве усохли бы в разы.


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

MrSanders коренной житель07.03.24 11:18
NEW 07.03.24 11:18 
в ответ alex445 07.03.24 10:26
Но сути это не меняет - до последнего "нам не нужны делегаты", а потом резко "но если очень надо, то вот вам имитирующие костыли".

Утомил тупостью, чесслово. Ещё раз: в статье было про то, что расширять/усложнять VM поддержкой ссылок на методы НЕ НАДО, потому что то же самое можно делать внутренними классами.

"потом резко, очень надо" - это твоя дурь. Синтаксический сахар добавляется постоянно. То ссылки на методы, то записи.

Всё остальное комментировать не имеет смысла. Ололёшенька в своём репертуаре, брехня.

Срыв покровов патриот07.03.24 14:11
NEW 07.03.24 14:11 
в ответ alex445 07.03.24 08:13
Делегаты это делегаты. Func и Action это готовые определённые типы делегатов, которые широко используются внутри Дотнет фреймворк

ну как я и говорю
delegate void MyMethod(string message) это эквивалент Action<string> MyMethod
или
delegate int MyFunc(string message) это Func<string,int> MyFunc


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

alex445 коренной житель07.03.24 14:23
NEW 07.03.24 14:23 
в ответ MrSanders 07.03.24 11:18

в статье было про то, что расширять/усложнять VM поддержкой ссылок на методы НЕ НАДО, потому что то же самое можно делать внутренними классами.

"потом резко, очень надо" - это твоя дурь. Синтаксический сахар добавляется постоянно. То ссылки на методы, то записи.

Так не надо, что они эти ссылки на методы и лямбды добавляли аж с версии 1.х - сколько там, больше 15 лет прошло? А чего раньше не добавили, раз это всё уже считай было и можно было легко сделать "внутренними классами"? Уверен, не дай им Сишарп и другие современные языки пинка под зад, они бы до сих пор шамкали "не надо, нам и так хорошо!".

alex445 коренной житель07.03.24 14:32
NEW 07.03.24 14:32 
в ответ Программист 06.03.24 16:32, Последний раз изменено 07.03.24 14:50 (alex445)
Гуй. В том числе гуёвые модели в паттернах типа MVVM, MVP, MVC и т.п.
Там используются event'ы. Эвенты используют делегаты, но разница между ними огромна.


Альтернатива какая событиям?
Эвенты используют делегаты, но разница между ними огромна.

Если в 2-х словах:


An Event declaration adds a layer of abstraction and protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list and only allows adding or removing targets from the invocation list.

Т.е. события основаны на делегатах. Т.е. без делегатов никуда. Ну и чего бухтеть "убил бы, убил бы"?


Что есть в той же Джаве по событиям, на чём они там основаны?

Срыв покровов патриот07.03.24 14:49
NEW 07.03.24 14:49 
в ответ Срыв покровов 07.03.24 14:11

или вот хочу я функцию, чтобы получать коллекцию объектов из БД по заданному фильтру


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



как это на староверском изобразить?

alex445 коренной житель07.03.24 14:52
NEW 07.03.24 14:52 
в ответ Срыв покровов 07.03.24 14:49, Последний раз изменено 07.03.24 14:53 (alex445)

Обычные методы с параметрами на каждый подобный чих. Ну и возможность самому ещё расширить это дело. До этих делегатов и лямбд такие методы вроде даже автоматически по шаблонам генерились - к каждому дата сету генерилась пачка методов на несколько тысяч строк в среднем.

Срыв покровов патриот07.03.24 15:14
NEW 07.03.24 15:14 
в ответ alex445 07.03.24 14:52

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

Murr патриот07.03.24 16:06
Murr
NEW 07.03.24 16:06 
в ответ Программист 06.03.24 15:35

Я против делегатов.

----------------

я - ЗА!

Но я против того, чтобы делегатам назначались методы самого класса - это способ подключения внешнего решения и пусть таким и остается.

Murr патриот07.03.24 16:15
Murr
NEW 07.03.24 16:15 
в ответ alex445 06.03.24 16:15

Альтернатива какая событиям?

-----

Альтернатива называется WinProc.

У меня сейчас сильно перегружен лапоть.

А при написании экранной клавы как раз пользовались делегатами.

Результат - нажимаю Шифт, нажимаю букву...буква выводится не в том регистре.

а чтобы было совсем смешно - лечить надо заменой... БП и акку... хаха

Murr патриот07.03.24 16:20
Murr
NEW 07.03.24 16:20 
в ответ AlexNek 06.03.24 17:46

то наверняка найдете более разумное решение.

------

пока функции внтренние - 100%...

alex445 коренной житель07.03.24 17:17
NEW 07.03.24 17:17 
в ответ Murr 07.03.24 16:06, Последний раз изменено 07.03.24 17:19 (alex445)
Но я против того, чтобы делегатам назначались методы самого класса - это способ подключения внешнего решения и пусть таким и остается.

А где вы видели, чтобы делегатам-членам класса назначались методы-члены этого же класса? Какой в этом смысл? Почему бы сами методы не использовать?


Когда я в своём примере использую лямбды в инициализаторе объекта, то это извне класса, объект которого создаю.

AlexNek патриот07.03.24 17:21
AlexNek
NEW 07.03.24 17:21 
в ответ alex445 07.03.24 08:13
Вобщем, народ букварей не читает,

А не кажется что может быть и другое объяснение?

Что лучше понять:Action или RedButtonPressed?

alex445 коренной житель07.03.24 17:24
NEW 07.03.24 17:24 
в ответ AlexNek 07.03.24 17:21, Последний раз изменено 07.03.24 17:24 (alex445)

RedButtonPressed должно стоять в названии экземпляра делегата, а не его типа. Т.е.


Action redButtonPressed


а не


RedButtonPressed redButtonPressed

AlexNek патриот07.03.24 17:29
AlexNek
NEW 07.03.24 17:29 
в ответ Срыв покровов 07.03.24 14:11
есть энтити класс Person, хочу функцию, которой я мог бы апдейтить любое свойство объекта Person в базе данных

пофигу в какую группу попадаю, но такую хотелку просто-бы отмели в зародыше.


AlexNek патриот07.03.24 17:35
AlexNek
NEW 07.03.24 17:35 
в ответ alex445 07.03.24 14:32
Т.е. без делегатов никуда. Ну и чего бухтеть "убил бы, убил бы"?

Да вот по телику показывали даже.

Два мужика выгрузили унитаз из авто и понесли, ... без унитаза то никуда, всем нужен.

Но они понесли его сбрасывать с моста на автобан.

alex445 коренной житель07.03.24 17:47
NEW 07.03.24 17:47 
в ответ AlexNek 07.03.24 17:29
есть энтити класс Person, хочу функцию, которой я мог бы апдейтить любое свойство объекта Person в базе данных

пофигу в какую группу попадаю, но такую хотелку просто-бы отмели в зародыше.

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

AlexNek патриот07.03.24 17:52
AlexNek
NEW 07.03.24 17:52 
в ответ alex445 07.03.24 17:17
использую лямбды в инициализаторе объекта

А давайте глянем на это немного "сверху".

У нас есть объект который нифига не умеет, а всё поведение мы задаем ему сами.

Обычно делают так:

https://medium.com/@kevinkuan_26362/back-to-basic-designin...

Но нам это нафиг не нужно, сделаем все сами, чтобы можно было закинуть всё что угодно, в любой комбинации и без тестов

alex445 коренной житель07.03.24 17:53
NEW 07.03.24 17:53 
в ответ alex445 07.03.24 17:47, Последний раз изменено 07.03.24 17:54 (alex445)

Да вот по телику показывали даже.

Два мужика выгрузили унитаз из авто и понесли, ... без унитаза то никуда, всем нужен.

Но они понесли его сбрасывать с моста на автобан.


AlexNek патриот07.03.24 17:54
AlexNek
NEW 07.03.24 17:54 
в ответ alex445 07.03.24 17:24

То бишь первое всё же лучше?

Action redButtonPressed

а не

ButtonPressed redButtonPressed

alex445 коренной житель07.03.24 17:55
NEW 07.03.24 17:55 
в ответ AlexNek 07.03.24 17:54, Последний раз изменено 07.03.24 17:56 (alex445)

Да, лучше.

AlexNek патриот07.03.24 17:58
AlexNek
NEW 07.03.24 17:58 
в ответ alex445 07.03.24 17:47
Вы сейчас будете отрицать, что используете это?

EF - да почти нет. Code first не нравится в принципе, хотя да, есть варианты когда без него никак.

alex445 коренной житель07.03.24 18:00
NEW 07.03.24 18:00 
в ответ AlexNek 07.03.24 17:58

Причём тут коде фёрст? Делегаты там в принципе используются везде. Отказываться от них это как приделать к своему велосипеду квадратные колёса и сделать морду "я самый умный". ))

AlexNek патриот07.03.24 18:02
AlexNek
NEW 07.03.24 18:02 
в ответ alex445 07.03.24 17:55
Да, лучше.

Ну, о вкусах не спорят. Мне и доска и море нафиг не нужны, а кому то позарез необходимо.

Срыв покровов патриот07.03.24 18:03
NEW 07.03.24 18:03 
в ответ AlexNek 07.03.24 17:58

Да хоть что first, ты под каждый пишешь свою функцию в репозитории, а потом размножаешь ее в каждом из слоев?

AlexNek патриот07.03.24 18:10
AlexNek
NEW 07.03.24 18:10 
в ответ alex445 07.03.24 18:00
Делегаты там в принципе используются везде

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

https://github.com/SeanLeitzinger/Entity-Framework-Core-Ex...

AlexNek патриот07.03.24 18:15
AlexNek
NEW 07.03.24 18:15 
в ответ Срыв покровов 07.03.24 18:03
ты под каждый пишешь свою функцию в репозитории, а потом размножаешь ее в каждом из слоев?

Сорри, никак не доходит о чём речь то смущ

Срыв покровов патриот07.03.24 18:23
NEW 07.03.24 18:23 
в ответ AlexNek 07.03.24 18:15

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

Как реализовать будешь?

AlexNek патриот07.03.24 19:43
AlexNek
NEW 07.03.24 19:43 
в ответ Срыв покровов 07.03.24 18:23
в одном месте тебе нужно изменить дату рождения человеку, в другом имя, в третьем адрес.

Так реализовывать в принципе не буду, всё должно быть в одном месте, а объект всегда иметь определенное состояние.

где то так - "Aggregates are the basic element of transfer of data storage — you request to load or save whole aggregates." MF

Хотя в зависимости от конкретики возможны варианты.


Вот рекомендации например:

https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/...

Никаких извращений


А визуально может быть так как и описано.

AlexNek патриот07.03.24 20:02
AlexNek
NEW 07.03.24 20:02 
в ответ Срыв покровов 07.03.24 18:23

Но если сильно хочется атомарности операций, нужно просто забыть об объекте "Покупатель".


Например, Вводим три "команды"

  • изменить дату рождения
  • изменить имя
  • изменить адрес


Которые могут вызывать скрытую "команду": изменить поле в таблице.


Принцип известный и простой - функция должна делать одну операцию и делать ее хорошо. И ничего другого она делать не должна.


Срыв покровов патриот07.03.24 21:43
NEW 07.03.24 21:43 
в ответ AlexNek 07.03.24 20:02, Последний раз изменено 07.03.24 21:47 (Срыв покровов)
Которые могут вызывать скрытую "команду": изменить поле в таблице.

и как эта команда может выглядеть?


Принцип известный и простой - функция должна делать одну операцию и делать ее хорошо.
изменить дату рождения

это очень много операций, надо отдельно:

Изменить день

Изменить месяц

Изменить год


AlexNek патриот07.03.24 22:03
AlexNek
NEW 07.03.24 22:03 
в ответ Срыв покровов 07.03.24 21:43
и как эта команда может выглядеть?

Совершенно не интересует на данный момент - это особенности реализации

Ну например так

https://www.w3schools.com/sql/sql_update.asp


UPDATE Customers
SET ContactName = 'Alfred Schmidt'
WHERE CustomerID = 1;


это очень много операций, надо отдельно:

согласно подобным желаниям нужно не так как написано, а так:

Изменить 1й бит в дне,

Изменить 2й бит в дне,

...

и т.п. для месяца и года бебе

А вообще, это задача для объекта "дата"

AlexNek патриот07.03.24 22:06
AlexNek
NEW 07.03.24 22:06 
в ответ AlexNek 07.03.24 22:03

Задолбался уже два раза кликать, как убрать эту галку: "Я хочу предварительно просмотреть мое сообщение и/или приложить файл"?

Убираешь и убираешь, а появляется опять.

Срыв покровов патриот08.03.24 06:55
NEW 08.03.24 06:55 
в ответ AlexNek 07.03.24 22:03

Ок, ответа от свидетелей банды четырех не будет

Какие уж там делегаты, когда все время уходит на войну с командой о недостаточности комментариев.

MrSanders коренной житель08.03.24 09:19
NEW 08.03.24 09:19 
в ответ Срыв покровов 08.03.24 06:55

Фу-фу-фу. Плюнуть в спину, когда ничего возразить не можешь... Не уподобляйся ололёшеньке.

Я на твой вопрос ответить не могу. Не понимаю проблемы, подозреваю что слишком конкретная, шарпистикая, я с шарпом практически не работал, EF не знаю.

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

Программист коренной житель08.03.24 10:18
NEW 08.03.24 10:18 
в ответ Срыв покровов 07.03.24 14:11
есть энтити класс Person, хочу функцию, которой я мог бы апдейтить любое свойство объекта Person в базе данных, доступ к объектам по айди

Я не когда-то очень давно делал один пример с EF просто ради ознакомления, но что-то мне подсказывает, что все эти делегаты - просто надстройка над EF. Ну типа как Linq - надстройка над коллекциями.


В случае с Linq все это работает по одной простой причине - Linq - это просто коллекция статических функций. Там нет, ни состояния, ни взаимодействия между компонентами.

Подозреваю, что в EF тоже самое - коллекция статических функций.


Делегат как входной параметр у статической функции вполне допустим. Другое дело, что сами по себе статические функции - зачастую головная боль. Но в виде расширения какого-либо интерфейса вполне допустимо.


Как я уже говорил, я не могу придумать пример, когда использование делегатов было бы оправдано. Как исключение можно тут указать только расширения существующих интерфейсов (типа Linq). Оспользование делегатов для уведомления других объектов - no go. Т.к. для этого надо использовать эвенты.

Murr патриот08.03.24 14:18
Murr
NEW 08.03.24 14:18 
в ответ Срыв покровов 07.03.24 21:43

еще

- изменить день недели

- изменить изменить порядковый номер дня в году

- изменить изменить порядковый номер недели в году


Самое смешное что это реальные требования потребителей.

Murr патриот08.03.24 14:20
Murr
NEW 08.03.24 14:20 
в ответ AlexNek 07.03.24 22:06

как убрать эту галку

----------------

В своем профиле поправь.

alex445 коренной житель08.03.24 16:43
NEW 08.03.24 16:43 
в ответ AlexNek 07.03.24 18:10, Последний раз изменено 08.03.24 16:48 (alex445)
Не имею понятия, для себя не пользую, вот нашел какой то примерчик. Покажите плиз...

А DbSet и IEnumerable со своими расширениями это что? Без LINQ этот EF - малополезная хрень.

alex445 коренной житель08.03.24 16:45
NEW 08.03.24 16:45 
в ответ AlexNek 07.03.24 19:43

Вот рекомендации например:

https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/...

Никаких извращений

Там делегаты в первом же примере.

Бесконечный цикл постоялец08.03.24 19:07
NEW 08.03.24 19:07 
в ответ Murr 08.03.24 14:18
еще

- изменить день недели

- изменить изменить порядковый номер дня в году

- изменить изменить порядковый номер недели в году

Самое смешное что это реальные требования потребителей.

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




AlexNek патриот08.03.24 19:18
AlexNek
NEW 08.03.24 19:18 
в ответ alex445 08.03.24 16:43
А DbSet

https://github.com/mono/entityframework/blob/master/src/En...

Можно копию кода о чём речь?

AlexNek патриот08.03.24 19:20
AlexNek
NEW 08.03.24 19:20 
в ответ Murr 08.03.24 14:20
В своем профиле поправь.

Блин, самому себе письмо отправить без галки зло

AlexNek патриот08.03.24 19:24
AlexNek
NEW 08.03.24 19:24 
в ответ alex445 08.03.24 16:45
Там делегаты в первом же примере.

А разве речь о делегатах? Речь об извращениях.

AlexNek патриот08.03.24 19:46
AlexNek
NEW 08.03.24 19:46 
в ответ alex445 08.03.24 16:43

https://github.com/dotnet/runtime/blob/main/src/libraries/...

Так это имелось в виду?

        public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
        {
            TSource? first = source.TryGetFirst(predicate, out bool found);
            if (!found)
            {
                ThrowHelper.ThrowNoMatchException();
            }

            return first!;
        }
Срыв покровов патриот08.03.24 19:51
NEW 08.03.24 19:51 
в ответ MrSanders 08.03.24 09:19
фу. Плюнуть в спину, когда ничего возразить не можешь.

Чему тут возражать? Было дано задание, в ответ только мычание, что за такое у нас лицо бьют.

Срыв покровов патриот08.03.24 19:53
NEW 08.03.24 19:53 
в ответ Murr 08.03.24 14:18
Самое смешное что это реальные требования потребителей.

Это требование современности - решать задачи актуальными инструментами.

alex445 коренной житель09.03.24 03:11
NEW 09.03.24 03:11 
в ответ MrSanders 07.03.24 09:19
12 год - да наф нам не нужон этот ваш делегат.

На всякий случай, Ололёшеньке всё равно, он у нас дурачок, по-англицки читать это не его, но вдруг кого удивило.

Во-первых, статья 1997-8 года. Не позднее. Java 1.2 не упоминается. Ну, ашипся ололёшенька. Бывает. (Статья про J++. Кто такое мелкомягкое уродство помнит?)

Во-вторых, суть статьи "нафиг усложнять VM ссылками на методы, если есть внутренние классы".

Ну и, в-третьих, ...

14 год - Джава 8 представляет лямбды и ссылки на методы.

"Ссылка на метод" в 8-й Яве это не "delegate". Это синтаксический сахар. Который компилятором преобразуется... во внутренний класс. Как и лямбда.

Да понятно, что из подручного мусора и костылей можно слепить что угодно, хоть небоскрёб. Мутить классы, чтобы из них использовать лишь методы, вместо того, чтобы сразу использовать лишь методы - гениальный же дизайн!


alex445 коренной житель09.03.24 03:19
NEW 09.03.24 03:19 
в ответ AlexNek 08.03.24 19:18
А DbSet

https://github.com/mono/entityframework/blob/master/src/En...

Можно копию кода о чём речь?

Речь об этом, на чём у вас все модели соединяются в удобоваримый контекст, а не остаются кучкой бесполезных классов.

alex445 коренной житель09.03.24 03:21
NEW 09.03.24 03:21 
в ответ AlexNek 08.03.24 19:24, Последний раз изменено 09.03.24 03:22 (alex445)
Там делегаты в первом же примере.
А разве речь о делегатах? Речь об извращениях.

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

AlexNek патриот09.03.24 10:46
AlexNek
NEW 09.03.24 10:46 
в ответ alex445 09.03.24 03:19
Речь об этом,

и где там, в какой строке?

Хотя вроде стало понятно, что фактические параметры функции называют "делегатом"


var entities = ChangeTracker.Entries().Where(x => (x.Entity is Entity)....

AlexNek патриот09.03.24 10:50
AlexNek
NEW 09.03.24 10:50 
в ответ alex445 09.03.24 03:21
Потому что ну уже у всех есть,

Ну нужно путать что-то с пальцем спок

Практически любую вещь можно использовать правильно и неправильно.

MrSanders коренной житель09.03.24 18:20
NEW 09.03.24 18:20 
в ответ alex445 09.03.24 03:21, Последний раз изменено 09.03.24 18:33 (MrSanders)
Извращения это имитация ссылок на методы внутренними классами, и пятнадцать лет говорить, что нам не нужны делегаты, а потом делать их через извращения. Потому что ну уже у всех есть, включая главного конкурента.

Кроме тебя никто не говорил что в яве есть делегаты. Их в яве нет. В яве есть "ссылки на методы". Так до тебя дойдёт?

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

вместо того, чтобы сразу использовать лишь методы - гениальный же дизайн!

Для объектно-ориентированного языка? Да. Ты про SmallTalk слышал? Там не то что на методы ссылаться, там код на лету менять можно. Почитай, ощути какое отсталое кю твой шарп. А потом опять немного подумай - а почему же мы все не пишем сейчас на таком прекрасном языке.

P.S. а как интересно "ссылки на методы" реализованы в Tcl... Если мелкомягкие шарписты его для себя когда-нибудь откроют, тоже начнут как не в себя тырить, не понимая что и зачем? :)

Бесконечный цикл постоялец09.03.24 19:25
NEW 09.03.24 19:25 
в ответ alex445 09.03.24 03:21

1. C# уже сильно позже Явы сделали, а потому С# во многих местах сильно лучше, поскольку по граблям уже не ходили, а все просто стырили. Ну скажем у массивов в Яве макс. размер 32 бита (2ГБ), а в C# 64 бита.


2. Надо различать язык и VM. Если в JVM чего-то нет, то значит нет, и в языке надо извращаться. В C# много чего встроили, а потому и в языке легче. Например генерики (классы с параметрами). В JVM их нет. Ну или делегаты.


3. Есть еще идеология. Многие полезные вещи считаются богохульством в ООП-религии. Ява хотела быть святее папы, а в C# все по барабану, лишь бы бабло польза была.

Срыв покровов патриот09.03.24 20:09
NEW 09.03.24 20:09 
в ответ MrSanders 09.03.24 18:20
Кроме тебя никто не говорил что в яве есть делегаты. Их в яве нет. В яве есть "ссылки на методы". Так до тебя дойдёт?

сорри за возможно глупый вопрос: но вот это разве не делегаты?

// Function which takes in a number

// and returns half of it

Function<Integer, Double> half = a -> a / 2.0;

// Applying the function to get the result

System.out.println(half.apply(10));

AlexNek патриот09.03.24 21:41
AlexNek
NEW 09.03.24 21:41 
в ответ Срыв покровов 09.03.24 20:09
вот это разве не делегаты?

Может быть мы вначале начнём с определения делегатов?

https://learn.microsoft.com/en-us/dotnet/csharp/programmin...


https://www.c-sharpcorner.com/article/send-method-as-param...

Murr патриот09.03.24 21:59
Murr
NEW 09.03.24 21:59 
в ответ Срыв покровов 09.03.24 20:09

это разве не делегаты?

------

Считай что делегат это декларация типа указателя на функцию с типизацией возврата и параметров.

Срыв покровов патриот10.03.24 08:02
NEW 10.03.24 08:02 
в ответ AlexNek 09.03.24 21:41

Я уже писал, что для меня это одно и то же.

В чем я ошибаюсь?

MrSanders коренной житель10.03.24 10:40
NEW 10.03.24 10:40 
в ответ Срыв покровов 09.03.24 20:09, Последний раз изменено 10.03.24 11:12 (MrSanders)
сорри за возможно глупый вопрос: но вот это разве не делегаты?

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

Для меня делегат это "переменная-метод". Которую можно использовать как метод.

Т.е. чтобы можно было сделать так:

Function<Integer, Double> half = a -> a /2.0;
// Applying the function to get the result
System.out.println(half(10));

В яве так сделать нельзя.
И этот "конструкт" должен быть "first-class citizen". Выполнять все 4 требования. В яве ссылки нa методы нельзя сравнивать. Не работает.

import java.util.function.Function;
public class MyClass {
    public static String value(int i) {
        return "Value: " + i;
    }
    public static void main(String args[]) {
      Function<Integer, String> f1 = MyClass::value; 
      Function<Integer, String> f2 = MyClass::value;    
      System.out.println("Same method? : " + f1.equals(f2));
    }
}

Вернёт false.


Function<Integer, Double> half = a -> a /2.0; компилятором превращается в

Function<Integer, Double> half = new Function<Integer, Double>() {
  @Override
  public Double apply(Integer t) {
    return t / 2.0;
  }
}

Новый класс. Сделали ещё раз то же самое, получили ещё один новый класс. То же и с ссылками,

из Function<Integer, String> f1 = MyClass::value; получается

Function<Integer, String> f1 = new Function<Integer, String>() {
  @Override
  public String apply(Integer t) {
    return MyClass.value(t);
  }
}

Два раза использовали ссылку, получили два класса. Сравниваешь их, а они не равны. Что правильно, это же разные классы. А вот логично было бы иметь возможность писать f1 == f2 и получать true. Если б это были и правда ссылки на методы. Вот такая фигня, малята.

Срыв покровов патриот10.03.24 10:59
NEW 10.03.24 10:59 
в ответ MrSanders 10.03.24 10:40, Последний раз изменено 10.03.24 10:59 (Срыв покровов)

требования, чтобы два делегата с одинаковым содержанием язык считал одинаковыми, я вообще не понимаю зачем ты сейчас привёл.
Без этого они не считаются делегатами?

MrSanders коренной житель10.03.24 11:17
NEW 10.03.24 11:17 
в ответ Срыв покровов 10.03.24 10:59, Последний раз изменено 10.03.24 11:25 (MrSanders)

Про одинаковое содержание я не заикаюсь.

Я про ссылку на одинаковый метод. x = <ссылка на метод>; y = <ссылка на тот же метод>; x == y => false. А должно быть true если б это была "настоящая ссылка на метод".


Ну, или так, сейчас со ссылками на методы такая ситуация, как будто ты делаешь

String x = "abc";

int l1 = x.length();

int l2 = x.length();

и l1 у тебя не равен l2.


P.S. к half(10) вместо half.apply(10) вопросов нет?

AlexNek патриот10.03.24 12:01
AlexNek
NEW 10.03.24 12:01 
в ответ Срыв покровов 10.03.24 08:02
В чем я ошибаюсь?

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

Поэтому давайте разбираться вместе.

https://learn.microsoft.com/en-us/dotnet/csharp/programmin...

https://www.c-sharpcorner.com/article/send-method-as-param...


C#

"A delegate is a type that represents references to methods with a particular parameter list and return type"

"Delegates are similar to C++ function pointers, but delegates are fully object-oriented, and unlike C++ pointers to member functions, delegates encapsulate both an object instance and a method."


delegate declaration

public delegate int Operation(int i, int j);

instantiate a delegate

Operation operation = (i, i1) => i + i1;

invoke

int result = operation(1, 2);


Java

"Since Java 1.8 we have the Java.util.Function interface (remember Java uses interfaces to send methods as parameters)."


Interface Function<T,R>


delegate declaration - нет


код похожий на instantiate a delegate

Function<Employee, String> f0 = (e) -> e.toString();


выполнение

String result = f0.apply(e1);

Отличия есть и довольно большие, хотя визуально ничего особенно не видно

alex445 коренной житель10.03.24 12:14
NEW 10.03.24 12:14 
в ответ MrSanders 10.03.24 10:40, Последний раз изменено 10.03.24 12:20 (alex445)
сорри за возможно глупый вопрос: но вот это разве не делегаты?
Вот кстати да, как уточняет AlexNek, было бы неплохо определиться, а что мы вообще делегатами называем.
Для меня делегат это "переменная-метод". Которую можно использовать как метод.
Т.е. чтобы можно было сделать так:



Function<Integer, Double> half = a -> a /2.0;
// Applying the function to get the result
System.out.println(half(10));
В яве так сделать нельзя.
И этот "конструкт" должен быть "first-class citizen". Выполнять все 4 требования. В яве ссылки нa методы нельзя сравнивать. Не работает.





import java.util.function.Function;
public class MyClass {
    public static String value(int i) {
        return "Value: " + i;
    }
    public static void main(String args[]) {
      Function<Integer, String> f1 = MyClass::value; 
      Function<Integer, String> f2 = MyClass::value;    
      System.out.println("Same method? : " + f1.equals(f2));
    }
}
Вернёт false.

Function<Integer, Double> half = a -> a /2.0; компилятором превращается в




Function<Integer, Double> half = new Function<Integer, Double>() {
  @Override
  public Double apply(Integer t) {
    return t / 2.0;
  }
}
Новый класс. Сделали ещё раз то же самое, получили ещё один новый класс. То же и с ссылками,
из Function f1 = MyClass::value; получается



Function<Integer, String> f1 = new Function<Integer, String>() {
  @Override
  public String apply(Integer t) {
    return MyClass.value(t);
  }
}
Два раза использовали ссылку, получили два класса. Сравниваешь их, а они не равны. Что правильно, это же разные классы. А вот логично было бы иметь возможность писать f1 == f2 и получать true. Если б это были и правда ссылки на методы. Вот такая фигня, малята.

Толчея воды в ступе. Спор даже не о словах, а о буквах. Единственный вывод, что я делаю из этой простыни: Джава говно, Сишарп - конфетка (по сравнению с Джавой).

AlexNek патриот10.03.24 13:09
AlexNek
NEW 10.03.24 13:09 
в ответ alex445 10.03.24 12:14
Единственный вывод, что я делаю

При этом не следует забывать добавить, для себя лично.

Из-за того, что мне не нравится тот или иной язык, не следует что он плохой.

Давайте сравним русский, немецкий и китайский - какой из них лучше?

Срыв покровов патриот10.03.24 13:37
NEW 10.03.24 13:37 
в ответ AlexNek 10.03.24 12:01

что вы мне тут пытаетесь доказать? Что в с# Что в яве я могу определить переменную или свойство с определённым входным и выходным типом, а затем в коде переопределять ее как мне заблагорассудится.

Вы можете хоть из штанов выпрыгнуть, но это одно и то же.

AlexNek патриот10.03.24 14:44
AlexNek
NEW 10.03.24 14:44 
в ответ Срыв покровов 10.03.24 13:37
что вы мне тут пытаетесь доказать?

Абсолютно ничего. Я предложил разбираться вместе и привел мои рассуждения. Вы с ними несогласны и приводите свои - ну так это замечательно. Через какое то время можно будет найти и точки соприкосновения. Ну или точно определится с разногласиями.


я могу определить переменную или свойство с определённым входным и выходным типом, а затем в коде переопределять ее как мне заблагорассудится.

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

Однако для меня это определение - всего лишь ссылка на метод. Типа как в Си. МС не трактует делегаты подобным образом. (A delegate is a type that represents references to methods with a particular parameter list and return type. Delegates are an object-oriented, type safe, and secure type that safely encapsulates a method)


Вот еще определение нашел: The delegate is a reference type data type that defines the method signature. You can define variables of delegate, just like other data type, that can refer to any method with the same signature as the delegate.

Насколько я понял, в Яве подобного определения нет.


И я совсем не уверен, что в Яве возможно что то подобное

public delegate void MyDelegate();
MyDelegate delg = () =>  Console.WriteLine("Test");
delg();
alex445 коренной житель10.03.24 15:13
NEW 10.03.24 15:13 
в ответ Срыв покровов 10.03.24 13:37, Последний раз изменено 10.03.24 15:17 (alex445)
что вы мне тут пытаетесь доказать? Что в с# Что в яве я могу определить переменную или свойство с определённым входным и выходным типом, а затем в коде переопределять ее как мне заблагорассудится.
Вы можете хоть из штанов выпрыгнуть, но это одно и то же.

Они пытаются доказать, что если в Джаве реализовано по-другому, то это не делегаты, как в Шарпе, а своя какая-то неведомая херня. Можно было бы сказать, что в Шарпе - ссылки на методы. Но они и тут бы возбудились - нет, в Шарпе делегаты! Спорят о словах и прочих неважных вещах, лишь бы увести в сторону от главного - в Джаве это реализовано хуже и костыльнее, не такое широкое применение имеет и не так хорошо интегнировано в язык и фреймворк.

MrSanders коренной житель10.03.24 17:01
NEW 10.03.24 17:01 
в ответ AlexNek 10.03.24 14:44

И я совсем не уверен, что в Яве возможно что то подобное

public delegate void MyDelegate();
MyDelegate delg = () =>  Console.WriteLine("Test");
delg();

Примерно так же, кроме последней строчки. В яве ссылка не метод превращается в объект. И пока что синтаксический сахар, чтобы вызвать deleg() не прикрутили. Runnable существующий тип, можно определить свой. Просто интерфейс с одним методом.


Runnable delg = () -> System.out.println("Print");
delg.run();

А как в шарпе можно присвоить delegate-у существующий метод класса? MyDelegate delg = <метод printX() объекта x1 типа X>;

7495 старожил10.03.24 17:05
7495
NEW 10.03.24 17:05 
в ответ alex445 10.03.24 15:13
Спорят о словах и прочих неважных вещах, лишь бы увести в сторону от главного...


Абсолютно согласен с вами, коллега, надо смотреть ширше и глыбже! Неважно на каком языке реализовано - главное результат!


Надо смотреть на уровень зарплаты, у кого зарплата больше - тот и прав! Практика является важным критерием истинности!


Кто пьёт смузи, у кого нестыдная машина, кто работает начальником - тот и прав! Эта истина проста, но не всем доступна! зло

Вопросы и Ответы - Программируем калькулятор пособий для беженцев вместе.
MrSanders коренной житель10.03.24 17:10
NEW 10.03.24 17:10 
в ответ alex445 10.03.24 12:14
олчея воды в ступе. Спор даже не о словах, а о буквах.

Многабуков. Понимаю. Лонгрид. В клиповый мозг не прогрузилось. Не плачь, оно тебе не надо. Просто сиди, не кукарекай, и всё будет хорошо!

AlexNek патриот10.03.24 17:56
AlexNek
NEW 10.03.24 17:56 
в ответ MrSanders 10.03.24 17:01
Примерно так же, кроме последней строчки...А как в шарпе

Судя пот ответу вы считает, что я тоже бросаю камни в Яву. Абсолютно не так. Я просто пытаюсь найти отличия.

И в данном случае опирался на это

https://docs.oracle.com/javase/8/docs/api/java/util/functi...

Про Runnable там не было. Интересно как с различными количеством параметров происходит?


Но опять таки, я не вижу определения типа, так как используются только существующие (видимо) интерфейсы.

AlexNek патриот10.03.24 18:08
AlexNek
NEW 10.03.24 18:08 
в ответ alex445 10.03.24 15:13, Последний раз изменено 10.03.24 18:09 (AlexNek)
в Джаве это реализовано хуже и костыльнее

А можно уточнить какой у вас опыт разработки приложений на Яве?

Могу сразу сказать, что у меня нулевой. Но если в каком то языке мне что то не нравится - это совсем не значит что язык из-за этого полное дёрьмо.


пытаются доказать

Это просто размышления вслух, как способ изучения материала.

Что то кому то доказывать, практически бесполезная трата времени. А может и того хуже https://ru.wikipedia.org/wiki/Рели�%...


alex445 коренной житель10.03.24 18:38
NEW 10.03.24 18:38 
в ответ MrSanders 10.03.24 17:01, Последний раз изменено 10.03.24 18:48 (alex445)
И я совсем не уверен, что в Яве возможно что то подобное
public delegate void MyDelegate();
MyDelegate delg = () =>  Console.WriteLine("Test");
delg();
Примерно так же, кроме последней строчки. В яве ссылка не метод превращается в объект. И пока что синтаксический сахар, чтобы вызвать deleg() не прикрутили. Runnable существующий тип, можно определить свой. Просто интерфейс с одним методом.




Runnable delg = () -> System.out.println("Print");
delg.run();
А как в шарпе можно присвоить delegate-у существующий метод класса? MyDelegate delg = <метод printX() объекта x1 типа X>;

Можно вывести тип делегата автоматически (начиная с 10 версии языка), если он совпадает с одним из Func или Action (до 16 параметров в каждом). Как раньше было сказано, в Дотнете определены Func или Action с числом обобщённых параметров до 16 (плюс возврат для Func), что позволяет покрыть практически все варианты функций. Тут в меню слева видно. Это позволяет работать фиче автоматического выведения типа делегата. Но если у вас свой тип, повторяющий один из уже готовых Func или Action - может не сработать, или приведёт к одному из Func-Action (тут я точно не знаю - не использовал). Посему лучше использовать уже готовый тип, если он совпадает с нужной вам сигнатурой по входящим параметрам и возврату, чтобы все выведения работали автоматически. Те, кто нарушают конвенции и изобретают велосипеды - да, должны страдать.


Так что объявлять свои типы делегатов для типичных методов - бесполезное занятие. Разве что кто-то хочет именно через имя типа делегата разъяснить, для чего он служит. Но это лишнее. В Дотнете существуют старые делегаты, которые ввели до появления пачек Action и Func - их оставили для совместимости. Но фактически Predicate это один из вариантов Func.


Ещё тут разъяснено, и как это делалось до версии 10.

alex445 коренной житель10.03.24 18:49
NEW 10.03.24 18:49 
в ответ alex445 10.03.24 18:38, Последний раз изменено 10.03.24 18:58 (alex445)

Да, кстати, что там в Джаве в качестве аналога деревьев выражений?


"Most times you're going to want Func or Action if all that needs to happen is to run some code. You need Expression when the code needs to be analyzed, serialized, or optimized before it is run. Expression is for thinking about code, Func/Action is for running it."


Я уже не говорю про динамический LINQ.

MrSanders коренной житель10.03.24 18:55
NEW 10.03.24 18:55 
в ответ AlexNek 10.03.24 17:56, Последний раз изменено 10.03.24 19:10 (MrSanders)
Судя пот ответу вы считает, что я тоже бросаю камни в Яву. Абсолютно не так. Я просто пытаюсь найти отличия.

Нет, мне просто интересно как в шарпе реализовали именно ссылки на методы, а не присваивание "имён" лямбдам. Я с этим в шарпе не сталкивался.


Про Runnable там не было. Интересно как с различными количеством параметров происходит?

В яве сделали через "функциональные интерфейсы". Любой интерфейс с одним методом считается "функциональным", т.е. может описывать тип функции (метода).

Runnable старый интерфейс, который был и до 8-й явы, и не лежит в java.util.function. Но так как у него один метод, то и он стал "фунциональным" :) И он прям подошёл для твоего примера, потому что параметров нет и ничего не возвращает.


Фишка в том, что любой метод класса или лямбду можно определить типом функционального интерфейса у которого единственный метод имеет те же параметры (количество и тип) и тот же тип результата (ну, про наследование и приведение типов не забываем) что и наш метод / лямбда. В примере, как add: два инта и возвращает инт.


public interface MyMethod { int add(int a, int b);}

// Не функциональный! больше одного метода
public interfce TooManyMethods {
  int add(int a, int b);
  int multiply(int a, int b);
}

MyMethod m = (a, b) -> a + b;

// маловато параметеров, ошибка будет
MyMethod wrong = a -> a + 10;

как-то так

Срыв покровов патриот10.03.24 18:56
NEW 10.03.24 18:56 
в ответ alex445 10.03.24 18:49

да вроде то же самое есть

    private static Function<Integer, Integer> multiply = x -> x * 2;

    private static Function<Integer, Integer> add = x -> x + 2;

    private static Function<Integer, Unit> logOutput = x -> {
        logger.info("Data:" + x);
        return Unit.unit();
    };

    public static Unit execute(Integer input) {
        Function<Integer, Unit> pipeline = multiply
                                               .andThen(add)
                                               .andThen(logOutput);
        return pipeline.apply(input);
    } 
alex445 коренной житель10.03.24 19:08
NEW 10.03.24 19:08 
в ответ Срыв покровов 10.03.24 18:56, Последний раз изменено 10.03.24 19:26 (alex445)
да вроде то же самое есть







<code>    private static Function<Integer, Integer> multiply = x -> x * 2;

    private static Function<Integer, Integer> add = x -> x + 2;

    private static Function<Integer, Unit> logOutput = x -> {
        logger.info("Data:" + x);
        return Unit.unit();
    };

    public static Unit execute(Integer input) {
        Function<Integer, Unit> pipeline = multiply
                                               .andThen(add)
                                               .andThen(logOutput);
        return pipeline.apply(input);
    } </code>

Это больше похоже на Select и SelectMany - просто пачка расширяющих методов с делегатами в качестве параметров, применяемых ко входным данным и результатам. А я спросил про деревья выражений - сериализация делегатов и функций, представление их в виде данных.


Вобщем, я поискал - нет такого в Джаве из коробки. Есть какие-то сторонние либы, разрабатываемые энтузиастами, типа JaQue. Это не сравнимо с Дотнетом и Шарпом, где подобные фичи разрабатываются, внедряются во фреймворк и поддерживаются на системном уровне самой компанией-разработчиком языка и фреймворка. В Дажве и большинстве других языков без крупного хозяина всегда такие проблемы - их экосистемы представляют из себя конструктор "сделай сам" - т.е. практически отсутствуют. Надо писать под десктоп? - Ищи гуёвую либу под Джаву. Надо под веб? - Ищи гуёвую либу для веба. Надо трёхмерную графику? - Ищи джавовый движок. И вот часто у Джавы и других языков либо нет нифига для этого, либо что-то стороннее, с поддержкой мелкой фирмочки или вообще тремя с половиной энтузиастами. Хочешь комплексное решение "всё из коробки, подогнанное"? - Иди к Майкрософт. Да, у них есть проблемы. Но у других их ещё больше. Что-то подобное есть лишь у Эппл. Но хуже, мельче, меньший охват (нет своей СУБД, например), и нужно менять ориентацию (в переносном смысле).

Срыв покровов патриот10.03.24 19:21
NEW 10.03.24 19:21 
в ответ alex445 10.03.24 19:08

select и SelectMany это вообще про другое.

Напиши код на с#, который не сделать на Яве.

alex445 коренной житель10.03.24 19:30
NEW 10.03.24 19:30 
в ответ Срыв покровов 10.03.24 19:21, Последний раз изменено 10.03.24 19:31 (alex445)

Как про другое, если это оно и есть?

https://docs.oracle.com/javase/8/docs/api/java/util/functi...


Написать можно что угодно на чём угодно. Только на одном это будет легко и приятно, а на другом нет. Вспоминаем.

AlexNek патриот10.03.24 20:00
AlexNek
NEW 10.03.24 20:00 
в ответ MrSanders 10.03.24 18:55
Нет, мне просто интересно как в шарпе реализовали именно ссылки на методы

Ну тут вроде достаточно много

https://www.tutorialsteacher.com/csharp/csharp-delegates


Если недостаточно, опишите подробнее, что именно интересует.


Есть подозрения, что начнётся новый вой, что в этом хх языке и Multicast Delegate нету спок

alex445 коренной житель10.03.24 20:30
NEW 10.03.24 20:30 
в ответ AlexNek 10.03.24 20:00, Последний раз изменено 10.03.24 20:38 (alex445)

Ну тут вроде достаточно много
https://www.tutorialsteacher.com/csharp/csharp-delegates

Только потом читатели букварей забывают забыть все эти MyDelegate(string msg), и начать пользоваться обычными Action и Func. Так и продолжают клепать свои однотипные делегаты на каждый чих.


в этом хх языке и Multicast Delegate нету

Я уже привык, что многое в Джаве, включая делегаты - кривое-косое-урезанное. После Сишарпа - будто переехал из своего дома в общагу. Как правильно отмечают в беседах на том же Stackoverflow, создатели Джава слишком ограничили себя "чистым ООП", загнали в сами себе же созданные рамки ради идеологии, принеся в жертву реальные потребности. Шарп оказался гибче и этим лучше. Да плюс возник попозже, учтя ошибки Джавы. "Что отвердело, то не победит."

Срыв покровов патриот10.03.24 20:38
NEW 10.03.24 20:38 
в ответ alex445 10.03.24 19:30

Алекс, ты три дня старперов за пояс затыкаешь и тут такой прокол на мелочах. Соберись.
сишарповский Select это аналог map() в stream api в Яве


Срыв покровов патриот10.03.24 20:42
NEW 10.03.24 20:42 
в ответ Срыв покровов 10.03.24 20:38

метод andThen из двух делегатов делает новый делегат

MrSanders коренной житель10.03.24 20:44
NEW 10.03.24 20:44 
в ответ AlexNek 10.03.24 20:00
Ну тут вроде достаточно много
https://www.tutorialsteacher.com/csharp/csharp-delegate

Во. Вот это меня интересует: MyDelegate del = MethodA;

Если я два делегейта сделаю

MyDelegate del1 = MethodA;

MyDelegate del2 = MethodA;

del1 будет равен del2? del1 == del2, или del1.Equals(del2)?

AlexNek патриот10.03.24 20:44
AlexNek
NEW 10.03.24 20:44 
в ответ alex445 10.03.24 20:30
Так и продолжают клепать свои однотипные делегаты на каждый чих

Я только не понимаю, зачем постоянно проталкивать своё мнение считая его единственно правильным?

Уже ведь давно выяснили, что кто то любит "пользоваться обычными Action и Func." спок

alex445 коренной житель10.03.24 20:59
NEW 10.03.24 20:59 
в ответ Срыв покровов 10.03.24 20:38, Последний раз изменено 10.03.24 21:07 (alex445)

Мне можно, т.к. на самом деле я ламер.

Глянул получше - это что-то типа Enumerable? Можно бесконечно цеплять фукнции к последовательностям, которые что-то делают с элементами этих последовательностей?


Просто в Select то же самое - это расширение Enumerable, позволяющее сразу задать несколько действий над элементами последовательности через параметры-делегаты.

AlexNek патриот10.03.24 21:24
AlexNek
NEW 10.03.24 21:24 
в ответ MrSanders 10.03.24 20:44, Последний раз изменено 10.03.24 21:29 (AlexNek)
del1 будет равен del2?

Никогда не интересовало, но по идее должны быть равны.

И таки да:

https://dotnetfiddle.net/9qRfq2 интересно еще View IL глянуть


alex445 коренной житель10.03.24 21:46
NEW 10.03.24 21:46 
в ответ Срыв покровов 10.03.24 20:42
метод andThen из двух делегатов делает новый делегат

Тогда это сишарповский мультикаст делегат.

MrSanders коренной житель11.03.24 07:14
NEW 11.03.24 07:14 
в ответ AlexNek 10.03.24 21:24

Никогда не интересовало, но по идее должны быть равны. И таки да

Ну вот. Поэтому (для меня) в шарпе делегейты есть, а в яве - нет. Если определять (по-моему неправильно) делегейт как "возможность передать метод как параметр" тогда они есть и в шарпе и в яве. Причём с самой первой версии :)

P.S. Но и тот и другой близко не функциональные языки с выводом типов (type inference) вроде ML или хаскеля.

alex445 коренной житель20.03.24 11:53
NEW 20.03.24 11:53 
в ответ MrSanders 11.03.24 07:14, Последний раз изменено 20.03.24 11:58 (alex445)

В Яву потихоньку подвозят Сишарп 5-7-летней давности.


Implicitly Declared Classes and Instance Main Methods (Second Preview) (JEP 463)

Мне ненравится как сделали этот JEP. Есть проблема-многословный синтаксис, лишние абстракции которые как выяснилось не всегда нужны. Что мы сделаем, исправим это в языке? Нет, введем дополнительный граничный случай для начинающих с неявно объявленными классами, которые как потом выснится больше нигде работать небудут.

В Яве через эти внутренние классы вообще все фичи вводят?

Срыв покровов патриот21.03.24 19:03
NEW 21.03.24 19:03 
в ответ alex445 20.03.24 11:53

большинство примеров это конечно разрыв мозга


оно может не запрещено, то блять зачем, когда можно просто написать total = orders.length();

int total = 0;
for (Order _ : orders) // order is unused
total++;
Срыв покровов патриот21.03.24 19:04
NEW 21.03.24 19:04 
в ответ Срыв покровов 21.03.24 19:03

а написать q.remove() без присвоения что нельзя?

Queue<Integer> q = ... // x1, y1, z1, x2, y2, z2, ...
while (q.size() >= 3) {
var x = q.remove();
var y = q.remove();
var _ = q.remove();
... new Point(x, y) ...
}
Срыв покровов патриот21.03.24 19:09
NEW 21.03.24 19:09 
в ответ Срыв покровов 21.03.24 19:04
Напомним, что ранее в Java 11 появилась возможность запускать программы, состоящие из одного файла, без необходимости самостоятельной компиляции (JEP 330):
Революция!
alex445 коренной житель22.03.24 05:33
NEW 22.03.24 05:33 
в ответ Срыв покровов 21.03.24 19:09, Последний раз изменено 22.03.24 05:40 (alex445)
AlexNek патриот22.03.24 18:08
AlexNek
NEW 22.03.24 18:08 
в ответ alex445 22.03.24 05:33

party пора вам делать на вашем острове и на костре Эванса спалить бебе

alex445 коренной житель22.03.24 22:45
NEW 22.03.24 22:45 
в ответ AlexNek 22.03.24 18:08

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

alex445 коренной житель22.03.24 22:54
NEW 22.03.24 22:54 
в ответ alex445 22.03.24 05:33, Последний раз изменено 22.03.24 23:01 (alex445)
Новая часть кода сделана по ЧиА, а старая постепенно переносится из дремучего легаси в новую парадигму. Да, получилось много классов, но они маленькие, сконцентрированные на своей задаче, разбитые по слоям. Но в чём проблема?

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


Вообще, всё это сделано для якобы аджайла и continuous integration. Но зачастую проекты как один раз написаны, так почти без существенных доработок и существуют годами. После чего их в значительной части или полностью переписывают. Раз в 5-10 лет. Получается просто последовательность переписываемых почти-монолитов. И такая модель в некоторых случаях более уместна. Проблема всяких аджайл-фанатиков и прочих солидистов в том, что они пихают своё видение во все щели, даже где оно нафиг не сдалось.


без ЧиА в легаси это большие классы на несколько сотен строк, а в новом коде это много классов до сотни строк каждый

Блин, чел хоть раз открывал исходники больших библиотек? Там некоторые классы на тыщи строк. Вот проще и удобнее в некоторых случаях сделать класс на тыщи строк - его так и делают. А не следуют тупым и слепым догмам "классы должны быть маленькими". В куче связанных мелочей зачастую очень трудно составить весь путь потока информации от скажем нажатия на кнопку до получения результата. Там всё проходит через десять слоёв, 20 классов и пачку конвертаций. Задолбаешься прыгать по этим мелким классам, отслеживая стеки вызовов.

AlexNek патриот22.03.24 22:59
AlexNek
NEW 22.03.24 22:59 
в ответ alex445 22.03.24 22:45
Видно, что народ вся эта хитромудрая хрень уже достала.

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

AlexNek патриот22.03.24 23:02
AlexNek
NEW 22.03.24 23:02 
в ответ alex445 22.03.24 22:54
Но зачастую проекты как один раз написаны, так почти без существенных доработок и существуют годами.

имею большое количество совершенно обратных примеров, но не хочу утверждать, что все были написаны хорошо.

alex445 коренной житель22.03.24 23:05
NEW 22.03.24 23:05 
в ответ AlexNek 22.03.24 22:59, Последний раз изменено 22.03.24 23:05 (alex445)
Видно, что народ вся эта хитромудрая хрень уже достала.
совсем не обязательно, то что вы видите в своем микроскопе должны видеть и другие.

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

alex445 коренной житель22.03.24 23:08
NEW 22.03.24 23:08 
в ответ AlexNek 22.03.24 23:02
Но зачастую проекты как один раз написаны, так почти без существенных доработок и существуют годами.

имею большое количество совершенно обратных примеров, но не хочу утверждать, что все были написаны хорошо.

Что было бы с вами, если бы вас родили не монолитом? Или пришол бы такой дядя с ножом, и предложил бы вам превратиться в кучку микросервисов с органами и частями тела по пакетам? Не везде микросервисы полезны - где-то рулят монолиты. ))

AlexNek патриот22.03.24 23:18
AlexNek
NEW 22.03.24 23:18 
в ответ alex445 22.03.24 23:05

Что будет обсираться в этом месяце? бебе

Пока помню JS, Java

AlexNek патриот22.03.24 23:19
AlexNek
NEW 22.03.24 23:19 
в ответ alex445 22.03.24 23:08
Не везде микросервисы полезны

Удивительно, но наконец-то можно согласится смущ

AlexNek патриот23.03.24 12:49
AlexNek
NEW 23.03.24 12:49 
в ответ alex445 22.03.24 23:05
Показываешь круглый оранжевый апельсин

А не приходит другое сравнение?

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


Что-то вы подзадолбали со своим аналогом divercity.

отчего то вы видите всё в другом свете.

Речь всего лишь о том, что не следует везде кричать - я имею мнение и оно единственно правильное. Всё остальное чушь собачья.

2022!

https://www.rbc.ru/society/02/08/2022/62e8e09f9a794727b478...

MrSanders коренной житель23.03.24 13:38
NEW 23.03.24 13:38 
в ответ AlexNek 23.03.24 12:49, Последний раз изменено 23.03.24 13:39 (MrSanders)

Да пациенту просто скучно. Он и развлекается как может. А может он плоховато.

Кто-нибудь! Заберите его во Флориду! Посадите в клетку, будете людям за деньги показывать. Только клeтка чтоб на берегу моря (или океана)! win-win

AlexNek патриот23.03.24 14:42
AlexNek
NEW 23.03.24 14:42 
в ответ MrSanders 23.03.24 13:38
Посадите в клетку,

В клетку нельзя, на доске кататься не сможет. бебе

alex445 коренной житель23.03.24 15:54
NEW 23.03.24 15:54 
в ответ AlexNek 22.03.24 23:18

Заметьте, я просто кинул ссылки пару раз на мысли других людей. А то вы тут могли подумать, что лишь я что-то "обсираю". А вот люди тоже недовольны, и их немало.


Что, шатается земля под ногами? Чувствуете неуверенность в казавшихся нерушими догматах? ))

alex445 коренной житель23.03.24 15:56
NEW 23.03.24 15:56 
в ответ AlexNek 23.03.24 12:49

Речь всего лишь о том, что не следует везде кричать - я имею мнение и оно единственно правильное. Всё остальное чушь собачья.

2022!

https://www.rbc.ru/society/02/08/2022/62e8e09f9a794727b478...


alex445 коренной житель23.03.24 15:58
NEW 23.03.24 15:58 
в ответ MrSanders 23.03.24 13:38, Последний раз изменено 23.03.24 16:00 (alex445)
Да пациенту просто скучно. Он и развлекается как может. А может он плоховато.

Вы неизменно отводите себе роль доктора. Чувствуете себя окружённым больными? Тогда окончите вашу мысль.

AlexNek патриот23.03.24 16:38
AlexNek
NEW 23.03.24 16:38 
в ответ alex445 23.03.24 15:54
А вот люди тоже недовольны, и их немало.

Статистика есть? Справки от спортлото у них есть?

MrSanders коренной житель23.03.24 17:51
NEW 23.03.24 17:51 
в ответ AlexNek 23.03.24 14:42
В клетку нельзя, на доске кататься не сможет. бебе

А как ещё зрителей защитить? Он же их заплюёт: и прибой звучит неправильно, и цвет у воды не как на картинке, и пальмы растут не те и не там. На доске кататься только за хорошее поведение :) Будет как отец Фёдор на скале:


"Спустилась быстрая ночь. В кромешной тьме и в адском гуле под самым облаком дрожал и плакал отец Федор. Ему уже не нужны были земные сокровища. Он хотел только одного – вниз, на землю. Ночью он ревел так, что временами заглушал Терек, а утром подкрепился любительской колбасой с хлебом и сатанински хохотал над пробегавшими внизу автомобилями. Остаток дня он провел в созерцании гор и небесного светила – солнца. Ночью он увидел царицу Тамару."


alex445 коренной житель23.03.24 21:26
NEW 23.03.24 21:26 
в ответ AlexNek 23.03.24 16:38, Последний раз изменено 23.03.24 21:27 (alex445)
А вот люди тоже недовольны, и их немало.
Статистика есть? Справки от спортлото у них есть?

С подписью лично Путина!

AlexNek патриот23.03.24 22:07
AlexNek
NEW 23.03.24 22:07 
в ответ alex445 23.03.24 21:26, Последний раз изменено 23.03.24 22:08 (AlexNek)
С подписью лично Путина!

тогда точно не годится бебе

О них так поютъ и самое важное с 4:11


AlexNek патриот23.03.24 22:10
AlexNek
NEW 23.03.24 22:10 
в ответ MrSanders 23.03.24 17:51
А как ещё зрителей защитить?

уупс, не подумал смущ

Нужно быть гуманным ко всем.

alex445 патриот25.04.24 01:14
NEW 25.04.24 01:14 
в ответ AlexNek 23.03.24 22:10, Последний раз изменено 25.04.24 01:35 (alex445)

Марают чистый код! Не уважают старичков.


Херово, когда на работу принимают, пытая "сколько мантр из Чистого Кода знаешь?", "а из банды четырёх с кем чалился?", и т.п.



MrSanders коренной житель25.04.24 07:44
NEW 25.04.24 07:44 
в ответ alex445 25.04.24 01:14

Если б кто другой это написал, я бы объяснил. А тебе - бессмысленно.

1 2 3 4 5 6 7 8 9 10 все