Ответы пользователя по тегу ООП
  • Как в родительском классе указать не сколько таблиц для методов?

    qonand
    @qonand
    Software Engineer
    Если правильно понимаю у Вас две проблемы:
    1. Вы не знаете как считывать данные из параметров дочерних классов и подставлять их в Ваши запросы.
    2. Вы не знаете как заполнить данными параметры дочерних классов полученными из SQL-запроса
    За подобного рода преобразования должны отвечать дочерние классы, а родительские класс должен только использовать эти преобразования. Соответственно Вам нужно создать два абстрактных метода реализующих для каждого потомка свои механизмы преобразования.

    P.S. почитайте про паттерн Active Record, по сути дела Вы пытаетесь его повторить в некой своей интерпретации
    Ответ написан
    2 комментария
  • Класс как аргумент функции, как это использовать?

    qonand
    @qonand
    Software Engineer
    что это вообще такое, как гуглить, где читать?

    Это обычная функция обратного вызова реализованная через анонимную функцию. Гуглить соответственно по словам "функция обратного вызова", "Анонимная функция". Читать статьи в интернете, книги по основам программирования ...
    Будет неплохо, если будут примеры или толковые объяснения

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

    Еще раз - это основы и они имеют такое же отношения к паттернам как и циклы, условия и т.п. т.е. никакое.
    Ответ написан
    Комментировать
  • Как обрабатывать добавление поста в классах?

    qonand
    @qonand
    Software Engineer
    ох Вы с названиями и ответственностью классов намудрили, давайте по порядку
    Есть модель ModelPosts, в которой мы получаем все из базы данных.

    Это не модель. Модель - это набор классов реализовывающих бизнес-логику. У Вас же этот класс реализовывает взаимодействие с базой данных - а это как бы вообще не бизнес-логика. По сути дела класс ModelPosts у Вас выступает в качестве репозитория, который только обеспечивает взаимодействие с базой данных. Репозиторий - это уровень доступа к данным.

    Есть объект Post, в котором обычно помещаются данные о посте, после их получения из БД (но у себя в голове никак не могу его определить куда-то при добавлении поста, получается этот объект никак не участвует в добавлении)

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

    Добавление поста - это что? в общем случае это просто выполнение определенного запроса к базе данных. А что отвечает за взаимодействие с базой данных? Уровень доступа к данным, в нашем случае это класс ModelPosts (вообще-то не удачное название). Соответственно в нем и должна быть реализация добавления поста в базу данных.

    Что касается валидации - реализация механизма валидации должна содержаться в отдельном классе (или классах). Сама валидация может происходить либо в контроллере, либо в модели
    Ответ написан
    Комментировать
  • Если бы в интерфейсе можно было реализовывать желаемые методы без необходимости реализации в наследниках, то были бы тогда нужны абстрактные классы?

    qonand
    @qonand
    Software Engineer
    Что бы понять в чем разница между абстрактными классами и интерфейсами для начала стоит немного отойти от их реализации для конкретного языка программирования и понять их суть.
    Что такое интерфейс? это спецификация взаимодействия внешнего мира с объектом. Обратите внимание именно ВЗАИМОДЕЙСТВИЯ, а не реализации.
    Возьмем для примера обычный класс, описывающий какой нибудь выключатель (т.е. задача такого класса включать или выключать какое-то устройство):
    public class Switch 
    {
        public void On()
        {
            // тут предполагается куча кода для включения устройства
        }
    	
        public void Off()
        {
            // тут предполагается куча кода для выключения устройства
        }
    }

    Что входит в состав данного класса:
    1. РЕАЛИЗАЦИЯ функционала включения/выключения устройства (т.е. куча кода который управляет устройством)
    2. ИНТЕРФЕЙС (сигнатура методов On и Off), с помощью которого клиенты класса взаимодействуют с ним.
    Вы можете спокойно управлять объектом этого выключателя, опираясь на его интерфейс, зная что есть метод On отвечающий за включение и метод Off отвечающий за выключение. Но теперь представьте что у Вас десятки разных типов выключателей с разной реализацией и над классом для каждого типа работает отдельный разработчик. Как сделать Ваш алгоритм управления универсальным и независимым от конкретного типа выключателя? Для этого нужно что бы у выключателя в независимости от его типа был одинаковый интерфейс (грубо говоря присутствовал метод On и метод Off). Но как разработчикам классов-выключателей знать что Вам нужен именно такой интерфейс? а если они и знают как заставить их его в точности соблюсти? Согласитесь было бы удобно, если бы была возможность, где-то отдельно описать интерфейс (формализовать его), на который можно было бы опираться при взаимодействии с выключателями, а другие разработчики просто бы его подключали и реализовывали. Вот тут на помощь уже и приходить отдельная конструкция interface, которая позволяет этого добиться. Вы можете сделать так:
    public interface ISwithable
    {
        public void On()
    	
        public void Off()
    }

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

    qonand
    @qonand
    Software Engineer
    ООП
    Бертран Мейер. "Объектно-ориентированное проектирование программных систем"
    Гради Буч “Объектно-ориентированный анализ и проектирование с примерами приложений”

    Алгоритмы / структуры данных
    Томас Кормен "Алгоритмы построение и анализ"
    Генри Уоррен "Алгоритмические трюки для программистов"
    Николас Вирт "Алгоритмы и структуры данных"
    Дональд Кнут "Искусство программирования"
    Ответ написан
    Комментировать
  • Какой шаблон проектирования больше подходит для загрузки связанных сущностей?

    qonand
    @qonand
    Software Engineer
    1. Как-то у Вас сущности живут отдельной жизнью друг от друга. По сути сейчас Вы перенесли структуру своей базы данных на объекты, а это не правильно. Сущность заказа должна агрегировать в себя сущности позиций заказа и покупателя, а не просто содержать их идентификаторы. Например:
    class OrderEntity
    {
        /**
         * @var integer Идентификатор заказа
         */
        protected $id;
        
        /**
         * @var MemberEntity Объект покупателя
         */
        protected $member;
        
        /**
         * @var ItemEntity Массив позиций заказа
        protected $items = [];
    }

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

    qonand
    @qonand
    Software Engineer
    применяйте либо, как сказал Максим, паттерн Abstract Factory либо Static Factory
    Ответ написан
    Комментировать
  • Как добиться создания иммутабелтных структур?

    qonand
    @qonand
    Software Engineer
    Ох как-то не правильно у Вас реализован иммутабельный объект. Почитайте как их стоит организовывать на PHP, например в этой статье
    Ответ написан
    Комментировать
  • Как динамически подключить к class'у свойства и методы другого class'а или trait'а?

    qonand
    @qonand
    Software Engineer
    Как динамически подключить свойства и методы другого class'а или trait'а?

    Средствами языка никак, да и изменение поведения/структуры объекта есть плохая практика, нарушающая принцип подстановки Барбары Лисков. Не до конца понимаю Вашу задачу, но порекомендовал бы посмотреть в сторону агрегации и композиции
    Ответ написан
    8 комментариев
  • Какие есть варианты реализации класса-хелпера для PHP?

    qonand
    @qonand
    Software Engineer
    сложно рассуждать не имея представления о функциях.
    вообще использование хелперов не есть хорошая практика с точки зрения ООП. Поэтому если есть возможность избежать создания хелпера - лучше это делать. Ну а если избежать нет возможности (например у Вас хелпер обеспечивающий дополнительные функции обработки массивов) тогда обычным классом с приватным конструктором и статическими методами....
    Ответ написан
    8 комментариев
  • Структурирование исключений. Что вы указываете в качестве exeption code?

    qonand
    @qonand
    Software Engineer
    Как по мне создание справочника кодов бессмысленная и геморройная вещь.
    Почему геморройная - Вы сами на этот вопрос ответили.
    Почему бессмысленная: Вы думаете что клиенты будут обращаться в техподдержку и сразу говорить код ошибки? на практике такого не будет... клиент обратившись просто скажет "Я тут клацнул кнопку а оно перестало работать", и сотрудникам поддержки все равно придется уточнять что и как там у него случилось. Так что как-бы коды ничего не изменят. К тому же по началу справочник будет добросовестно вестись, а в процессе эксплуатации клиент/начальник скажет какому-то программисту Васе - запили как фичу на проекте по быстрому, он ее сделает но в справочник данные не внесет, ибо нафик ему нужен этот гемор. Поэтому как бы актуальность справочника скорее всего на практике пострадает.

    Зачем вообще коды? Возникла ошибка - вернули 500 статус и описание проблемы, записали подробную информацию в лог и все. Обратился клиент в тех. поддержку - посмотрели что за исключение возникло, посмотрели его stack-trace в логе и все. Грамотно сформированный лог + система поиска по нем решают все проблемы с поддержкой.
    Ответ написан
    7 комментариев
  • Совет по проектированию класса?

    qonand
    @qonand
    Software Engineer
    1. Интерфейс приносить много бонусов с точки зрения архитектуры. Изучите контрактное программирование - поймете все преймущества
    2. Да Вы правильно понимаете...
    Ответ написан
    Комментировать
  • Как должен называться и обязанности класса регистации, авторизации и прочего для пользователя?

    qonand
    @qonand
    Software Engineer
    как сказал Виталий IIIFX Хоменко здесь лучше откинуть идею реализации всего функционала в одном классе и применить SRP. Соответственно методы регистрации и авторизации необходимо вынести в специальные классы сервисы.

    P.S. Рекомендую почитать не только SRP но и про SOLID в целом
    Ответ написан
    Комментировать
  • Что почитать и на чем потренироваться, не могу перейти от процедурного к ооп?

    qonand
    @qonand
    Software Engineer
    Бертран Мейер - Объектно-ориентированное конструирование программных систем
    Мэтт Вайсфельд - Объектно-ориентированное мышление
    Грэди Буч - Объектно-ориентированный анализ и проектирование с примерами приложений
    Ответ написан
    Комментировать
  • Чем отличается active record от data mapper?

    qonand
    @qonand
    Software Engineer
    Оба эти паттерна предназначаются для преобразования данных из реляционного представления в объектное. Разница в том как они это делают и как они организованы, если в вкратце:
    ActiveRecord - это объект, который хранит данные и содержит логику взаимодействия с БД.
    Преимущества: простота, удобно использовать на небольших проектах.
    Недостатки: паттерн нарушает множество принципов в частности Single Responsibility Principle, его использование как правило делает код сильно связанным, из за чего на сложных проектах его использовать невозможно.
    DataMapper - объект хранящий логику взаимодействия с БД. Он не хранит данные как ActiveRecord
    Преимущества: позволяет построить слабосвязанную архитектуру, разделить приложения на слои

    Более подробно можете почитать у Фаулера, да и просто погуглить можно, на эту тему уже много материалов написано на просторах интернета.
    Ответ написан
    Комментировать
  • Возможно ли прекратить виполнения дальнейших методов класса в конструкторе?

    qonand
    @qonand
    Software Engineer
    Возможно ли прекратить виполнения дальнейших методов класса в конструкторе?

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

    qonand
    @qonand
    Software Engineer
    Если правильно понимаю, Вас интересует вопрос как именно связанные данные из реляционного представления преобразовать в объектное. В этом случае рекомендую почитать про паттерн Foreign Key Mapping. Почитать можно у Фаулера, (ну либо просто погуглить)
    Ответ написан
  • Шаблон Реестр ООП?

    qonand
    @qonand
    Software Engineer
    Как мне избавиться от контейнера $App, что бы я вызывал подключаемые объекты реестра вот так:

    Главный вопрос зачем? Ваш класс $app - это вариация синглтона (хоть и довольно кривая), обеспечивающий в данной ситуации избежания дубликатов объекта Registry со всем содержимым.

    App->NameClass->getUser();

    Так Вы вообще не сделаете, есть либо статически методы, которые можно вызывать без создания объекта, либо обычные для вызова которых необходимо создавать объект. А Вы спрашиваете как вызвать обычный метод без создания класса, ответ - никак.
    Хотите избавиться от класса App - тогда создавайте объект Registry и используйте его (хоть это и не очень хорошая идея)
    Ответ написан
    3 комментария
  • Зависимости внутри системы лучше строить от интерфейсов или абстрактных классов? Когда лучше использовать абстрактный класс и когда интерфейс?

    qonand
    @qonand
    Software Engineer
    Абстрактный класс позволяет частично реализовать функциональность и указать что должно быть реализовано в потомках, это удобно как для базового класса. Но использовать его в качестве реализации механизма зависимости не стоит, т.к.:
    1. Могут возникнуть ситуации когда понадобиться реализовать класс не наследуясь от абстрактного класса.
    2. Один класс может использоваться в нескольких зависимостях и для каждой из них может быть свой набор обязательных характеристик. В этом случае Вам придется "раздувать" базовый класс что не хорошо.

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