Фабрика объектов с вопросами о свойствах? - PullRequest
1 голос
/ 22 декабря 2010

Это просто общий вопрос.

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

По какому шаблону я могу сказать, дать мне объект с этой функцией и этой функцией?Это такая картина?Мой друг говорит мне, что фабрика объектов, но я не могу найти какую-либо информацию о фабрике объектов со свойствами объекта.Если это закономерность, а я не говорю о чепухе, кто-нибудь может дать мне хороший пример, теорию об этом.Это также с целью разработки игр.

Я думаю, я просто не знаю, что с Google.

Спасибо.

РЕДАКТИРОВАТЬ:
быстрый пример: ( извините за довольно банальный пример )
Я хочу космический корабль со щитами, ракетами и радаром.
Затем я хочу космический корабль с приводом варпа, щитами и большим количеством грузового пространства.

Ответы [ 4 ]

3 голосов
/ 22 декабря 2010

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

class Spaceship {
public:
    void add(Gadget*);
};

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

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

class Spaceship {
public:
    void add(Gadget*);

    long getMaxSpeed() const;
    long getCargoCapacity() const;
    long getRadarRange() const;
};

Каждый космический корабль будет иметь разные базовые значения для этих свойств, которые вы можете варьировать в зависимости от установленных гаджетов. Таким образом, они дадут бонус или малус указанным свойствам:

class SpaceshipGadget {
public:
    long getSpeedBonus() const; // this can be positive or negative
    long getCargoBonus() const;
    long getRadarBonus() const;
};

Может быть, вам даже не нужна иерархия гаджетов: если они дают только бонус / малус, вы можете назначить их через конструктор, и все готово.

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

В конце концов вы получите фабрику для космического корабля и фабрику для гаджетов. У космического корабля один будет много таких методов, как

SpaceshipFactory {
public:
    Spaceship* buildCargo();
    Spaceship* buildWarship();
};

GadgetFactory {
public:
    Gadget* buildEnhancedRadar();
    Gadget* buildAntigravityCannons();
};

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

2 голосов
/ 22 декабря 2010

Единственное, о чем я могу думать, что даже удаленно описывает то, что вы ищете, это QueryInterface, используемый в COM, где вы указываете тип, и если объект может создать объект, который наследуется от этого интерфейса, ,

Кроме того, то, что вы говорите, не имеет никакого смысла вообще. Вы не можете просто запросить у фабрики объект, который наследуется от интерфейса X, или что-нибудь еще в этом роде.

Edit:

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

class Spaceship {
    std::vector<std::string> properties;
public:
    bool HasProperty(string property) {
        for(int i = 0; i < properties.size(); i++) {
            if (properties[i] == property)
                return true;
        }
        return false;
    }
};
std::vector<Spaceship*> GetShipsWithPropertiesFromList(std::vector<std::string> properties, std::vector<Spaceship*> spaceships) {
    for(int i = 0; i < properties.size(); i++) {
        std::vector<Spaceship*> list;
        for(int j = 0; j < spaceships.size(); j++) {
            if (spaceships[j]->HasProperty(properties[i]))
                list.push_back(spaceships[j]);
        }
        spaceships = list;
    }
    return spaceships;
}

РЕДАКТИРОВАТЬ: Забыли заявление о возврате.

1 голос
/ 22 декабря 2010

Я бы сказал, что это просто фабрика с аргументами для метода создания:

class ShipFactory
{
    function Create(Shield shield, WeaponConfiguration weapons, Engine engine)
    {
        // Return an instance with the appropriate configuration
    }
}

Зависимости (щит и т. Д.) Вполне могут быть созданы с использованием собственных фабрик:

class ShieldFactory
{
    function Shield Create();
}

class WeaponsFactory
{
    function WeaponConfiguration Create();
}

class EngineFactory
{
    function Engine Create();
}

В результате получается что-то вроде:

shield = shieldFactory.Create();
weapons = weaponsFactory.Create();
engine = engineFactory.Create();

ship = shipFactory.Create(shield, weapons, engine);

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

1 голос
/ 22 декабря 2010

Звучит смутно, как ... э-э ... анти-паттерн. Но это похоже на шаблон локатора службы .

...