Название: Проблемы обобщения Отправлено: Igors от Декабрь 12, 2017, 10:00 Добрый день
Есть класс CGeometry (полигонный объект). Он управляется таким методом Код И есть класс камера для которого трансформация задается по-другому Код И вот есть еще один класс CLight (источник света) для которого SetTransform задается точно так же как и для CCamera. Сейчас это решается просто дублированием кода (его не так уж много). Но все-таки интересно - а как грамотно (или правильно)? Очевидное наследование камеры и источника от одного базового класса (напр CReferenceObject) не нравится - слишком уж мало общего у этих классов (ну 5% отсилы) чтобы заряжать общую базу. Тогда какие еще возможности? Спасибо Название: Re: Проблемы обобщения Отправлено: ssoft от Декабрь 12, 2017, 11:48 Здесь возможно несколько вариантов. Вот некоторые из них.
1. Наследование от общего интерфейса Transformable, который в общем случае будет абстрактным, а конкретная реализация уточняться так называемыми деталями. + обобщение всех типов через общие интерфейсы Transformable и любой <Atribute>able. + сокрытие (как следствие, легкая замена) и множественность деталей реализации - множественные наследования, сложность модели, определенный способ мышления (DDD). 2. Похожая реализация Здесь принимаем, что копипаст реализаций - это случайное совпадение обстоятельств. В общем случае реализации могут быть похожи. Так как типы совершенно независимы, то изменение одной реализации не должно затронуть другую. 3. Выделение отдельной сущности В примере можно выделить отдельную сущность Transform, которая и будет нести в себе всю функциональность. Соберет разные реализации в одну сущность. Тогда другие типы будут принимать только готовый экземпляр объекта Transform. Название: Re: Проблемы обобщения Отправлено: Racheengel от Декабрь 12, 2017, 13:01 Метод 1 - не сработает, т.к. интерфейсы должны быть разными.
Метод 2 - в принципе, для малой задачи самое оно. Но если вдруг "общее" разрастется - тогда плохо. Метод 3 - вообще какой-то ад. Будет жуткий микс из кастов и свитчей. Я бы лично либо использовал метод 2, либо сделал класс вроде CBaseTransform, в котором бы собрал общий функционал для камеры и света, и затем использовал бы его как член классов камеры и источника света. Название: Re: Проблемы обобщения Отправлено: ssoft от Декабрь 12, 2017, 16:21 Я бы лично либо использовал метод 2, либо сделал класс вроде CBaseTransform, в котором бы собрал общий функционал для камеры и света, и затем использовал бы его как член классов камеры и источника света. Это ж и есть методы 2 и 3). Только вместо CBaseTransform был предложен Transform, собирающий общий функционал по работе с трансформациями). Название: Re: Проблемы обобщения Отправлено: Igors от Декабрь 13, 2017, 08:21 Да, 3 выглядит самым идейным
Код Ну и делать его членом CGeometry, CCamera, CLight и др. Тогда метод SetReferenceTransform можно использовать как для CCamera, так и для CLight. Однако хранить сами данные (напр position, reference и др) этот новый класс вряд ли сможет. Надо делегироваться к объекту членом которого он является - и опять придется разбираться кто там CCamera или CLight. Кстати общий базовый для всех объектов есть. И явно проще долить ф-ции SetTransform в базовый, плюс что-то типа virtual GetTransformType. Но так явно "god class" Название: Re: Проблемы обобщения Отправлено: ssoft от Декабрь 13, 2017, 08:34 Кстати общий базовый для всех объектов есть. И явно проще долить ф-ции SetTransform в базовый, плюс что-то типа virtual GetTransformType. Но так явно "god class" По хорошему, я бы рекомендовал пересмотреть объектно-ориентированную модель и перейти от наследования к агрегации. Но только если есть желание и время)). Наличие у разнородных типов общего предка "god class" - это достаточно серьезное ограничение. На счет "хранить сами данные (напр position, reference и др) этот новый класс вряд ли сможет" могу порекомендовать использовать для CTransformer PIMPL технику. Тогда в зависимости от внутреннего представления CTransformer может хранить совершенно разный набор данных. Название: Re: Проблемы обобщения Отправлено: Racheengel от Декабрь 13, 2017, 11:19 Я бы лично либо использовал метод 2, либо сделал класс вроде CBaseTransform, в котором бы собрал общий функционал для камеры и света, и затем использовал бы его как член классов камеры и источника света. Это ж и есть методы 2 и 3). Только вместо CBaseTransform был предложен Transform, собирающий общий функционал по работе с трансформациями). Просто Вы написали "Соберет разные реализации в одну сущность" - но по сути то реализация будет одна, для одного случая, а "не для всех возможных", когда без свитчей никак) |