Суть этого вопроса о расширении класса, уменьшении, забивающем все в единый класс и максимизирующем повторное использование кода. После чтения этого вопроса не стесняйтесь редактировать заголовок или описание для создания этого более сжатым. Хотя сообщение выглядит длинным, я просто пытаюсь быть полным при помощи большого количества примеров.
Предположим, что у меня есть класс:
class UsedByManyPeople
{
// ...has many fields
};
Поскольку имя подразумевает, этот класс используется большим количеством разработчиков. Я должен добавить 2 опции к этому классу:
Они оба характерны для потребностей моего отдела.
Сначала я думал о простом добавлении 2 новых методов к UsedByManyPeople. Таким образом класс будет теперь похож:
class UsedByManyPeople
{
// ...has many fields
public:
SomeOtherType const convert() const;
std::string const getFileName() const;
};
Однако эти 2 функции на самом деле характерны для варианта использования моего отдела, и другие отделы даже не имеют определения класса SomeOtherType, и при этом они не заботятся о getFileName ().
Очевидно, вышеупомянутый подход не является хорошим подходом (?).
Как Вы расширили бы этот класс?
Альтернативы, которые прибыли по моему мнению:
Например,
class ExtUsedByManyPeople : public UsedByManyPeople
{
public:
SomeOtherType const convert() const;
std::string const getFileName() const;
};
Например,
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&);
};
Особенно, если методы специфичны для ваших отделов, использующих этот класс, вы должны реализовать их следующим образом: Создайте один вспомогательный класс со всеми методами внутри.
Для этого есть несколько причин:
UsedByManyPeople
не должен
быть ответственным за преобразование самого себя
в другой тип. Это нарушает
SOLID Хотя это почти идентичный (по крайней мере, в использовании) классу с общедоступными статическими методами, вы можете использовать пространство имен для инкапсуляции необходимых вам подпрограмм (как было сказано ранее, это будет работать только при условии, что вызовы могут быть реализованы из общедоступных данных и методов оригинала класс).
namespace MyDept
{
SomeOtherType const convert( UsedByManyPeople const& );
std::string const getFileName( UsedByManyPeople const& );
}
, который предоставляет вызывающему объекту интерфейс, очень похожий на статические вызовы из класса, например
overusedObjectAsSomeOtherType = MyDept::convert( overusedObject );
Я хотел бы услышать от других людей, которые ответили в этом списке, есть ли какие-либо реальные различия между этим подходом и тем, который был выбран подавляющим большинством голосов.
последний вариант ни на кого не повлияет и изолирует ваши разовые потребности в один класс
Не следует изменять существующий класс UsedByManyPeople. Если у вашего отдела есть предпочтения относительно того, какие шаблоны использовать, то оставайтесь в рамках стиля вашего отдела. В противном случае создайте вспомогательный класс для преобразований. Если в будущем вы планируете использовать несколько преобразований, возможно, вы захотите создать класс для каждого преобразования. Для расширения getFileName вы можете вывести класс (если это действительно полезное расширение) или добавить его в свой вспомогательный класс.
Опять же, стандарт вашего отдела (если он существует) должен подсказать вам в этом вопросе. Если у вас нет стандарта, сейчас самое время его создать.