В Doctrine, если я хочу реализовать разные типы транспортных средств. Может быть, автомобиль, самолет, велосипед и так далее ... у всех этих транспортных средств есть много разных свойств, но есть и очень общие вещи, например, все они сделаны из материала.
Итак, если я хочу получить этот материал ... должен ли я реализовать абстрактный класс Vehicle со свойством material и реализовать геттер / сеттер или я должен определить интерфейс IVehicle и определить там геттер / сеттер, чтобы убедиться, что действительно существует метод для получения и установки материала? Или мне даже следует использовать оба в комбинации?
Использование интерфейса кажется "профессиональным" ... но мне кажется неправильным определять геттеры / сеттеры в интерфейсах, поэтому мое личное ощущение:
Не используйте интерфейс, просто используйте абстрактный класс.
Но защищен ли подход абстрактного класса от неправильного использования? Например, в другом месте я определенно ожидаю, что тип Material вернется из функции getMaterial ... может ли подход абстрактного класса также сохраняться для того, чтобы не возвращать полные неожиданные вещи (например, интерфейс)?
Поэтому, если я расширю это средство для другого конкретного класса, разработчик не сможет возвращать неожиданные вещи, но также должен иметь возможность при необходимости изменить логику в конкретном методе.
Этот вопрос не по теме для SO, поскольку он самоуверен, однако здесь может быть лучше: softwareengineering.stackexchange.com
Использование интерфейсов даст вам возможность использовать множественное наследование.
я опубликовал это в другом сообществе softwareengineering.stackexchange.com/questions/375461/… ... спасибо
Создайте MaterialInterface, чтобы пометить ваш код, что у объекта есть материал. Затем создайте MaterialTrait для реализации вашего метода getMaterial. Это избавляет вас от необходимости в абстрактном базовом классе и в то же время сокращает повторяющийся код.






Мои 2 цента:
Вы можете написать абстрактный класс с методами, которые возвращают null (или какое-либо другое предопределенное значение), что потребует от вас реализации их в каждом производном классе.
Этот подход по-прежнему потребует от вас написания некоторого шаблонного кода для проверки ваших условий в каждом классе.
Я бы лично выбрал здесь интерфейс, поскольку природа ваших классов кажется весьма разнообразной и может быть лишь частично обобщена до одного абстрактного класса. Однако я тоже не вижу ничего плохого в том, чтобы идти по пути абстрактного класса. В этом случае дьявол кроется в деталях.
Вы можете просто сделать эти функции abstract, а затем вам нужно будет определить их в каждом дочернем классе вместо того, чтобы возвращать null или что-то еще
Я бы лично сделал и то, и другое, потому что интерфейс - очень хорошее место, чтобы иметь надежную документацию по коду (например, почему вам нужен ваш абстрактный класс), не прибегая к комментариям Doctrine. Если ваш AbstractVehicle реализует
VehicleInterface, вы можете ввести свой код, ожидая Транспортное средство (что, на мой взгляд, является хорошей практикой). После создания интерфейса зачем вам копировать / вставлять код в каждый класс? Подводя итог, я бы сделал как интерфейс, так и абстрактный класс