dimanche 27 août 2017

Scala : Registry design pattern or similar?

I am migrating my system from java to Scala. I have used registry pattern in my java code to get the implementation from the string. Is there any similar thing I could do with scala ? I am new to scala, can someone point to me proper references ?

My java code :

public class ItemRegistry {

    private final Map<String, ItemFactory> factoryRegistry;

    public ItemRegistry() {
        this.factoryRegistry = new HashMap<>();
    }

    public ItemRegistry(List<ItemFactory> factories) {
        factoryRegistry = new HashMap<>();
        for (ItemFactory factory : factories) {
            registerFactory(factory);
        }
    }

    public void registerFactory(ItemFactory factory) {
        Set<String> aliases = factory.getRegisteredItems();
        for (String alias : aliases) {
            factoryRegistry.put(alias, factory);
        }
    }

    public Item newInstance(String itemName) throws ItemException {
        ItemFactory factory = factoryRegistry.get(itemName);
        if (factory == null) {
            throw new ItemException("Unable to find factory containing alias " + itemName);
        }
        return factory.getItem(itemName);
    }

    public Set<String> getRegisteredAliases() {
        return factoryRegistry.keySet();
    }
}

My Item interface :

public interface Item {
    void apply(Order Order) throws ItemException;

    String getItemName();
}

I map the string like :

public interface ItemFactory {

    Item getItem(String itemName) throws ItemException;

    Set<String> getRegisteredItems();
}


public abstract class AbstractItemFactory implements ItemFactory {


    protected final Map<String, Supplier<Item>> factory = Maps.newHashMap();

    @Override
    public Item getItem(String alias) throws ItemException {
        try {
            final Supplier<Item> supplier = factory.get(alias);
            return supplier.get();
        } catch (Exception e) {
            throw new ItemException("Unable to create instance of " + alias, e);
        }
    }

    protected Supplier<Item> defaultSupplier(Class<? extends Item> itemClass) {
        return () -> {
            try {
                return itemClass.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException("Unable to create instance of " + itemClass, e);
            }
        };
    }

    @Override
    public Set<String> getRegisteredItems() {
        return factory.keySet();
    }
}

public class GenericItemFactory extends AbstractItemFactory {

public GenericItemFactory() {
     factory.put("reducedPriceItem",  () -> new Discount(reducedPriceItem));
     factory.put("salePriceItem",  () -> new Sale(reducedPriceItem));
}
}

where Sale and Discount are implemntation of Item. I use the newInstance method in ItemRegistry to get the class based on the name. Can some one suggest me any similar thing which can allow me to do the same in scala ?

Aucun commentaire:

Enregistrer un commentaire