Какой будет хороший шаблон сборки для этой ситуации? (раздел инструмент) - PullRequest
1 голос
/ 18 января 2012

Я занимаюсь разработкой инструмента для создания разделов и столкнулся с проблемой в дизайне. У меня есть класс (называемый CtrlFactories), который будет читать MBR и создавать объект для каждого раздела, который находится в MBR. У меня есть класс для каждого типа раздела и Фабрика для каждого из них.

Вот как это выглядит:

UML

(в примере я поместил только NTFS и FAT32, но у меня есть один для каждого типа раздела).

Моя идея заключалась в том, чтобы поместить в IFactory что-то вроде:

std::map< EPartType, IFactory* > mpFactories;

И встроить его в конструктор или в некоторую функцию инициализации:

IFactory::IFactory()
{
    mpFactories[PART_NTFS] = new FactoryNTFS();
    mpFactories[PART_FAT32] = new FactoryFAT32();
    mpFactories[PART_EXT2] = new FactoryEXT2();
    ...
}

А в функции «Сборка» выполните:

int CtrlFactories::Build()
{
    ...
    MBR mbr;
    BuildMBR( mbr );

    //... here I loop all the partitions found...
    for( /*each partition*/ )
    {
        IPartition* part = mpFactories[ mbr.GetPartType() ]->Build( mbr.PartPosition() );
        //..and store each partition somewhere
    }
}

Дело в том, что у меня много типов разделов (> 100), и в большинстве случаев у пользователя будет только два или три различных типа разделов в HD. Таким образом, это кажется пустой тратой времени и памяти, чтобы распределить все фабрики и не использовать большинство из них. Я думаю, что ленивая инициализация была бы здесь намного лучше, но тогда мне понадобился бы где-нибудь код вроде:

    switch( mbr.GetPartType() )
    {
    case PART_NTFS:
        if ( mpFactories[ PART_NTFS ] == NULL )
            mpFactories[PART_NTFS] = new FactoryNTFS();
        break;       

    case PART_FAT32:
        if ( mpFactories[ PART_32 ] == NULL )
            mpFactories[PART_32] = new Factory32();
        break;       

    ...
    }
* *} Тысяча двадцать-один

И этот очень длинный переключатель / регистр привнесет в код слишком много цикломатической сложности (даже кода, который легко понять).

Итак, есть ли лучшее решение для проблемы, которое может избежать очень длинного "переключателя / случая" и которое не тратит впустую ресурсы?

1 Ответ

1 голос
/ 18 января 2012

Один из подходов состоит в том, чтобы реализовать фабрики с использованием шаблона Singleton. Имейте статический метод Instance() на каждом фабричном классе, который управляет его реализацией. Затем в вашей карте вы можете сохранить указатель на функцию для этого метода.

В вашем коде Build() вы ищите указатель на метод Instance() для фабрики для каждого раздела, с которым вы сталкиваетесь. Используйте этот указатель, чтобы получить фактическую фабрику, в которой вы нуждаетесь, и затем продолжите оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...