An alternative to service locator for an application which should be expansible

时间:2016-03-04 18:17:21

标签: java design-patterns service-locator

I'm working on a game which has different items which all have different behavior. All items can be improved by buying different upgrades for different aspects of the item. I save the player's data in a MongoDB. This data includes an array of documents. Each documents represents one item and contains at least a String holding the item's name. This makes it possible to identify the type and instantiate an object of that type when the player wants to use it.

My plan was to use some sort of service locator to map the names to the factories of the specific item. After reading a lot of similar questions spread across StackExchange I learned that service locator is generally considered an anti-pattern.

The question that comes up now is: What should I do instead? I plan to move the items out of the core and create different expansion packets, which would add new items. These would be added to the service locator, so I somewhat need it or a good alternative to it.

Is my case one of these special cases where service locator isn't the bad anti-pattern which should be avoided or is it considered bad practice even in this kind of usage? What are my possible alternatives?

Thank you for your help!

EDIT

Example

Some additional information to clarify the given situation: There are different items with different abilities, as an example I will use the easiest one I found. This item shoots some explosives when used. These explosives will explode when they hit something. The item has the following aspects, which may be upgraded:

  • Ammo: How many shoots I have before I need to reload.
  • Cooldown: After using all my ammo I have to wait the given time until the item is usable again.
  • Radius: The radius in which other players will take damage around the explosions.
  • Damage: The amount of damage the players will take.
  • Explosives: How many explosives will be shoot. They will be spread around so that not all are on the same spot.

Other items have different attributes. As each attribute can be upgraded individually there have to be different upgrade lists for each.

Current situation

Right now I have an interface Item:

public interface Item<T extends Item<T>> {

    // Get type of this item
    public ItemType<T> getType();

    // Serialize for database storage
    public Map<String, Object> serialize();

    // Get the player owning this item
    public Player getOwner();
}

and ItemType<T extends Item<T>>:

public interface ItemType<T extends Item<T>> {

    // create a new item of that type with everything set to default values
    public T constructNewItem(Player player);

    // deserialize and create item with existing data
    public T deserializeItem(Player player, Map<String, Object> serialized);

    // Serialize upgrade lists for database storage
    public Map<String, Object> serialize();

    // Get the item's name
    public String getName();
}

I now have a class ItemRegistry* which manages a map containing the registered items' name as keys and the registered items as values(Map<String, ItemType<?>>). Currently it is a singleton, which is initialized with the available items loaded from a folder, when the application starts. When a player wants to play I load the data, lookup the item to construct with the name given in the loaded data and then deserialize it using ItemType#deserializeItem. I'm using an ItemType as a workaround because there is now way to create abstract static methods.

Maybe already this setup is one big disaster, so any comments about it are also appreciated.


*Side question: Am I mixing up registry and service locator?

0 个答案:

没有答案