• Есть ли сервис по типу Upwork, но без заказов и фрилансеров?

    DmitriyEntelis
    @DmitriyEntelis
    Думаю за деньги
    Называется - слетайте и откройте свою компанию.
    Или откройте ООО в РФ и выставляйте англоязычные инвойсы - оплата без проблем проходит, тут куча обсуждений этого есть.
    И как вообще называется такой сервис, когда какая-то компания для тебя делает проводку платежей с бухгалтерией, уплатой налогов, подписанием контрактов, и все от своего имени.
    называется shell company :-D шучу конечно, не могу представить кто этим будет заниматься в таком формате. Риски сумасшедшие, профит не очевиден.
    Ответ написан
    3 комментария
  • Как правильно писать на ООП?

    TLDR: Все зависит от ситуации. Набивайте свои шишки и наберетесь опыта.

    Самый главный вопрос - зачем вы вообще хотите использовать ООП, насколько сложный и "правильный", какие цели хотите достичь.

    Когда разрабатываете библиотеку, то есть несколько важных целей (независимо от парадигмы):
    1. Апи должнен быть простым, понятным и самодокументируемым
    2. Вы должны иметь возможность развивать библиотеку и не нарушать при этом уже используемый пользователями API

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

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

    Не слушайте евангелистов ФП - сейчас в JS функциональностью модно прикрывать говнокод.

    Так же не слушайте тех, которые на каждом углу кричат "Composition over inheritance", "Banana monkey problem" другие страшные термины. В своем религиозном угаре они забывают, что все эти принципы рекомендации для определенных ситуаций. Да, иногда (в большинстве случаев на самом деле) композиция значительно лучше наследования, очень часто стыкаешься с ситуацией, что наследование применено не в тему и из-за этого усложнено развитие. Но иногда наследование - правильный путь и пока сами не набъете шишек - будет крайне сложно понять разницу. Помогает принцип is-a/has-a. И я видел код отличных программистов, где наследование было применено так, что значительно разгрузило API и упростило код. Не зацикливайтесь из-за религиозных фанатиков.

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

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

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

    interface IPipeline {
    	ResultView Render (RawData rawData);
    }
    
    class Pipeline : IPipeline {
    	protected virtual ParsedRawData ParseRawData(RawData rawData) {
    		return new DataParser(rawData).GetParsedData();
    	}
    	
    	protected virtual ActualData GetActualData (ParsedRawData rawData) {
    		return new HttpRequest(rawData.src);
    	}
    	
    	protected virtual ResultState GetResultState (RawData rawData, ActualData actualData) {
    		return new StateCounter().Count(rawData, actualData);
    	}
    	
    	public virtual ResultView Render (RawData rawData) {
    		var parsed = ParseRawData(rawData);
    		
    		if (parsed.IsValid) {
    			var actual = GetActualData(rawData);
    			var state = GetResultState(rawData, response);
    			return new Renderer().Render(state);
    		} else {
    			throw new Exception("Raw data is invalid");
    		}
    	}
    }


    Для пользователя это выглядит довольно симпатично:
    new Pipeline().Render(rawData);

    Если же ему необходимо брать из другого источника данные - он легко это исправит:
    class MyPipeline : Pipeline {
    	protected virtual ActualData GetActualData (ParsedRawData rawData) {
    		return new LocalStorageRequest(rawData.src);
    	}
    }
    
    new MyPipeline().Render(rawData);


    Конечно, это же можно сделать при помощи композиции. Ну давайте поиграем на основе паттерна Билдер:

    interface IPipeline {
    	ResultView Render (RawData rawData);
    }
    
    class Pipeline : IPipeline {
    	private IRawDataParser rawDataParser;
    	private IActualDataReciever actualDataReciever
    	private IResultStateCounter resultStateCounter;
    	private IRenderer renderer;
    	
    	public GetRawDataParser () {
    		return rawDataParser ?? new RawDataParser();
    	}
    	public GetActualDataReciever () {
    		return rawDataParser ?? new ActualDataReciever();
    	}
    	public Pipeline GetActualDataReciever (actualDataReciever) {
    		actualDataReciever = actualDataReciever;
    		return this;
    	}
    	
    	// ...
    	private GetRenderer () {
    		return renderer ?? new Renderer();
    	}
    	
    	
    	public virtual ResultView Render (RawData rawData) {
    		
    		var parsed = GetRawDataParser().Parse(rawData);
    		
    		if (parsed.IsValid) {
    			var actual = GetActualDataReciever().Get(rawData);
    			// ...
    			return GetRenderer().Render(state);
    		} else {
    			throw new Exception("Raw data is invalid");
    		}
    	}
    }


    Использование по-умолчанию всё то же:
    new Pipeline().Render(rawData);

    А изменить пользователь их может так:
    new Pipeline()
    	.SetActualDataReciever(new MyDataReciever())
    	.Render(rawData);


    Тут впору уже и о DI Container'ах почитать.

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

    В качестве вывода повторю самое главное - просто тренируйтесь, пишите и набивайте шишки, читайте о паттернах и приемах, но помните, что это рекомендации, а не законы и старайтесь думать и анализировать, что пишете и читаете.
    Ответ написан
    Комментировать
  • Хорошая ли практика создавать свои классы Exception для отлавливания разных ошибок?

    @WhoMe
    UPD:
    > Это нормально что в контроллере столько много catch'eй?
    Не то чтобы нет, но "попахивает".
    > как быть, если у меня возникает несколько исключений, и я хочу выдать пользователю информацию о всех возникших сразу

    У вас смешана валидация входных параметров с возникновением нештатных ситуаций.
    Exception стоит кидать если метод не может вернуть осмысленный результат.
    Ошибки валидации ("сообщение слишком длинное", "файл не того расширения") можно собирать, к примеру, в массив. Как валидировать входные данные выходит за рамки этого вопроса.
    ------
    > Можно ли так делать?
    Попробуйте использовать правило 5 почему (ну или "зачем") чтобы попытаться добраться до сути.

    - Я даю отдельные имена исключениям.
    - Зачем?
    - Для того что бы отловить различные ошибки.
    - Зачем отлавливать различные типы ошибок?
    - Чтобы показывать разные сообщения.
    - Зачем показывать разные сообщения?
    - Чтобы пользователь мог отреагировать определенным образом на конкретный тип ошибки
    (решить что ему делать в случае конкретного исключения).

    Давайте посмотрим что человек (пользователь) на вашем сайте (системе) может сделать в случае ошибки:
    1. Не корректное сообщение.
    Привести его к корректному (сделать его короче, как-то отформатировать и т.п.)

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

    3. Ошибка PDO.
    Ничего, это внутренняя ошибка.

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

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

    Внутренние - пользователь не может влиять (ошибка подключения к БД, SQL syntax error и т.п).
    Пользователю показывается только код ошибки. В такие ошибки также вкладываю техническую информацию.

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

    Подытожу:

    > Можно ли создавать свои пустые классы Exception'ов наследуемые от класса Exception только лишь для того что бы было отдельное имя исключения?

    Можно.

    Сколько делать отдельных исключений?
    Зависит от того как их будет обрабатывать пользователь.
    Если твой контроллер(модель, подсистема) кидает множество разных ошибок и все они обрабатываются одинаково - то стоит призадуматься.
    Ответ написан
    3 комментария
  • Что проще (или как правильнее), изучить Wordpress или научится писать свой движок на php?

    Sanasol
    @Sanasol Куратор тега PHP
    нельзя просто так взять и загуглить ошибку
    Научиться писать на php.

    Тогда вы сможете и своё написать и водрпресс взять.

    Ну и заодно будете понимать когда надо взять вордпресс, а когда написать велосипед(почти никогда)
    Ответ написан
    Комментировать
  • Какой тип оценки контента лучше на сайте, like - dislike, оценка по шкале или комбинированные варианты?

    OtshelnikFm
    @OtshelnikFm
    Обо мне расскажет yawncato.com
    Важно - самому пройти через эти кармы))

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

    5-10 баллов подходит для кино (ох уж эти тонкие эстеты что ратуют который год за 100-то бальную систему на кинопоиске), игр, музыки, для товаров.

    imdb и кинопоиск используют формулы + алгоритмы, следящие, если юзер минусатор - его заносят в список, оценки которого не влияют на рейтинг (тихий бан - ему они отображаются, но рейтинг не искажают). Там много хитрых моментов - понятное дело в открытую они об этом не говорят.

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

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

    Важно - для чего вам сайт:
    Если для кармо войн (интриги, расследования, хайп, рен-тв) - отображайте кто минусанул и сколько.

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

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

    И важный момент - только зарегистрированным давайте возможность голосовать полноценно.

    Но можно и так: Если плюсанул незарегистрированный - добавьте не 1, а 0.1 балл. И конечно защита по времени, ip, кука и прочее.
    Ответ написан
    Комментировать
  • Как правильно писать на ООП?

    Adamos
    @Adamos
    ООП - это компьютерная мечта о дамской сумочке. Которая большая внутри и крошечная снаружи.
    Главное в хорошем классе - это интерфейс, позволяющий вообще не думать о том, что находится внутри класса.
    Представьте себе черный ящик, решающий вашу задачу. Сформулируйте, каких внешних данных ему должно быть достаточно и какими внешними же признаками и логикой должен обладать этот ящик. Старательно абстрагируясь от того, что там будет происходить внутри (процедурное программирование приучает думать об этом, придется напрячься).

    Простейший пример - jQuery.cookies. Кукисы в браузере хранятся неудобно для редактирования, но это проблемы внутри черного ящика, снаружи их быть не должно. Снаружи вам надо поставить куку и прочитать куку. С коротким списком возможных свойств. Вот это класс и реализует, вполне успешно. Буквально одним методом.
    Мог бы этот метод быть простой процедурой? Да, конечно. Но как раз это - неважно.
    Ответ написан
    2 комментария
  • Почему нет профсоюза IT-работников?

    DmitriyEntelis
    @DmitriyEntelis
    Думаю за деньги
    Imho все адекватные люди аполитичны и предпочитают тратить время на зарабатывание денег.
    В текущих реалиях проще эмигрировать, чем тратить время на это вот все.

    А про забастовку, ну право смешно. Вы реально считаете что правительство рассматривать it отрасль как социально значимую? Это скорее что-то непонятное, мешающее свету из телевизора проникать глубь народных масс.

    Тем более что государственных то it компаний практически нет. Будете бастовать внутри своей коммерческой структуры - никому кроме этой структуры вы не навредите.

    Поднимите столько хайпа что государство обратит внимание на регулирование работников - вот тут то вы и взвоете по настоящему.
    Ответ написан
    10 комментариев
  • Рационально ли внедрять зависимости в класс через DI-контейнер, обходя при этом стороной конструктор и сеттеры?

    @Flying
    В целом это считается плохой практикой. Приведу ссылку на соответствующий кусок из документации DI контейнера в Symfony: https://symfony.com/doc/current/components/depende...

    Доставая зависимости непосредственно из контейнера вы лишаете себя массы преимуществ внедрения зависимостей:
    • Страдает тестируемость класса т.к. вы не можете подменить сервисы на нужные вам во время тестов
    • Вы лишаете себя возможности валидации целостности графа зависимостей в случае если используется компилируемый контейнер (как, например, в Symfony)
    • Вы привносите в класс излишнюю информацию о названиях конкретных сервисов которые вы достаёте из контейнера
    • Вам потребуется дополнительно проверять есть ли каждый из сервисов в контейнере и что же именно вы достали из контейнера (через instanceof)


    Уверен что есть и другие факторы, это то что пришло на ум в первую очередь.
    Ответ написан
    Комментировать
  • Стратегия входа, путь развития во фрилансе. С чего начать, чтобы стать верстальщиком и php-программистом?

    Jump
    @Jump
    Системный администратор со стажем.
    marsel81,
    Как понимаю, самые популярные и востребованные "профессии" во фрилансе - это верстка и php-программисты на разных фреймворках.
    Неправильно понимаете.
    Названные вами направления это очень узкий пласт фриланса даже в IT, хотя и достаточно популярны.

    Электрики, маляры, строители, учителя, сантехники, архитекторы, дизайнеры, программисты, системные администраторы, и много других профессионалов работают во фрилансе, и очень востребованы.
    Ответ написан
    Комментировать
  • Какая из посадок верстки на Wordpress более актуальная и правильная?

    entity1313
    @entity1313
    Веб-разработчик, проект-менеджер
    Правильный путь - следовать API wordpress и особенностям CMS.

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

    Прежде чем делать что-то с темой, нужно разобраться, делаете вы тему с нуля, или обновляете существующую.

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

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

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

    Изменяемые блоки делаются или через визуальный редактор (Visual Composer или другие), или через механизм опций, или через плагины вроде ACF. Причём ACF использовать не обязательно, у WP есть интерфейс для произвольных полей.

    В плане того, что использоваться - ACF, фреймворки, или ещё что, логика примерно такая:
    1. Общие элементы темы вроде лого, копирайта, контактных данных - это опции (свой код для страницы настроек), фреймворки опций (Redux, ACF-про ) или кастомайзер WP. Последнее кажется наиболее правильным и соответствующим развитию WP - там почти рукой подать до визуального редактирования уже.
    2. Контент страниц - стандартный интерфейс для произвольных полей, ACF или другие решения. С ACF причём нужно быть аккуратным, он может упереться в ограничения сервера по количеству полей или давать неверные данные (писал бакенд для мобильного приложения через WP REST API и хлебнул лиха от сохранённых через ACF данных, привязанных к таксономиям)

    В плане кода - всё, что должно решаться через API, решается через API. wp_enqueue_script/style для скриптов и стилей, wp_head(), wp_footer() в соответствующих местах. Вариантов превратить разработку темы в извращение тут очень много, доводилось видеть много всякого от неопытных разрабочтиков. И какого-то универсального решения всего этого избежать, возможно, просто нет. Кроме как учиться, смотреть гайды и лучшие практики, следить за обновлениями WP и рекомендациями для разработчиков.
    Ответ написан
    5 комментариев
  • Плагин для профилирования в Wordpress?

    deniscopro
    @deniscopro Куратор тега WordPress
    WordPress-разработчик, denisco.pro
    Доброго.

    Query Monitor?
    Ответ написан
    Комментировать
  • Как быстро реагировать на новые задачи на биржах фриланса?

    zamboga
    @zamboga
    Аналитика данных, BI-аналитика, дашборды
    Искать заказы на других площадках, кроме ад.кг

    Ловите из моей подборки:
    • Биржи фриланса СНГ
    https://primelance.com — агрегатор фриланс-бирж.
    https://freelance.ru/
    https://freelansim.ru/
    https://YouDo.com
    https://fl.ru/
    https://freelancehunt.com/
    § Статистика цен https://freelancehunt.com/statistics/rates/currency/rub
    https://www.weblancer.net/
    www.free-lance.ru
    https://yukon.to — пока бесплатная (январь 2018)

    • Биржи фриланса международные
    https://www.upwork.com
    www.freelancer.com
    https://www.peopleperhour.com
    https://www.guru.com
    fiverr.com
    https://envato.com
    https://talent.hubstaff.com
    https://remoteok.io
    https://weworkremotely.com
    https://www.cybercoders.com
    https://djinni.co
    https://www.toptal.com
    https://www.linkedin.com
    https://elance.com — куплен upwork
    https://odesk.com — куплен upwork
    Ответ написан
    1 комментарий
  • Wordpress на UpWork - реально ли начать в 2018 году?

    coderisimo
    @coderisimo
    Имхо, на Upwork WP одна из доминирующих технологий. Заказов МОРЕ.

    М О Р Е !!!!!!

    Спецов , как раз не так много. Много низкоквалифицированных людей, берущихся за любую работу по низким ценам. Качество соответствующее. Как только наработаете портфолио и хороший рейтинг , проблем не будет. Прочтите статьи про то, как брать заказы , как заполнять профиль итд. Сделайте в профиле акцент на WP.
    Я вот WP не знаю и не люблю :) , но в начале работал с ним. Писал плагины. Причем, были предложения от клиентов работать постоянно с такими проектами, но мне это не интересно.

    Резюме - именно для спецов WP на апворке раздолье.
    З.Ы. Только не хватайте любой заказ. Оцените заказчика. Это сэкономит время, деньги и главное - НЕРВЫ.
    Удачи.
    Ответ написан
    7 комментариев
  • Какие есть критерии для выбора технологии для сайта?

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

    vaut
    @vaut
    Для маркировки каких либо значимых версий можно использовать теги. Не обязательно целую ветку для этого создавать.
    А добавление фичи в мастер по сути нечем не отличается от удаление легаси или рефакторинга. Ветка --> изменения --> объединение.
    Ответ написан
    Комментировать
  • Что означает (jQuery) после (function( $ )?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    (function( ) {
    })();

    Вот эта конструкция называется "анонимная самовызываемая функция".

    То есть, тут два действия:
    Объявление анонимной функции
    function( ) {
    }

    и сразу ее вызов
    ()()
    Первые скобки это синтаксический приём для вызова анонимной функции. Есть и другие методы. Например
    +function(){}()
    Вторые скобки - это собственно вызов функции и при необходимости передача параметра (обычный вызов же)

    ()(jQuery) — в параметре передается jQuery

    function($){} — а тут этот параметр объявлен и используется

    (function($){})(jQuery) — итого, объявили анонимную функцию, и вызвали ее, передав параметром объект jQuery

    Например, доллар у вас используется другой библиотекой, пусть MooTools.
    Тогда вы запускаете jQuery в безконфликтном режиме

    jQuery.noConflict();

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

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

    (function($){
      $('.slider').slick();
    })(jQuery);


    Чтобы стало совсем понятно, конструкцию можно переписать без анонимной функции

    var myFunc = function($){
     // some code
    }
    
    myFunc(jQuery);
    Ответ написан
    Комментировать
  • Можно ли в реакте писать на jQuery, а не на JS?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    JS - язык программирования
    jQuery и React - библиотеки написаные на JS, обе решают одну и туже задачу - управление DOM, но разными методами: jQuery - императивно, React - реактивно
    Для использования любой из них нужно знание JS
    Ваш вопрос бессмысленный
    Ответ написан
    Комментировать
  • Укажите на ошибку синтаксиса?

    0xD34F
    @0xD34F
    Где я лапухнулся?

    Там, где решили чтение документации подменить фантазированием. Верните SELECT обратно, а "непонятный результат" - это ресурс результата запроса, из него надо достать что там вам нужно, для этого есть всякие разные методы - pg_fetch_result, pg_fetch_row, pg_fetch_all, ... - выбирайте подходящий.
    Ответ написан
    Комментировать
  • Как перерасти из кодера в программиста?

    Yertuwernat
    @Yertuwernat
    Кратко о себе: живу в России, не женат, характер
    Кодер и программист это одно и то же, как мне кажется.
    С лингвистической точки зрения это тот человек который владеет языком машины.
    Тот кто умеет писать код - то есть умеет заставить машину работать.

    На самом деле в природе такое разделение:

    1) слесари монтажники (работают в рамках готовой архитектуры) 90% популяции
    2) инженеры (разрабатывают архитектуры) 10% популяции

    Если хочешь стать инженером - надо просто больше учиться - читай все вузовские учебники для инженеров-программистов и практикуйся.
    Ответ написан
    1 комментарий