Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Подарки от программис'тов

6208   3 4 5 6 7 8 9 10 11 12 13 все
alex445 коренной житель11.04.22 10:15
NEW 11.04.22 10:15 
в ответ Murr 11.04.22 02:32, Последний раз изменено 11.04.22 10:16 (alex445)
А потом всплывает баг
-----
И обрабатывается в том же режиме. Все вполне нормально получается.

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

MrSanders коренной житель11.04.22 12:52
NEW 11.04.22 12:52 
в ответ Murr 11.04.22 02:00

1. Постановщик задачи. Не может / не хочет принимать решения. Описывает задачи максимально обтекаемо.

------

Как вариант - описывает на уровне своего знания/понимания задачи.

Это всегда так. Описывать не на "уровне своего знания" могут не только лишь все, мало кто может это делать. (ц)

Что делает адекватный постановщик задач, когда возникает технический вопрос, на который он не может ответить? Говорит это. Ротом. Мол, ребята, я не знаю что на это ответить. И или

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

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

Для такого надо хотеть брать на себя ответственность и принимать решения. Минимум 2/3 этого делать не хотят, и формулируют требования специально размытыми. Чтобы можно было любой косяк спихнуть на разработчиков. Есть разработчики, которым тоже нравятся размытые требования. Потому что можно нахреновертить что угодно, оправдывая это "а так в требованиях написано".

Murr патриот11.04.22 15:51
Murr
NEW 11.04.22 15:51 
в ответ MrSanders 11.04.22 12:52

Говорит это. Ротом.

-----

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


Это всегда так.

------

Пыхх...

Инструкция по применению Ложки Столовой...

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

Далеко не всегда это уровень его понимания задачи .


проконсультируется с архитектором

------

А толку?

Описанная выше ситуация - она не выдуманная.

Кодеров завязали на постановщика, постановщика - на контактное лицо, а лицо контактировало с никем у заказчика.

Нормальный "испорченный телефон"

Пока не ознакомили кодеров с предметной областью - ничего не двигалось...

alex445 коренной житель25.07.22 10:24
NEW 25.07.22 10:24 
в ответ Murr 11.04.22 15:51, Последний раз изменено 25.07.22 10:26 (alex445)

Кто-нибудь может объяснить, зачем делать такое объявление класса


class A<T> where T : B, new()

{

public T MyProperty

}


если можно сделать сразу свойство типа B


class A

{

public B MyProperty

}


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

alex445 коренной житель25.07.22 10:29
NEW 25.07.22 10:29 
в ответ alex445 25.07.22 10:24, Последний раз изменено 25.07.22 10:32 (alex445)

Это как написать


class A<T1, T2, T3>

where T1 : Int32

where T2 : String

where T3 : String

{

public T1 Age

public T2 Name

public T3 Surname

}


Круто же!

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

Программист коренной житель25.07.22 17:08
NEW 25.07.22 17:08 
в ответ alex445 25.07.22 10:24
Только для того, чтобы потребовать, чтобы у типа B был конструктор без параметров?

А этого мало? :)

AlexNek патриот25.07.22 18:28
AlexNek
NEW 25.07.22 18:28 
в ответ alex445 25.07.22 10:24
если можно сделать сразу свойство типа B

А в дополнение типа С, Д, Е. Вопрос был бы а нужны ли мне в данной реализации "генерики"?

alex445 коренной житель25.07.22 22:17
NEW 25.07.22 22:17 
в ответ Программист 25.07.22 17:08
Только для того, чтобы потребовать, чтобы у типа B был конструктор без параметров?

А этого мало? :)

Это слишком много. Настолько, что можно обойтись и без этого.

alex445 коренной житель25.07.22 22:34
NEW 25.07.22 22:34 
в ответ AlexNek 25.07.22 18:28
А в дополнение типа С, Д, Е. Вопрос был бы а нужны ли мне в данной реализации "генерики"?

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

Wanderer_ завсегдатай25.07.22 23:56
NEW 25.07.22 23:56 
в ответ alex445 25.07.22 10:24
class A where T : B, new(){public T MyProperty}



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

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

Программист коренной житель26.07.22 07:32
NEW 26.07.22 07:32 
в ответ alex445 25.07.22 22:17
Это слишком много. Настолько, что можно обойтись и без этого.

Ну если добавили такое ограничение, значит оно для чего-то нужно :) Например где-то в недрах этого класса создается объект типа B, не важно десериализацией или Activator'ом.

alex445 коренной житель26.07.22 10:35
NEW 26.07.22 10:35 
в ответ Программист 26.07.22 07:32
Ну если добавили такое ограничение, значит оно для чего-то нужно :) Например где-то в недрах этого класса создается объект типа B, не важно десериализацией или Activator'ом.

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

alex445 коренной житель26.07.22 10:37
NEW 26.07.22 10:37 
в ответ alex445 26.07.22 10:35, Последний раз изменено 26.07.22 10:40 (alex445)

Вот ещё один "подарок". В базе данных стоит ограничение на поле nvarchar(40). Где-то в глубине бизнес логики при логировании проверяется длина поля на 40 символов (захардкодено числом), и если больше - обрезается. Я так понимаю, что где-то эта строка может оказаться и больше 40 символов. Почему ещё при её создании она не валидируется на длину? А если в обрезанной части важная инфа? А нельзя было сделать так, чтобы эти ограничения на длину где-то в одном месте сидели и оттуда брались, а не были разбросаны захардкоденным способом по всем частям проекта?


Блин, да там дохрена таких полей. Кусок с логированием - магические чиселки без комментов 40, 12, 36 и т.д. Нумерология! Пока в БД не заглянешь в эти поля, не поймёшь, что это такое. Чел, который писал логирование, похоже тупо со схемы БД руками копировал и никак не обозначил, что они означают.

Программист коренной житель26.07.22 10:51
NEW 26.07.22 10:51 
в ответ alex445 26.07.22 10:35
Как я написал, что если не ставить такое ограничение для параметра типа, то ошибка компиляции возникнет при попытке создания такого объекта внутри этого класса, если конструктора без параметров нет.

Нет, ошибки на этапе компиляции не будет. Исключение будет в рантайм.


Можешь проверить:

    public class TestType
    {
        public int Val { get; private set; }
        public TestType(int val)
        {
            Val = val;
        }
    }

...

Activator.CreateInstance(typeof(TestType));


alex445 коренной житель26.07.22 11:07
NEW 26.07.22 11:07 
в ответ Программист 26.07.22 10:51, Последний раз изменено 26.07.22 11:23 (alex445)

Это подходит только для Активатора и других подобных способов создания объектов в процессе выполнения программы? Т.е. если я работую "обычным" способом - создаю объекты не через динамические механизмы, то всё это мне не нужно?


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

alex445 коренной житель26.07.22 11:08
NEW 26.07.22 11:08 
в ответ alex445 26.07.22 11:07, Последний раз изменено 26.07.22 11:18 (alex445)

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

Программист коренной житель26.07.22 11:39
NEW 26.07.22 11:39 
в ответ alex445 26.07.22 11:07
Это подходит только для Активатора и других подобных способов создания объектов в процессе выполнения программы?

Я с ходу вспомню только 3 способа динамического создания объектов: активатор, взять конструктор через рефлершен (по сути тот же активатор) и десериализация. Во всех 3-х случаях ошибка не будет поймана на стадии компилирования.


Т.е. если я работую "обычным" способом - создаю объекты не через динамические механизмы, то всё это мне не нужно?

Совершенно верно.


Правда, непонятно, почему не использовать банальную сериализацию? Т.е. они откуда-то получают описание типа в XML, но доступа к C# коду описания этого типа не имеют? Супер-секретность, или раздолбайство с невозможностью пошарить библиотеки с описанием типов?

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

Программист коренной житель26.07.22 11:53
NEW 26.07.22 11:53 
в ответ alex445 26.07.22 11:08
Зачем тогда вся эта инкапсуляция, если я могу её легко обойти?

Перед тем как выстрелить себе в колено нужно изучить все детали :)

alex445 коренной житель26.07.22 13:42
NEW 26.07.22 13:42 
в ответ Программист 26.07.22 11:53

В чём прикол делать приватный словарь, а потом публичные методы доступа к нему GetValue и SetValue, которые просто достают данные из словаря и помещают их в него?

alex445 коренной житель26.07.22 14:00
NEW 26.07.22 14:00 
в ответ alex445 26.07.22 13:42, Последний раз изменено 26.07.22 14:09 (alex445)

Ещё такой подарок. В одном месте данное называется FileName. Потом оно передаётся в другое место, и там оно уже - FormName. Далее в третьем месте присваивается - уже SessionState (не спрашивайте про логику названия). Чтобы понять, что состояние сессии в поле таблицы в БД - это на самом деле имя файла формы в проекте - надо перелопатить кучу кода и отследить кучу присваиваний.


Или вот циклическое владение друг другом. Форма имеет ссылку на сессию, а сессия - на форму. Связь 1 к 1. Нахрена?!


И до кучи - специально выделенные строковые поля для имени формы в объекте сессии, и для состояния сессии в объекте формы. С учётом вышесказаного...


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


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

3 4 5 6 7 8 9 10 11 12 13 все