Предложения дизайна класса: расширение класса и повторного использования кода

Суть этого вопроса о расширении класса, уменьшении, забивающем все в единый класс и максимизирующем повторное использование кода. После чтения этого вопроса не стесняйтесь редактировать заголовок или описание для создания этого более сжатым. Хотя сообщение выглядит длинным, я просто пытаюсь быть полным при помощи большого количества примеров.

Предположим, что у меня есть класс:

class UsedByManyPeople
{
  // ...has many fields
};

Поскольку имя подразумевает, этот класс используется большим количеством разработчиков. Я должен добавить 2 опции к этому классу:

  1. преобразование (), который преобразовывает UsedByManyPeople в SomeOtherType
  2. getFileName (), который возвращает строку

Они оба характерны для потребностей моего отдела.


Первое решение для попытки

Сначала я думал о простом добавлении 2 новых методов к UsedByManyPeople. Таким образом класс будет теперь похож:

class UsedByManyPeople
{
  // ...has many fields

  public:
    SomeOtherType const convert() const;
    std::string   const getFileName() const;
};

Однако эти 2 функции на самом деле характерны для варианта использования моего отдела, и другие отделы даже не имеют определения класса SomeOtherType, и при этом они не заботятся о getFileName ().

Очевидно, вышеупомянутый подход не является хорошим подходом (?).

Как Вы расширили бы этот класс?

Альтернативы, которые прибыли по моему мнению:


Разделите UsedByManyPeople на подклассы и создайте мой собственный класс.

  • Свяжите данные и метод

Например,

class ExtUsedByManyPeople : public UsedByManyPeople
{
  public:
    SomeOtherType const convert() const;
    std::string   const getFileName() const;
};

Создайте классы Помощника, один для каждого метода (yikes!), и реализация это как статические методы.

  • Отдельные данные из методов, единый класс одна ответственность

Например,

class UsedByManyPeopleToSomeOtherTypeConverter
{    
  public:
    static SomeOtherType const convert(UsedByManyPeople const&);
};
class UsedByManyPeopleFileName
{
  public:
    static std::string const getFileName(UsedByManyPeople const&);
};

Создайте единственный класс Помощника со всеми методами внутри.

  • Отдельные данные из методов, единый класс много обязанностей

Например,

class UsedByManyPeopleHelper
{
  public:
    static SomeOtherType const convert(UsedByManyPeople const&);
    static std::string   const getFileName(UsedByManyPeople const&);
};
6
задан sivabudh 23 February 2010 в 18:54
поделиться

4 ответа

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

Для этого есть несколько причин:

  • Один вспомогательный класс может быть расположен в другой логической структуре проекта
  • Если ваши новые методы не требуют доступа к внутреннему состояние класса это выражено четко. Это обеспечивает лучшую инкапсуляцию. (который вы дополнили с помощью const ref, что считается хорошим стилем)
  • UsedByManyPeople не должен быть ответственным за преобразование самого себя в другой тип. Это нарушает SOLID
4
ответ дан 16 December 2019 в 21:38
поделиться

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

namespace MyDept
{
    SomeOtherType const convert( UsedByManyPeople const& );
    std::string   const getFileName( UsedByManyPeople const& );
}

, который предоставляет вызывающему объекту интерфейс, очень похожий на статические вызовы из класса, например

overusedObjectAsSomeOtherType = MyDept::convert( overusedObject );

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

1
ответ дан 16 December 2019 в 21:38
поделиться

последний вариант ни на кого не повлияет и изолирует ваши разовые потребности в один класс

2
ответ дан 16 December 2019 в 21:38
поделиться

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

Опять же, стандарт вашего отдела (если он существует) должен подсказать вам в этом вопросе. Если у вас нет стандарта, сейчас самое время его создать.

1
ответ дан 16 December 2019 в 21:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: