Регистрация  |  Вход

Паттерны в SF

Очень часто работодадеть на собеседовании задает данный вопрос.
Я их особо не знаю. Поэтому у меня предложение, может кто желает рассказать о паттернах которые вы используете на SF, показать пример? Я думаю это будет полезно.

Очень часто работодадеть на собеседовании задает данный вопрос. 
Я их особо не знаю. Поэтому у меня предложение, может кто желает рассказать о паттернах которые вы используете на SF, показать пример? Я думаю это будет полезно. 
https://developer.salesforce.com/page/Apex_Design_Patterns

https://github.com/financialforcedev/fflib-apex-common

Загугли ГОФ паттерны

Загугли ГОФ паттерны
https://trailhead.salesforce.com/en/modules/apex_patterns_sl
https://trailhead.salesforce.com/modules/apex_patterns_dsl

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

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

По себе скажу - я выработал для себя простейшую минимальную схему организации проекта.
Тупо сервис классы со статическими методами с бизнес логикой. Причем SOQL и DML операции сконцентрированы в них же. Это позволяет минимизировать и сконцентрировать код в одном месте и сделать его минимально подогнанным под нужную логику. Все! Никаких больше абстракций. Все лишние абстракции становятся только проблемой в командах с более 1 человеком.

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

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

KISS друзья!

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

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

По себе скажу - я выработал для себя простейшую минимальную схему организации проекта.
Тупо сервис классы со статическими методами с бизнес логикой. Причем SOQL и DML операции сконцентрированы в них же. Это позволяет минимизировать и сконцентрировать код в одном месте и сделать его минимально подогнанным под нужную логику. Все! Никаких больше абстракций. Все лишние абстракции становятся только проблемой в командах с более 1 человеком. 

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

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

[url=https://ru.wikipedia.org/wiki/KISS_(%D0%BF%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF)]KISS[/url] друзья!

Вот тут уже что-то обсуждали похожее
https://salesforce-developer.ru/forum/topic-patterny-proektirovaniya-eto-ogromnaya-trata-vremeni

Вот тут уже что-то обсуждали похожее
https://salesforce-developer.ru/forum/topic-patterny-proektirovaniya-eto-ogromnaya-trata-vremeni

Перефразирую так.

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

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

Перефразирую так. 

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

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

Дима любит много кода, хорошего и одинакогого

Дима любит много кода, хорошего и одинакогого

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

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

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

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

Какие ваши аргументы?

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

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

Какие ваши аргументы?

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

Неее :D уж лушче я напишу лишний SOQL, но буду знать что он вернет мне именно то что я попросил. А не то что захотел вернуть кто-то еще. :D 

Dmitry Shnyrev
Неее уж лушче я напишу лишний SOQL, но буду знать что он вернет мне именно то что я попросил. А не то что захотел вернуть кто-то еще. :D

А если еще вынести этот сокл в сервис/селектор то вообще конфета.

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

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

[quote="Dmitry Shnyrev"]Неее :D уж лушче я напишу лишний SOQL, но буду знать что он вернет мне именно то что я попросил. А не то что захотел вернуть кто-то еще. :D[/quote]
А если еще вынести этот сокл в сервис/селектор то вообще конфета.

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

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

Ну вот подтверждение моих слов.
2 недостатка уже вижу

Maxim Elets
А если еще вынести этот сокл в сервис/селектор то вообще конфета.

Я как раз про это пишу что смысла в этом выносе 0. Лишний класс чтобы собрать все соклы в одном месте. Зачем? Для удобства? Какого? Чтобы можно было реюзать? Я писал выше про реюзать и "проблему с индусами". Чтобы можно было было быстро найти все соклы и внести изменения? Зачем? Я например не хочу чтобы в мои соклы добавляли новые поля если они появились в другой логике.
Maxim Elets
Оптимально иметь чтото свое, маленькое, для конкретной задачи

Опять лишняя абстракция. У каждого будет "свое", как тогда на проектах будем работать вместе? Придется меряться у кого "свое" больше :D.

Блин, хотел еще один живой пример привести, но описание оказалось какое-то сильно запутанное. Попробую потом сформулировать мысль проще.

Одни примеры и примеры!

Где? Где плюсы паттернов?

Ну вот подтверждение моих слов.
2 недостатка уже вижу
[quote="Maxim Elets"]А если еще вынести этот сокл в сервис/селектор то вообще конфета.[/quote]
Я как раз про это пишу что смысла в этом выносе 0. Лишний класс чтобы собрать все соклы в одном месте. Зачем? Для удобства? Какого? Чтобы можно было реюзать? Я писал выше про реюзать и "проблему с индусами". Чтобы можно было было быстро найти все соклы и внести изменения? Зачем? Я например не хочу чтобы в мои соклы добавляли новые поля если они появились в другой логике. 
[quote="Maxim Elets"]Оптимально иметь чтото свое, маленькое, для конкретной задачи[/quote]
Опять лишняя абстракция. У каждого будет "свое", как тогда на проектах будем работать вместе? Придется меряться у кого "свое" больше :D.

Блин, хотел еще один живой пример привести, но описание оказалось какое-то сильно запутанное. Попробую потом сформулировать мысль проще. 

Одни примеры и примеры! :D 

Где? Где плюсы паттернов?

А, да, еще.

Из-за паттернов логи становятся нечитаемыми.
Чтобы использовать лог остается делать только одно.

System.debug(LoggingLevel.ERROR, '...')

и отрубить к херам все выводы кроме ошибок.

А помню раньше были времена - читали логи. Реально читали!!!

А, да, еще. 

Из-за паттернов логи становятся нечитаемыми.
Чтобы использовать лог остается делать только одно.

System.debug(LoggingLevel.ERROR, '...')

и отрубить к херам все выводы кроме ошибок.

А помню раньше были времена - читали логи. Реально читали!!!

Хороший пример использования ООП это Unit of Work (та же реализация в fflib), представь тебе нужно заинсерить n (n > 2) связанных объектов ещё и в балке (логика в триггере). Старый добрый способ - инсертить всё по очереди, сохранив перед этим свои связи в мапах (куча мап так как нет Id ещё у новых записей). В итоге код превращается в манипуляции с мапами и заполнению Ids.

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

Хороший пример использования ООП это Unit of Work (та же реализация в fflib), представь тебе нужно заинсерить n (n > 2) связанных объектов ещё и в балке (логика в триггере). Старый добрый способ - инсертить всё по очереди, сохранив перед этим свои связи в мапах (куча мап так как нет Id ещё у новых записей). В итоге код превращается в манипуляции с мапами и заполнению Ids.

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

Домен паттерн с одним хендлером на триггер - тоже огромный плюс

Домен паттерн с одним хендлером на триггер - тоже огромный плюс

Опять же повторюсь.
Сказывается моя специфика работы на консалтинговые компании.
Проектов много, проекты всегда шли на потоке.
Городить "супер" проекты нет не времени ни желания.
Копаться в чужих "супер" наработках тоже не всегда удается, проще написано самому с нуля.
Были пару продуктовых проектов, да там были использованы все современные подходы к разработке в SF. Но за этим следили и не давали возможности уйти вправо влево. Но и разработка замедлилась в разы. Если сейчас на разработку одной полноценной страницы отводят максимум неделю, а обычно 2 дня. То там 1 страница пилилась несколько месяцев.

Опять же повторюсь. 
Сказывается моя специфика работы на консалтинговые компании.
Проектов много, проекты всегда шли на потоке.
Городить "супер" проекты нет не времени ни желания.
Копаться в чужих "супер" наработках тоже не всегда удается, проще написано самому с нуля.
Были пару продуктовых проектов, да там были использованы все современные подходы к разработке в SF. Но за этим следили и не давали возможности уйти вправо влево. Но и разработка замедлилась в разы. Если сейчас на разработку одной полноценной страницы отводят максимум неделю, а обычно 2 дня. То там 1 страница пилилась несколько месяцев.

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

Полностью согласен с Димой. Чем проще, тем лучше.

Да, может когда пилят какие-то большие решение, которые могут настраиваться пользоватеми вдоль и поперек, там это надо. Для пакетов, продаваемых на AppExchange.
А когда одному клиенту делать уникальную бизнес логику... врятли. Особенно разбираться в этом без IDE. Тебя проклянут на всю оставщуюся жизнь :-)

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

Полностью согласен с Димой. Чем проще, тем лучше.

Да, может когда пилят какие-то большие решение, которые могут настраиваться пользоватеми вдоль и поперек, там это надо. Для пакетов, продаваемых на AppExchange.
А когда одному клиенту делать уникальную бизнес логику... врятли. Особенно разбираться в этом без IDE. Тебя проклянут на всю оставщуюся жизнь :-)

Пишите как хотите, дело ваше и наше

Всё равно никто никого не переубедит, вечный холивар :D

Пишите как хотите, дело ваше и наше :)

Всё равно никто никого не переубедит, вечный холивар :D

Ну вот наконец-то поперли аргументы. Дима, спасибо.

Dmitry Lisovsky
C UOW ты просто закидываешь всё внутрь, прописываешь релейшны и делаешь коммит одной транзакцией, все обёъкты свяжет UOW.

Согласен с UOW удобнее сохранять связанные данные. Но это не всегда нужно. И эту логику можно просто вынести в хелпер метод. А я видел как UOW заставляли использовать просто везде. Нахера? Ну чтобы каждый раз когда надо написать просто DML нужно было лезть в глобальный поиск чтобы найти и скопипастить 10 строк кода инициализации и правильного вызова UOW. Не всегда он нужен. Но если он будет в качестве хелпера почему бы и нет (хотя я сильный поклонник мапов - с тех пор как я научился их использовать я готов им памятник поставить )

Dmitry Lisovsky
Домен паттерн с одним хендлером на триггер - тоже огромный плюс

Вот тут хотелось бы узнать что за плюс. Единственный плюс что я вижу - это добавление глобальной логики в виде отключения всех триггеров в одном месте. Но это можно сделать и простой вставкой 1 строки вызова метода из всех триггеров. Зато не надо разбираться с тем как этот триггер хендлер использовать. Я уже видел 100500 вариантов триггер хендлеров и каждый раз приходилось тратить время на изучение реализации. По мне проще сделать 100 классических триггеров и добавить по 1-й строчке вначале для вызова общей мега логики (которую я кстати ни разу не видел на реальных проектах) чем делать триггер по шаблону (копипаст) + делать хендлер (копипаст) который наследует какой-то там абстрактный класс, который надо изучить чтобы понять как там мля параметры хранятся и используются.

Но за мнение спасибо

Ну вот наконец-то поперли аргументы. Дима, спасибо. 

[quote="Dmitry Lisovsky"]C UOW ты просто закидываешь всё внутрь, прописываешь релейшны и делаешь коммит одной транзакцией, все обёъкты свяжет UOW.[/quote]
Согласен с UOW удобнее сохранять связанные данные. Но это не всегда нужно. И эту логику можно просто вынести в хелпер метод. А я видел как UOW заставляли использовать просто везде. Нахера? Ну чтобы каждый раз когда надо написать просто DML нужно было лезть в глобальный поиск чтобы найти и скопипастить 10 строк кода инициализации и правильного вызова UOW. Не всегда он нужен. Но если он будет в качестве хелпера почему бы и нет (хотя я сильный поклонник мапов - с тех пор как я научился их использовать я готов им памятник поставить :D )

[quote="Dmitry Lisovsky"]Домен паттерн с одним хендлером на триггер - тоже огромный плюс[/quote]
Вот тут хотелось бы узнать что за плюс. Единственный плюс что я вижу - это добавление глобальной логики в виде отключения всех триггеров в одном месте. Но это можно сделать и простой вставкой 1 строки вызова метода из всех триггеров. Зато не надо разбираться  с тем как этот триггер хендлер использовать. Я уже видел 100500 вариантов триггер хендлеров и каждый раз приходилось тратить время на изучение реализации. По мне проще сделать 100 классических триггеров и добавить по 1-й строчке вначале для вызова общей мега логики (которую я кстати ни разу не видел на реальных проектах) чем делать триггер по шаблону (копипаст) + делать хендлер (копипаст) который наследует какой-то там абстрактный класс, который надо изучить чтобы понять как там мля параметры хранятся и используются.

Но за мнение спасибо :) 


Andrii Muzychuk
Тебя проклянут на всю оставщуюся жизнь :-)

+100

[quote="Andrii Muzychuk"]Тебя проклянут на всю оставщуюся жизнь :-)[/quote]
+100 :D 

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

Понятно что для инсерта 2х объектов совсем нет необходимости в UOW, но когда это 5 листов и создание объектов происходит с разными условиями (что-то создавать, что-то нет) тут уже UOW выручает в скорости разработки и удобстве чтения кода.

По триггерам, можно кучу проблем поиметь с множеством триггеров на объекте как и с кучей вложенных if (isInsrer), if(isBefore) и тд.

Триггер хендлер даёт тебе простой интерфейс

public override void onBeforeInsert(){
// call service class
}

public override void onAfterUpdate(){
// call service class
}

Здесь вызывайте сервис методы и всё будет хорошо, в сервис метод ещё и UOW подаёте и получаете один коммит на триггер.


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


Если бы ООП был таким не нужным никто бы не загонялся с языками программирования, писали бы до сих пор на ассемблере, так же проще

Вы ведь сами не замечаете, что используете ООП каждый день - тот же полиморфизм для DML операций, так бы писали свою реализацию инсерта/апдейта на каждый кастомный объект.

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

Понятно что для инсерта 2х объектов совсем нет необходимости в UOW, но когда это 5 листов и создание объектов происходит с разными условиями (что-то создавать, что-то нет) тут уже UOW выручает в скорости разработки и удобстве чтения кода.

По триггерам, можно кучу проблем поиметь с множеством триггеров на объекте как и с кучей вложенных if (isInsrer), if(isBefore) и тд. 

Триггер хендлер даёт тебе простой интерфейс

[code]
public override void onBeforeInsert(){
// call service class
}

public override void onAfterUpdate(){
// call service class
}
[/code]

Здесь вызывайте сервис методы и всё будет хорошо, в сервис метод ещё и UOW подаёте и получаете один коммит на триггер.


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


Если бы ООП был таким не нужным никто бы не загонялся с языками программирования, писали бы до сих пор на ассемблере, так же проще :D 

Вы ведь сами не замечаете, что используете ООП каждый день - тот же полиморфизм для DML операций, так бы писали свою реализацию инсерта/апдейта на каждый кастомный объект.

То что мы используем ООП каждый день это понятно. Все такие Apex это Java, а Java это чисто ООП язык.
Холивар сводится к тому чтобы использовать apex на низком уровне - так сказать в соотвествии с документацией или еще до кучи использовать паттерны проектирования.
Я за простоту кода. Я согласен с использованием сторонних либ, но это должно быть ненавязчево, в качестве помощи - по принципу надо используй, не надо не используй.
А есть люди которые не начнут работать пока построят структуру проекта на основе современного паттерна проектирования с навязыванием этой структуры другим разработчикам.
Тут наверное fflib стоит на острие ножа. С одной стороны эта либа, которую можно использовать в качестве хелпера для улучшения и ускорения разработки. А можно возвести ее в ранг паттерна проектирования и пихать в каждую дырку по типу "никаких дмл операций и соклов в коде". Вот тут уже надо смотреть что получается.

То что мы используем ООП каждый день это понятно. Все такие Apex это Java, а Java это чисто ООП язык.
Холивар сводится к тому чтобы использовать apex на низком уровне - так сказать в соотвествии с документацией или еще до кучи использовать паттерны проектирования. 
Я за простоту кода. Я согласен с использованием сторонних либ, но это должно быть ненавязчево, в качестве помощи - по принципу надо используй, не надо не используй. 
А есть люди которые не начнут работать пока построят структуру проекта на основе современного паттерна проектирования с навязыванием этой структуры другим разработчикам. 
Тут наверное fflib стоит на острие ножа. С одной стороны эта либа, которую можно использовать в качестве хелпера для улучшения и ускорения разработки. А можно возвести ее в ранг паттерна проектирования и пихать в каждую дырку по типу "никаких дмл операций и соклов в коде". Вот тут уже надо смотреть что получается.

Вот выше привели в качестве примера

https://habrahabr.ru/post/210288/

Что вы используете или думаете что используете?

Вот выше привели в качестве примера

https://habrahabr.ru/post/210288/

Что вы используете или думаете что используете?

Dmitry Shnyrev
Что вы используете или думаете что используете?

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

[quote="Dmitry Shnyrev"]Что вы используете или думаете что используете?[/quote]
Давайте реально общими силами найдем общий вариант которые можно использовать под SF.
А то я заглянул и у меня глаза прям разбежались - что лучше, что нужно использовать?
[img]https://habrastorage.org/getpro/habr/post_images/349/055/ba9/349055ba96e21b43c7d3e506d4920bc8.jpg[/img]

Мне довольно трудно понять по абстракному описанию паттерна, как его использовать.
Я предлагаю написать не только паттерн который вы используете, а пример его реализации на SF.

Мне довольно трудно понять по абстракному описанию паттерна, как его использовать.
Я предлагаю написать не только паттерн который вы используете, а пример его реализации на SF.

Кстати вот от нефиг делать замутил маленький аналог fflib в котором есть только то что мне действительно нужно:
Unit of Work
Query Factory

Заняло минимально времени.
Надо будет затестить что быстрее работает по времени.
CRUD через мою или через ффлиб

Кстати вот от нефиг делать замутил маленький аналог fflib в котором есть только то что мне действительно нужно:
Unit of Work
Query Factory

Заняло минимально времени.
Надо будет затестить что быстрее работает по времени.
CRUD через мою или через ффлиб

Давай делись ссылкой на гитхаб, может чего-нибудь допилим ещё :)

Давай делись ссылкой на гитхаб, может чего-нибудь допилим ещё :)

Dmitry Lisovsky
Давай делись ссылкой на гитхаб, может чего-нибудь допилим ещё :)

я слишком стеснителен делиться моим говнокодом Но мысля такая возникала и я обязательно поделюсь как проведу свои тесты :)

[quote="Dmitry Lisovsky"]Давай делись ссылкой на гитхаб, может чего-нибудь допилим ещё :)[/quote]
я слишком стеснителен делиться моим говнокодом :) Но мысля такая возникала и я обязательно поделюсь как проведу свои тесты :)

Maxim Elets
я слишком стеснителен делиться моим говнокодом

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

[quote="Maxim Elets"]я слишком стеснителен делиться моим говнокодом[/quote]
Вот это есть плохо. Все говнокодят по разному. И не надо считать что ты самый худший. Github должен быть обязательно и туда непременно надо кидать хоть что-нибудь.

Maxim Elets
я слишком стеснителен делиться моим говнокодом

Делиться обязательно! Так хоть можно какой полезный фидбек получить, вот мне не жалко своего говнокода, буду рад любым комментариям https://github.com/dlisovsky

[quote="Maxim Elets"]я слишком стеснителен делиться моим говнокодом[/quote]

Делиться обязательно! Так хоть можно какой полезный фидбек получить, вот мне не жалко своего говнокода, буду рад любым комментариям https://github.com/dlisovsky

Maxim Elets
Кстати вот от нефиг делать замутил маленький аналог fflib в котором есть только то что мне действительно нужно:
Unit of Work
Query Factory

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

Кстати - вот комментарий из fflib :

* This class is not meant to be used as a replacement for all SOQL queries, and due to the relativley high overhead in both CPU and describe calls 
* should be used in places where highly dynamic queries, such as those that include field sets or are mutated heavilly
* in multiple locations are a good fit for use with fflib_QueryFactory.

[quote="Maxim Elets"]Кстати вот от нефиг делать замутил маленький аналог fflib в котором есть только то что мне действительно нужно:
Unit of Work
Query Factory
[/quote]

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

Кстати - вот комментарий из [url=https://github.com/yurybond/fflib-apex-common/blob/master/fflib/src/classes/fflib_QueryFactory.cls]fflib[/url] :
[code] * This class is not meant to be used as a replacement for all SOQL queries, and due to the relativley high overhead in both CPU and describe calls 
 * should be used in places where highly dynamic queries, such as those that include field sets or are mutated heavilly
 * in multiple locations are a good fit for use with fflib_QueryFactory.[/code]

yurybond
Поясни зачем нужен вообще query factory - я месяц-два назад дрался с коллегой на шпагах чтобы этих пережитков жавы в нашем коде не было.

ну лично мне нравится компактность, возможность настроить списки филдов для селекта и каждый раз просто указывать .selectFields(fromList) вместо тонны повторяющихся строк

[quote="yurybond"]Поясни зачем нужен вообще query factory - я месяц-два назад дрался с коллегой на шпагах чтобы этих пережитков жавы в нашем коде не было.[/quote]
ну лично мне нравится компактность, возможность настроить списки филдов для селекта и каждый раз просто указывать .selectFields(fromList) вместо тонны повторяющихся строк

Maxim Elets
каждый раз просто указывать .selectFields(fromList)

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

[quote="Maxim Elets"]каждый раз просто указывать .selectFields(fromList)[/quote]
Насколько я могу судить, то наборы необходимых филдов в каждом запросе разные.
И под каждый запрос строить свой FieldsList?
А если нужно часто повторять один и тот же запрос, то может проще вынести его в отдельный метод?
Я понимаю про что ты говоришь, но реально за всю карьеру не сталковался с тем чтобы это было реально необходимо.
Сразу с ходу скажу какой минус - лишний оверхед при чтении кода. Запрос получается "размазанный" по проекту. Пойди еще найди этот самый FieldsList и после того как найдешь и запомнишь вернись обратно на строчку запроса. Код усложнился и следовательно усложнилось время на его поддержку.

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

class01 {
Set<String> method01RequiredFields;
public static method01(List<Account> accList) {...}
}

class02 {
...
List<Account> accList = [SELECT Name, QQQ__c Account];
Class01.method01(accList);
...
}

class03 {
...
List<Account> accList = [SELECT Name, QQQ__c, ZZZ__c Account];
Class01.method01(accList);
...
}

И вот ты в метод method01 добавляешь обработку поля EEE__c.

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

class01 {
Set<String> method01RequiredFields;
public static method01(List<Account> accList) {...}
}

class02 {
...
List<Account> accList = [SELECT Name, QQQ__c Account];
Class01.method01(accList);
...
}

class03 {
...
List<Account> accList = [SELECT Name, QQQ__c, ZZZ__c Account];
Class01.method01(accList);
...
}

И вот ты в метод method01 добавляешь обработку поля EEE__c.

Dmitry Shnyrev
И под каждый запрос строить свой FieldsList?

Делается так сказать defaultFields лист.
А потом => .selectFields(defaultFields).selectFields(Account.JOPA).selectFields(Account.POPA)

[quote="Dmitry Shnyrev"]И под каждый запрос строить свой FieldsList? [/quote]
Делается так сказать defaultFields лист.
А потом => .selectFields(defaultFields).selectFields(Account.JOPA).selectFields(Account.POPA)

Andrii Muzychuk
Дима, самый простой пример, где я бы такой подход использовал (список вычитываемых полей) это когда у тебя метод вызывается из разных мест, а в тех разных местах свои SOQL. Так вот если ты в этом методе добавляешь обработку нового поля, то это поле надо добавить во всех SOQL, которые вытягивают данные для этого метода в разных местах.
А так у тебя для этого метода есть список полей. Ты этот список добавляешь в список полей, где вызывается этот метод. И получается, когда добавляешь обработку нового поля, надо добавить это поле только в списке, который относится к этому методу, а не во всех его вызовах, да еще пойди найди где эти SOQL.

class01 {
Set<String> method01RequiredFields;
public static method01(List<Account> accList) {...}
}

class02 {
...
List<Account> accList = [SELECT Name, QQQ__c Account];
Class01.method01(accList);
...
}

class03 {
...
List<Account> accList = [SELECT Name, QQQ__c, ZZZ__c Account];
Class01.method01(accList);
...
}

И вот ты в метод method01 добавляешь обработку поля EEE__c.

Все так

[quote="Andrii Muzychuk"]Дима, самый простой пример, где я бы такой подход использовал (список вычитываемых полей) это когда у тебя метод вызывается из разных мест, а в тех разных местах свои SOQL. Так вот если ты в этом методе добавляешь обработку нового поля, то это поле надо добавить во всех SOQL, которые вытягивают данные для этого метода в разных местах.
А так у тебя для этого метода есть список полей. Ты этот список добавляешь в список полей, где вызывается этот метод. И получается, когда добавляешь обработку нового поля, надо добавить это поле только в списке, который относится к этому методу, а не во всех его вызовах, да еще пойди найди где эти SOQL.

class01 {
Set<String> method01RequiredFields;
public static method01(List<Account> accList) {...}
}

class02 {
...
List<Account> accList = [SELECT Name, QQQ__c Account];
Class01.method01(accList);
...
}

class03 {
...
List<Account> accList = [SELECT Name, QQQ__c, ZZZ__c Account];
Class01.method01(accList);
...
}

И вот ты в метод method01 добавляешь обработку поля EEE__c.[/quote]

Все так

Andrii Muzychuk
Так вот если ты в этом методе добавляешь обработку нового поля, то это поле надо добавить во всех SOQL, которые вытягивают данные для этого метода в разных местах

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

[quote="Andrii Muzychuk"]Так вот если ты в этом методе добавляешь обработку нового поля, то это поле надо добавить во всех SOQL, которые вытягивают данные для этого метода в разных местах[/quote]
Вот это самый ошибочный пример. Я уже устал говорить - зачем? Зачем добавлять поле во все SOQL? Понимаю еще убрать/изменить во всех SOQL. Но добавлять зачем? Если ты где-то на своей странице будешь использовать новое поле с новой логикой. Зачем мне добавлять его в свои запросы если я его использовать не буду? 

Как и ошибка вытягивать абсолютно все поля. Видел такое тоже часто - типа селектор для sObject который динамически вытягивает все поля из метадаты и потом их подставляет в SOQL. Зачем так делать?

Как и ошибка вытягивать абсолютно все поля. Видел такое тоже часто - типа селектор для sObject который динамически вытягивает все поля из метадаты и потом их подставляет в SOQL. Зачем так делать?

в моем понимании все "СФ" паттерны можно условно разделить на три группы:

(1) Собственно именно СФ паттерны, обычно их называют Best Practices. Они касаются вещей специфичных для SaaS and PaaS таких как например лимиты и батч-операции. Знание данных СФ Best Practices критически важно, и по-сути и отличает СФ програмиста ото всех других програмистов.

(2) Паттерны направленные на улучшение архитектуры приложения, разделение кода на layers. К ним я например отношу концепцию Триггер-коммутатор и севис классы его обслуживающие. Важно иметь хотя бы представляние о них, так как они важны и используюся в мало-мальских приличных приложениях, и не только в СФ;

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

По моему мнению классические паттерны активно используется в СФ в некоторых случаях, например в продуктовых компаниях, которые годами пилят один и тот же продукт, доводя его до совершенства (в плане гибкости и расширяемости, например). Им это надо. Или если програмист-"тертый калач" годами сидит на одном клиенте, и он знает, что если клиент попросил его сделать "ключ на 10", это на самом деле может значит, что им нужен ключ на 11, или через полгода на 12, и в таком случае програмист сегодня тратит немного больше своего времени, чтобы заметно съекономить позже: он пишет "ключ со сменной головкой" и к нему инъекцией вставляет "головку на 10". И если завтра его попросят "ключ на 12", он быстро напишет "головку на 12" и все готово.

в моем понимании все "СФ" паттерны можно условно разделить на три группы:

(1) Собственно именно [b]СФ[/b] паттерны, обычно их называют Best Practices. Они касаются вещей специфичных для SaaS and PaaS таких как например лимиты и батч-операции. Знание данных СФ Best Practices критически важно, и по-сути и отличает СФ програмиста ото всех других програмистов.

(2) Паттерны направленные на улучшение архитектуры приложения, разделение кода на layers. К ним я например отношу концепцию Триггер-коммутатор и севис классы его обслуживающие. Важно иметь хотя бы представляние о них, так как они важны и используюся в мало-мальских приличных приложениях, и не только в СФ;

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

По моему мнению классические паттерны активно используется в СФ в некоторых случаях, например в продуктовых компаниях, которые годами пилят один и тот же продукт, доводя его до совершенства (в плане гибкости и расширяемости, например). Им это надо. Или если програмист-"тертый калач" годами сидит на одном клиенте, и он знает, что если клиент попросил его сделать "ключ на 10", это на самом деле может значит, что им нужен ключ на 11, или через полгода на 12, и в таком случае програмист сегодня тратит немного больше своего времени, чтобы заметно съекономить позже: он пишет "ключ со сменной головкой" и к нему инъекцией вставляет "головку на 10". И если завтра его попросят "ключ на 12", он быстро напишет "головку на 12" и все готово.





Dmitry Shnyrev
Зачем добавлять поле во все SOQL?
Это же очевидно - чтоб использовать значение этого поля в бизнес-логике. А че его еще вытягивать?
Dmitry Shnyrev
Зачем мне добавлять его в свои запросы если я его использовать не буду?
Если не будешь - не надо. Но я ж тебе пример показал, где это делать надо.

[quote="Dmitry Shnyrev"]Зачем добавлять поле во все SOQL? [/quote] Это же очевидно - чтоб использовать значение этого поля в бизнес-логике. А че его еще вытягивать?
[quote="Dmitry Shnyrev"]Зачем мне добавлять его в свои запросы если я его использовать не буду?[/quote]Если не будешь - не надо. Но я ж тебе пример показал, где это делать надо.

Dmitry Shnyrev
Как и ошибка вытягивать абсолютно все поля. Видел такое тоже часто - типа селектор для sObject который динамически вытягивает все поля из метадаты и потом их подставляет в SOQL. Зачем так делать?
Мне кажется, в большинстве случаев не надо. Но, например, для клонирования приходится вычитывать все поля, которые хочешь склонировать, ибо клонируется объект в коде, а не запись в БД.

[quote="Dmitry Shnyrev"]Как и ошибка вытягивать абсолютно все поля. Видел такое тоже часто - типа селектор для sObject который динамически вытягивает все поля из метадаты и потом их подставляет в SOQL. Зачем так делать?[/quote]Мне кажется, в большинстве случаев не надо. Но, например, для клонирования приходится вычитывать все поля, которые хочешь склонировать, ибо клонируется объект в коде, а не запись в БД.

У меня, кстати, есть метод, который возвращает список Opportunity со всеми полями. Мне это надо для клонирования. Но я его никогда не использовал для вычитывания списков с каким-то набором полей.
Хотя, интересная идея. Надо ее воплощать.

У меня, кстати, есть метод, который возвращает список Opportunity со всеми полями. Мне это надо для клонирования. Но я его никогда не использовал для вычитывания списков с каким-то набором полей.
Хотя, интересная идея. Надо ее воплощать.

Andrii Muzychuk
Если не будешь - не надо. Но я ж тебе пример показал, где это делать надо.

Хорошо. У меня сложная страница со сложным Remote Action работающий на пределе лимита в 3 метра. Ты добавляешь поле LongTextArea во все запросы и оно включается в мой общий ответ. Оно мне нафиг не нужно на странице, но моя страница перестает работать. Блин, даже чего далеко ходить - классическая страница VF с View State. И тут лимит куда меньше 3 метров. А то что выборка лишних полей создает нагрузку на базу данных!? (ну SF программистов это меньше всего волнует )

[quote="Andrii Muzychuk"]Если не будешь - не надо. Но я ж тебе пример показал, где это делать надо.[/quote]
Хорошо. У меня сложная страница со сложным Remote Action работающий на пределе лимита в 3 метра. Ты добавляешь поле LongTextArea во все запросы и оно включается в мой общий ответ. Оно мне нафиг не нужно на странице, но моя страница перестает работать. Блин, даже чего далеко ходить - классическая страница VF с View State. И тут лимит куда меньше 3 метров. А то что выборка лишних полей создает нагрузку на базу данных!? (ну SF программистов это меньше всего волнует :) ) 

Andrii Muzychuk
Мне кажется, в большинстве случаев не надо. Но, например, для клонирования приходится вычитывать все поля,

Ну так я ж не говорю про частный случай. Я тебе говорю про глобальную замену всех стандартных SOQL вот такой вот доменной моделью с кастомными селекторами. Когда ты хочешь получить только Id + Name а тебе возвращают все 100500 полей которые вообще существуют в объекте.

[quote="Andrii Muzychuk"]Мне кажется, в большинстве случаев не надо. Но, например, для клонирования приходится вычитывать все поля, [/quote]
Ну так я ж не говорю про частный случай. Я тебе говорю про глобальную замену всех стандартных SOQL вот такой вот доменной моделью с кастомными селекторами. Когда ты хочешь получить только Id + Name а тебе возвращают все 100500 полей которые вообще существуют в объекте.

Dmitry Shnyrev
Когда ты хочешь получить только Id + Name а тебе возвращают все 100500 полей которые вообще существуют в объекте.

Это не выдумка, а пример из реальной жизни.

[quote="Dmitry Shnyrev"]Когда ты хочешь получить только Id + Name а тебе возвращают все 100500 полей которые вообще существуют в объекте.[/quote]
Это не выдумка, а пример из реальной жизни.

Дима, я так понимаю, в этом же и прелесть этого паттерна, что на страницу у тебя один список полей, а для бизнес-логики другой. У на страницу ты Id, Name вычитываешь, а в бизнес-логику все 100500 полей.

Дима, я так понимаю, в этом же и прелесть этого паттерна, что на страницу у тебя один список полей, а для бизнес-логики другой. У на страницу ты Id, Name вычитываешь, а в бизнес-логику все 100500 полей.

Andrii Muzychuk
что на страницу у тебя один список полей, а для бизнес-логики другой. У на страницу ты Id, Name вычитываешь, а в бизнес-логику все 100500 полей.

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

Добавить новое поле точечно в нужный запрос так же просто как добавить поле в fieldSet или в query builder. Заодно такой подход стимулирует разработчика делать это осознанно в каждом месте бизнес логики где это необходимо и после этого проверять/тестировать. В отличии от того что ты добавить новое поле где-нибудь в классе селекторе и потом будешь "надеяться" что оно заработает везде. Про надеяться увы знаю не понаслышке - программисты в основной своей массе ленивый народ и я просто уверен что вся проверка изменений закончится на тестровании одного лишь юзкейса, а остальные будут просто по умолчанию приняты за рабочие (собственно для этого и придумываются всякие паттерны проектирования - чтобы облегчить жизнь программистов )

[quote="Andrii Muzychuk"]что на страницу у тебя один список полей, а для бизнес-логики другой. У на страницу ты Id, Name вычитываешь, а в бизнес-логику все 100500 полей.[/quote]
Вот тут не понял. Я страницы и бизнес логику не разделяю. Для меня это одно целое. Я просто веду к тому что лично я против того чтобы из базы доставалась лишняя информация (доставались лишние поля). ВСЕ! Я считаю это крайне негативным фактором в архитектуре приложения. И пока что не вижу чем лишняя информация из базы данных может оправдать использование какого либо паттерна проектирования.

Добавить новое поле точечно в нужный запрос так же просто как добавить поле в fieldSet или в query builder. Заодно такой подход стимулирует разработчика делать это осознанно в каждом месте бизнес логики где это необходимо и после этого проверять/тестировать. В отличии от того что ты добавить новое поле где-нибудь в классе селекторе и потом будешь "надеяться" что оно заработает везде. Про надеяться увы знаю не понаслышке - программисты в основной своей массе ленивый народ и я просто уверен что вся проверка изменений закончится на тестровании одного лишь юзкейса, а остальные будут просто по умолчанию приняты за рабочие (собственно для этого и придумываются всякие паттерны проектирования - чтобы облегчить жизнь программистов :D ) 

Ну, а я разделяю. У меня на странице нет бизнес-логики. Она вся в контроллере.
Еще раз.
Не надо все поля вычитывать. Надо только те, что нужны. И этот паттерн, как я понимаю, в этом и помогает. Я так понимаю, что вычитываются как раз только те поля, которые используются бизнес-логикой. Добавил новое поле в методе - добавил его в список используемых полей. Убрал из метода - убрал из списка.
Кстати, вспомнил когда мне бы помог этот паттерн.
Идет каскад вызовов, и список передается в 100й вызов, в котором ты добавил новое поле. Проверку поставил. И ищи птм, где ж этот список вычитывается.

Ну, а я разделяю. У меня на странице нет бизнес-логики. Она вся в контроллере.
Еще раз.
Не надо все поля вычитывать. Надо только те, что нужны. И этот паттерн, как я понимаю, в этом и помогает. Я так понимаю, что вычитываются как раз только те поля, которые используются бизнес-логикой. Добавил новое поле в методе - добавил его в список используемых полей. Убрал из метода - убрал из списка.
Кстати, вспомнил когда мне бы помог этот паттерн.
Идет каскад вызовов, и список передается в 100й вызов, в котором ты добавил новое поле. Проверку поставил. И ищи птм, где ж этот список вычитывается.

Тема опять превращается в холивал.
Мне дак не удобно читать код, если вся логика написана в одном методе, намного приятнее код смотрится, когда он разнесен на несколько методов по 10-15 строк.

Тема опять превращается в холивал.
Мне дак не удобно читать код, если вся логика написана в одном методе, намного приятнее код смотрится, когда он разнесен на несколько методов по 10-15 строк.

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

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

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

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

Gres
Использовать или нет какие-то паттерны дело каждого конкретного разработчика и команды

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

[quote="Gres"]Использовать или нет какие-то паттерны дело каждого конкретного разработчика и команды[/quote]
Ну я бы как раз хотел повернуть это в обратную сторону, в пользу для всех.
Если это будет делом каждого отдельного разработчика, то так и будут случаться холивары. Хорошо когда они будут случаться тут на страницах форума, но хуже если на страницах исходного кода проекта.
Почему я приглашаю всех поделиться своими best practice. 
Будет классно найти общий подход, узнать кто чем живет. 
Разработчики иногда переходят из компаний в компании, из комманд в комманды. 
И может завтра кто-нибудь отсюда придет в твою команду, Gres. А ты даже ни слова не написал что вы используете  в проектах, а компания у вас вроде не маленькая и проектов не один. 
Поделись информацией как ты организовываешь структуру проекта. Какие паттерны используешь.

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

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

[quote="Gres"]А вот знание самих паттернов и подходов к проектированию архитектуры приложения говорит об уровне разработчика.[/quote]
Согласен, что теоретические знания важны. Но вот в тех компаниях где я работал, важнее как будут решаться практические вопросы. Да и теоретические знания имеют свойство быстро забываться без практики.

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

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

одна контора (большая, я сказал бы куда да NDA подписывал перед интервью) задала толковый вопрос :
интервьювер - паттерны распределения лидов у нас хранятся в обьекте по типу region:user, лиды распределяются и на апдейте и на инсерте, в одном контексте происходит и инсерт и апдейт, как сделать чтобы SOQL на паттерны был сделан один раз
я - синглтон
интервьювер - а напиши этот синглтон

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

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

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

одна контора (большая, я сказал бы куда да NDA подписывал перед интервью) задала толковый вопрос : 
интервьювер - паттерны распределения лидов у нас хранятся в обьекте по типу region:user, лиды распределяются и на апдейте и на инсерте, в одном контексте происходит и инсерт и апдейт, как сделать чтобы SOQL на паттерны был сделан один раз
я - синглтон
интервьювер - а напиши этот синглтон

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