2016-06-21 47 views
0

我想为许多(〜40-50)类似的实体(在我的情况下,这一块是用这些实体对文件建立索引)推广一段重复的Java代码。Java与很多具体工厂打交道

我试图用泛型方法重构它,但是,因此,我得到了Java中明显禁止的泛型类的构造函数。为了避免这种情况,我实现了抽象工厂模式,这是我得到的。

public <E extends CMObject, F extends IndexedFile<E>> F indexFile(CMFactory<E, F> factory) { 
    F items; 
    ByteBuffer[] buffs; 

    // ...filling buffers... 

    items = factory.makeFile(buffs); // as I cannot do items = new F(buffs) 

    return items; 
} 

public CityFile getCities() { 
    return indexFile(new CityFactory()); 
} 

public ContinentFile getContinents() { 
    return indexFile(new ContinentFactory()); 
} 
// a lot of more 

这解决了创建泛型类实例的问题。但是,我现在面临的任务是为每个单一实体创建一个具体的工厂,这些实体看起来很单调,因为它们看起来都很像。

public abstract class CMFactory<E extends CMObject, F extends IndexedFile<E>> { 
    public abstract F makeFile(ByteBuffer[] buff); 
} 

public class CityFactory extends CMFactory<City, CityFile> { 
    @Override 
    public CityFile makeFile(ByteBuffer[] buff) { 
     return new CityFile(buff); 
    } 
} 
public class ContinentFactory extends CMFactory<Continent, ContinentFile> { 
    @Override 
    public ContinentFile makeFile(ByteBuffer[] buffs) { 
     return new ContinentFile(buffs); 
    } 
} 

问题是:有什么办法可以自动创建这样的工厂吗?或者也许还有另一种模式,至少可以让这样的创作变得更加痛苦吗?

我试图使用IntelliJ IDEA的Replace Constructor与Factory Method重构,但它没有帮助我。

回答

3

由于您CMFactory几乎是一个功能界面就可以使用构造处理,而不是对每个具体类实现CMFactory

CMFactory接口:

public interface CMFactory<E extends CMObject, F extends IndexedFile<E>> { 
    public abstract F makeFile(ByteBuffer[] buff); 
} 

,然后写

public CityFile getCities() { 
    return indexFile(CityFile::new); 
} 

你甚至可以丢弃CMFactory并使用java.util.Function

public <E extends CMObject, F extends IndexedFile<E>> F indexFile(Function<ByteBuffer[],F> factory) { 
    ByteBuffer[] buffs; 
    // ...filling buffers... 
    return factory.apply(buffs); 
}