Pull to refresh
224
Алексей@PsyHaSTe

Зигохистоморфирующий

280
Subscribers
Send message

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


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

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


Например?

fn foo(x: Option<i32>) -> i32 {
    match x {
        Some(val) => val   
    }
}

error[E0004]: non-exhaustive patterns: `None` not covered
 --> src/lib.rs:2:11
  |
2 |     match x {
  |           ^ pattern `None` not covered
  |
Почему не выражается? Просто отдельный класс с этими полями,
в основном классе поле, ссылающийся на объект этого класс, помечается как nullable/optional и тому подобное. Плюс на поле навешивается аттрибут "flattern", чтобы ORM действовал как будто вип поля являются частью основного класса.

Если ОРМ это разрешает то так действитлеьно решается. Но по моему опыту подобные "сложные" действия многие ормки даже если заявляют что поддеживают по факту может оказаться иначе. Но да, если можно то так оно работает.


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

Ну то есть ответ на мой вопрос выше "напишем код который кажется правильным а дальше пусть тестировщики ловят"?

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


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


Ничего из этого не является непреодолимым препятствием, но имхо один подход чуть проще другого.

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


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

Ну давайте пример: вам нужно по неочень тривиальной логике (тем не менее она описана бизнесом в какой-нибудь жире) отправлять сообщения пользователю. Типа если не заходил 3 месяца или только один месяц, но подписан на такие-то определение категории, или ещё что-то и то-то. Ну и какие категории порекомендовать тоже спецификация на пару страниц. Как будете релизить такой функционал?

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

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

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


Думаю люди среагировали бы куда мене бурно, если бы эта инфорация была в первом комменте вида "а вы знаели что бд X,Y,Z автоматически это оптимизируют и вам не нужно ничего делать? Вот ссылка на документацию (линк)". Для меня например это была новая информация, спасибо за нее. Впрочем, как я ниже говорил могут быть и другие причины для подобного разделения. В свою очередь считаю что одно из качетв хорошего разработчика — отсутствие категоричности в высказываниях/суждениях.

Ок, а как нам тогда быть если у нас не 1 дополнительное поле, а 3? У нас получается либо 3 нулла, либо они все заполнены — раньше это автоматически энфорсилось правило наличием отдельной таблицы, а в таком подходе как защищаться от запрещенных комбинаций вида "нулл-данные-нулл"? У нас кроме вопроса хранения на диске есть еще вопрос корректности.

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

Тесты это способ описать формально дефинишн оф дан — если логика чуть нетрививальнее чем 2+2 то тупо проще написать тест и озеленить его чем писать код, а потом поднимать все и глазами смотреть что вышло что хотелось. Хотя встречал товарищей, которые считают что их дело кодес написать, а делает ли он что хотелось пусть специально обученные люди смотрят, не про него честь.

Так а зачем вам тесты? Я так понял они только в гуано проектах… Вы же не хотите работать с гуано проектом? Значит и тестов быть не должно

Видели. Вот такой например код из прод кодовой базы:


impl Responder for UpdateResponse {
    type Body = BoxBody;

    fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
        match self {
            UpdateResponse::UpdateSuccess => HttpResponse::Ok().finish(),
            UpdateResponse::UpdateIgnored => HttpResponse::Ok().json("Update ignored"),
            UpdateResponse::UpdateNeedsFullData => HttpResponse::new(StatusCode::IM_A_TEAPOT),
            UpdateResponse::AlreadyUpdating => HttpResponse::new(StatusCode::IM_A_TEAPOT),
        }
    }
}

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


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

остается вопрос зачем нам в базе хранить 10 миллионов нуллов

А вы сами хороший разработчик, верно? Можете спроектировать схему как хранить данные для товарища выше: пяток служебных полей по 32 байта каждая и картинка на 10мб. Как будут хранить это добро в одной таблице разработчики, которые умеют проектировать схему?

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

Так а с чего вы взяли что полиморфизма там нет? Не забывайте что у полиморфизма есть разные измерения — set of objects vs set of features. Поэтому например существует паттерн "визитор", который часто используется в местах иерархией которая редко меняется, но зато функционал часто разный. А визитор это просто switch in disguise по большому счету.


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


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

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

Information

Rating
Does not participate
Registered
Activity