• Ubuntu начала тормозить, в чем дело?

    Vovanys
    @Vovanys
    Может swap-ится?
    увеличь в /etc/sysctl.conf
    vm.swappiness = 10
    чтобы свопалась только если памяти занято 90%
    Ну и диск проверь, может пишет что-то куда то..
    Ответ написан
    Комментировать
  • Как решить задачу о распределении?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Если есть какой-то уникальный id у заказа, и они равномерно и плотно растут (например, имеют порядковые номера), то можно смотреть на последнюю цифру. 0-2 отдавать фирме с 30% заказов, 3-9 - второй фирме. Или для равномерности отдавать второй фирме цифры 1,3,4,6,7,8,0 Если таких номеров нет, то можно генерировать случайное число для заказа и смотреть на последнюю цифру там. В среднем будет соотношение 30/70 примерно.
    Ответ написан
    Комментировать
  • Как решить задачу о распределении?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Смотреть соотношение уже переданных заказов первой и второй службам. Если оно меньше 3/7, то передавать первой, иначе второй
    Ответ написан
    4 комментария
  • Как читать объекты D7 Bitrix?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Как мне получить TRADING_PLATFORM_ID ?

    $tradeBindingCollection = $order->getTradeBindingCollection();
    
    /** @var Bitrix\Sale\TradeBindingEntity $item */
    foreach ($tradeBindingCollection as $item) {
        $tpId = $item->getField('TRADING_PLATFORM_ID');
    }


    Как вообще читать такие объекты?

    В дампе который вы привели указаны типы объектов.
    Например $order->getTradeBindingCollection(); возвращает коллекцию Bitrix\Sale\TradeBindingCollection
    Она как и другие коллекции Bitrix имеет реализацию интерфейсов \ArrayAccess, \Countable, \IteratorAggregate
    Поэтому может проходится циклом foreach.

    В свою очередь каждый объект внутри коллекции является объектом класса Bitrix\Sale\TradeBindingEntity, что так же видно из дампа. Этот класс является наследником Internals\Entity, который имеет методы для получения полей хранящихся в поле values.

    Для того чтобы разобраться нужно смотреть документацию или исходные коды. Исходные коды рекомендую смотреть через IDE (не в notePad++), для удобной навигации и облегчения работы.

    В принципе всё это приходит с опытом.
    Ответ написан
    6 комментариев
  • Как выбрать оптимальную компанию для посылки?

    @402d
    начинал с бейсика на УКНЦ в 1988
    нахождение оптимального решения методами математического моделирования.
    Решение методом полного перебора.
    Написание весовой функции оценки качества решения.
    Подбор коэффициэнтов . Построение оптимальных планов экспериментов.

    В общем обратитесь к студенту 2-3 курса по специальном прикладная математика.

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

    DevMan
    @DevMan
    у вас решение здорового человека.

    возможно, можно оптимизировать проверки в условиях, но это:
    1. невозможно исходя из вопроса.
    2. экономия на спичках.
    Ответ написан
    Комментировать
  • Применимы ли генераторы для переиспользования кода?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Для провторного использования кода генераторы как раз подходят.
    В частности, они позволяют использовать полиморфизм, в едином интерфейсе обращаться как к изначально итерируемым ресурсам, так и к потокам.

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

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

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

    В моем коде требуется несколько раз переиспользовать foreach вложенный в foreach.


    Скорее всего генератор здесь будет бессмысленным.
    Чтобы понять, насколько здесь нужна какая-либо оптимизация, надо привести ИСХОДНЫЙ код, про который вдруг в голову ударила идея что его надо обязательно "оптимизировать"
    Ответ написан
    2 комментария
  • Как получить из фабрики коллекцию сущностей либо саму сущность?

    SilenceOfWinter
    @SilenceOfWinter Куратор тега PHP
    та еще зажигалка...
    1. ты путаешь/миксуешь фабрику и билдер
    2. должен быть определен абстрактный метод AbstactEntityFactory::create()
    3. что мешает реализовать Collection::__construct(array $entities)?
    4. фабричный метод EntityInterface::fromState() заявлен непосредственно в модели зачем создавать отдельный класс?
    Ответ написан
    8 комментариев
  • Чем паттерн Repository отличается от DataMapper?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Это два абсолютно разных паттерна.

    DataMapper - это то, что традиционно неправильно называют моделью. Тупо мостик между БД и объектом: считать данные из БД и записать в объект, сохранить объект в БД. Фактически CRUD. Способ автоматизировать рутинные операции. Моделью являться не может в силу изначальной ограниченности.
    Другими словами, это универсальный код, подходящий для работы с любыми объектами. Инструмент для работы с БД. Все его методы одинаковы для любых объектов.

    Репозиторий - это то, что на самом деле является моделью - набор методов, реализующих бизнес-логику приложения. Метод в репозитории может включать в себя десяток разных запросов к БД для получения набора данных, необходимого в приложении, плюс их обработку.
    В отличие от DM, репозиторий содержит также уникальные методы, которые отражают конкртеные нужды конкретного модуля приложения.
    Ответ написан
    1 комментарий
  • Чем паттерн Repository отличается от DataMapper?

    DarkRaven
    @DarkRaven
    разработка программного обеспечения
    Паттерн репозиторий дает унифицированный набор общих операций над сущностью в БД.
    Внутри репозитория может быть использован DataMapper. Назначение последнего именно в маппинге сущности из БД на доменную сущность (или модель).

    Информация:

    design-pattern.ru/patterns/repository.html
    design-pattern.ru/patterns/repository.html
    Ответ написан
    Комментировать
  • Как получить количество удаленных строк?

    @PetrPo
    попробуй $connection->getAffectedRowsCount()
    Ответ написан
    Комментировать
  • Как избежать спагетти-кода в result_modifier?

    Нет необходимости делать в виде модуля нечто под отдельный проект.
    Я делаю так (и не редко встречают похожий подход):
    В /local/php_interface/lib размещаю классы реализующие некоторую функциональность конкретного проекта, и подключаю его с помощью автозагрузки composer:
    60fb43892d58e809635873.png
    Тут можно разместить и классы реализующие модуль и просто обычные хелперы - не вижу ничего плохого в процедурном подходе, если все идеи реализованы в виде простых, коротких и минимально функциональных чистых статических методах.
    Ответ написан
    2 комментария
  • Когда полезно использовать генератор, если объем данных небольшой?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Эффективность здесь вообще не при чем.
    Генератор - это синтаксический сахар
    То есть вопрос вообще не про эффективность

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

    Но на самом деле бывают и другие критерии.
    У генератора есть одно однозначно полезное применение - возможность создания унифицированных интерфейсов.
    Любой потоковый источник он может превратить в перебираемый.
    То есть можно наплодить интерфейсов и скармливать их какому-нибудь форичу, и он будет с ними работать, не зная, поток внутри, или массив. Файл, результат запроса из БД, раскодированный джейсон - если в каждого из этих источников будет перебираемый интерфейс, то все их можно будет перебирать в одном и том же цикле.
    И вот ради такой унификации и используется генератор
    Ответ написан
    Комментировать
  • Как оптимально использовать кеширование при фильтрации по дате?

    udjin123
    @udjin123
    PHP, Golang, React
    Так и использовать, только время жизни кеша сделать 1 сутки, после будет удалятся
    Ответ написан
    Комментировать
  • Почему Service Locator это зло и что использовать вместо?

    kraso4niy
    @kraso4niy
    fullstack
    1. Вы всё верно поняли. Сложность в том что внутри может оказаться не та структура которую вы ожидайте (ожидалась)

    Но это не значит что это плохо. Эту проблему можно решить валидацией. В вашем примере достаточно проверять на instanceOf. Тогда код станет правильный. А в symfony сделали это ещё лучше и добавили строгость к типам для сервис локатора через подписку на сервисы.

    Что бы понять когда применять сервис локатор, а когда инъекцию пройдите по ссылке https://symfony.com/doc/current/service_container/... и почитайте.

    Там есть пояснение:
    Sometimes, a service needs access to several other services without being sure that all of them will actually be used. In those cases, you may want the instantiation of the services to be lazy. However, that’s not possible using the explicit dependency injection since services are not all meant to be lazy


    Можно пояснить на примере: допустим у вас есть класс с методом, и внутри метода только в некоторых случаях вам понадобится сделать запись в БД (допустим обращение к сервису в виде get->('db')).

    Например:
    if($userData = $request->get('user_data')) {
        $db = $serviceLocator->get('db')->insert($userData);
    } else {
       die("user data empty");
    }


    Если делать через инъекцию, то $db всегда будет инициализирована, например если проводить инъекцию через конструктор или метод, то объект вашего класса всегда будет при любых условиях запускать код инициализации $db и тратить на это ресурсы. Пример через инъекцию (тут тип инъекции через аргумент метода, аналогично можно сделать через конструктор или сеттер)

    class MyClass {
       // $db будет инициализрован, но используется только в 1 случае для if
      // если $db тяжёлый сервис и инициализируется долго это проблема!
       function httpResponse(Request $request, Database $db) {
          
           if($userData = $request->get('user_data')) {
              $db->insert($userData);
           } else {
              die("user data empty");
           }
       }
    }


    А в случае сервис локатора $db будет инициализирован только в условии когда придёт user_data. Таким образом если у вас контроллер использует 15 сервисов (но это bad code!), а одновременно нужен только 1 из них, лучше использовать сервис локатор.

    class MyClass {
       // В таком случае рекомендуется воспользоваться сервис локатором! 
       function httpResponse(Request $request, Database $db, Servive1 $s1, Service2 $s2) {
          
           if($userData = $request->get('user_data')) {
              $db->insert($userData);
              if ($db->lastId()) {
                   $s1->makeSuccess();
                   if($s1->isSuccess()) {
                       $s2->commit();
                   }
              }
           } else {
              $s2->rollback();
              die("user data empty");
           }
       }
    }


    Отсюда следует почему сервис локатор считается антипаттерном. Если ваш класс использует 15 сервисов, и из них все используются выборочно, то вам вероятно следует изменить архитектурный подход, провести рефакторинг, провести декомпозицию класса.

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

    P.S:
    Использовать service locator можно и в этом нет ничего страшного, особенно когда есть понимание что это такое и для чего он нужен.
    Ответ написан
    Комментировать
  • Паттерн "Фабричный метод": как получить конкретный продукт из конкретной фабрики?

    vitaly_74
    @vitaly_74
    (получаю название нужной фабрики и продукта из запроса — в контроллере)
    Например в yii2 есть такая штука как сценарии у моделей, вы можете использовать сценарий как имя продукта.
    либо вы можете написать валидатор, который из запроса будет определять, какой параметр использовать для конструктора фабрики.
    Например, если у вас много платежных систем, то пользователю можно дать на выбор 4 ссылки (4 платежные системы) в роутеры которых зашиты их названия, т.е. pay/yandex-money или pay/webmoney
    тогда в клиентском коде вы должны будете что то типо такого сделать:
    ... 
    Validator / Scenario / Router
    ...
    $payMethod = $validator->scenario() // yandex-money
    ...
    $paymentSystem = new PaymentFactory($payMethod);
    $paymentSystem->pay();//оплачиваем через яндекc деньги
    ...
    Ответ написан
    2 комментария
  • Как реализовать фабричный метод без switch?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Фабричный метод - это т.н. виртуальный конструктор. Внутри функции не должно быть конструкций выбора. Сам фабричный метод передается в другое место для порождения объектов некоторого класса с определенным интерфейсом.

    Конструкции выбора обычно присутствуют внутри абстрактных фабрик. В фабрику приходит некий идентификатор типа и (если идентификатор определен) фабрика создает объект некоторого класса с определенным интерфейсом.

    Абстрактную фабрику можно реализовать на основе контейнера фабричных методов. Шаблоны C++ и стандарты C++11/14 нам в этом только помогут. Самый простой код такой фабрики может выглядеть вот так:
    Пример фабрики
    template< typename TInterface, typename... TArguments >
    class AbstractFactory final
    {
    public:
    	// Produce the implementation, but return the pointer to interface.
    	inline std::shared_ptr<TInterface> Produce( const std::string& implementation_name, TArguments... arguments )
    	{
    		auto found_function = m_factory_functions.find( implementation_name );
    		return ( found_function == m_factory_functions.end() )? std::shared_ptr<TInterface>{} : found_function->second( std::forward<TArguments>( arguments )... );
    	};
    	
    	// Define the implementation.
    	template< typename TImplementation >
    	inline const bool DefineImplementation()
    	{
    		return DefineImplementation<TImplementation>( TImplementation::ClassName() );
    	};
    	
    	// Define the implementation.
    	template< typename TImplementation >
    	inline const bool DefineImplementation( const std::string& implementation_name )
    	{
    		// Abort the incorrect registration.
    		static_assert( std::is_base_of<TInterface, TImplementation>::value, "Implementation may only be derived from interface of Factory." );
    		
    		auto found_function = m_factory_functions.find( implementation_name );
    		if( found_function == m_factory_functions.end() )
    		{
    			m_factory_functions[ implementation_name ] = &AbstractFactory<TInterface, TArguments...>::template ConstructImplementation<TImplementation>;
    			return true;
    		};
    		
    		return false;
    	};
    	
    	// Check the implementation name is already defined.
    	inline const bool IsImplementationDefined( const std::string& implementation_name ) const
    	{
    		return m_factory_functions.find( implementation_name ) != m_factory_functions.end();
    	};
    	
    private:
    	// The factory function just produce implementation.
    	template< typename TImplementation >
    	static std::shared_ptr<TInterface> ConstructImplementation( TArguments... arguments )
    	{
    		return std::static_pointer_cast<TInterface>(
    			std::make_shared<TImplementation>( std::forward<TArguments>( arguments )... )
    		);
    	};
    
    private:
    	// Factory function produces the implementations of TInterface.
    	using FactoryFunction	= std::shared_ptr<TInterface> (*)( TArguments... arguments );
    	
    	std::unordered_map<std::string, FactoryFunction>	m_factory_functions;
    };


    Работает она примерно так:
    cpp.sh/93obm
    Ответ написан
    Комментировать
  • Как создать экземпляр класса в фабричном методе?

    vitaly_74
    @vitaly_74
    1. case сам по себе не есть плохо, и это не считается дурным тоном. т.е. использовать конструкцию case можно и нужно.
    2. Давайте подумает чем характеризуется объект экземпляра класса, а потом перейдем к фабрике.
    Объект прежде всего характеризуется данными хранящимися внутри него. Т.е. Фабрика должна внутри себя хранить то что она выпускает (строит) и всю информацию о нем.
    3. не используйте рефлекшен. это плохо это дурной код, без крайней необходимости не нужно. Обычно рефлекшены не используются в клиентском коде, только непосредственно в самих фреймворках. но раз вы задаете вопросы про фабрики, вы фреймворк не пишите, а значит и использование рефлекшенов вам не нужно.
    4. Взгляните на оператор new (например, new Factory()) по сути оператор new и есть фабрика, которая из класса создает объект с уникальными (а может и не всегда) наборами данных.
    5. в ссылке выше, вам дали информацию по рефакторингу switch но если прочитать там, написано,
    не стоит трогать если
    Зачастую оператор switch используется в фабричных паттернах проектирования (Фабричный метод, Абстрактная фабрика) для выбора создаваемого класса

    вот в данном случае не нужно трогать.
    Почему лучше использовать switch?
    - потому что когда через год, или два зайдете в эту фабрику, навряд ли вы захотите разбираться в рефлекшенах, и не интуитивных выражениях. А когда все есть в switch вы сразу увидите перед глазами какие объекты может выпускать фабрика + по аналогии создать подобный объект используя менее трудозатрат (почти копипаст).
    Вот тут хороший пример фабрики:
    https://refactoring.guru/ru/design-patterns/factor...
    или можно так:
    /**
     * Интерфейс Продукта объявляет операции, которые должны выполнять все
     * конкретные продукты.
     */
    interface Product
    {
        public function operation(): string;
    }
    
    /**
     * Конкретные Продукты предоставляют различные реализации интерфейса Продукта.
     */
    class ConcreteProduct1 implements Product
    {
        public function operation(): string
        {
            return "{Result of the ConcreteProduct1}";
        }
    }
    
    class ConcreteProduct2 implements Product
    {
        public function operation(): string
        {
            return "{Result of the ConcreteProduct2}";
        }
    }
    
    class Factory implements Product{
       private $product;
       function __construct(string $productClass){
           switch($productClass){
               case default:
               case ConcreteProduct1::class:
                          $product = new ConcreteProduct1();
               break;
               case ConcreateProduct2::class:
                          $product = new ConcreateProduct2();
               break;
           }
           $this->product = $product;
       }
    
       public function operation(): string
        {
            return $this->product->operation();
        }
    }
    
    $product = new Factory(ConcreateProduct1::class);
    echo $product->operation();


    В данном случае Разрешено менять старый код, но только в пределах switch.
    Ответ написан
    7 комментариев
  • Mysqli vs PDO — что выбрать?

    webdisigner
    @webdisigner
    mysqli выбирай, мозга не трахай Вася
    Ответ написан
    Комментировать
  • Как получить по лимиту данные из одной таблицы по разным критериям?

    @Akina
    Сетевой и системный админ, SQL-программист.
    WITH cte AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY RAND()) rn
                  FROM ...
                  WHERE ID IN (1, 2, ..100) )
    SELECT *
    FROM cte
    WHERE rn <= 5
    Ответ написан
    2 комментария